ÿØÿà JFIF    ÿÛ „ ( %!1!%*+...983,7(-.- PK[t]d d pkgxml/alt-php74-vld.xmlnu[ vld pecl.php.net Provides functionality to dump the internal representation of PHP scripts The Vulcan Logic Disassembler hooks into the Zend Engine and dumps all the opcodes (execution units) of a script. Derick Rethans derick derick@xdebug.org yes 2025-07-15 0.19.1 0.19.1 beta beta BSD style - Remove 'ZEND_' prefix from opcode names - PHP 8.5: Add support for the new DECLARE_ATTRIBUTED_CONST opcode - Improve support for PHP 8.4 property hooks, and add the new INIT_PARENT_PROPERTY_HOOK_CALL opcode - Fixed EXT_STMT display, as it does not have any used op nodes 7.0.0 1.4.0b1 vld PKu] {++.channels/pecl.php.net.regnu[a:6:{s:14:"suggestedalias";s:4:"pecl";s:4:"name";s:12:"pecl.php.net";s:7:"summary";s:31:"PHP Extension Community Library";s:7:"servers";a:1:{s:7:"primary";a:1:{s:4:"rest";a:1:{s:7:"baseurl";a:2:{i:0;a:2:{s:7:"attribs";a:1:{s:4:"type";s:7:"REST1.0";}s:8:"_content";s:25:"http://pecl.php.net/rest/";}i:1;a:2:{s:7:"attribs";a:1:{s:4:"type";s:7:"REST1.1";}s:8:"_content";s:25:"http://pecl.php.net/rest/";}}}}}s:15:"validatepackage";a:2:{s:8:"_content";s:19:"PEAR_Validator_PECL";s:7:"attribs";a:1:{s:7:"version";s:3:"1.0";}}s:13:"_lastmodified";i:1747068539;}PKu]ui< .channels/.alias/pecl.txtnu[pecl.php.netPKu] .channels/.alias/pear.txtnu[pear.php.netPKu]o/ .channels/.alias/phpdocs.txtnu[doc.php.netPKu]5j.channels/doc.php.net.regnu[a:5:{s:14:"suggestedalias";s:7:"phpdocs";s:4:"name";s:11:"doc.php.net";s:7:"summary";s:22:"PHP Documentation Team";s:7:"servers";a:1:{s:7:"primary";a:1:{s:4:"rest";a:1:{s:7:"baseurl";a:3:{i:0;a:2:{s:7:"attribs";a:1:{s:4:"type";s:7:"REST1.0";}s:8:"_content";s:24:"http://doc.php.net/rest/";}i:1;a:2:{s:7:"attribs";a:1:{s:4:"type";s:7:"REST1.1";}s:8:"_content";s:24:"http://doc.php.net/rest/";}i:2;a:2:{s:7:"attribs";a:1:{s:4:"type";s:7:"REST1.3";}s:8:"_content";s:24:"http://doc.php.net/rest/";}}}}}s:13:"_lastmodified";i:1747068539;}PKu]  .channels/__uri.regnu[a:4:{s:4:"name";s:5:"__uri";s:7:"servers";a:1:{s:7:"primary";a:1:{s:4:"rest";a:1:{s:7:"baseurl";a:2:{s:7:"attribs";a:1:{s:4:"type";s:7:"REST1.0";}s:8:"_content";s:4:"****";}}}}s:7:"summary";s:34:"Pseudo-channel for static packages";s:13:"_lastmodified";i:1747068539;}PKu]W((.channels/pear.php.net.regnu[a:5:{s:14:"suggestedalias";s:4:"pear";s:4:"name";s:12:"pear.php.net";s:7:"summary";s:40:"PHP Extension and Application Repository";s:7:"servers";a:1:{s:7:"primary";a:1:{s:4:"rest";a:1:{s:7:"baseurl";a:3:{i:0;a:2:{s:7:"attribs";a:1:{s:4:"type";s:7:"REST1.0";}s:8:"_content";s:25:"http://pear.php.net/rest/";}i:1;a:2:{s:7:"attribs";a:1:{s:4:"type";s:7:"REST1.1";}s:8:"_content";s:25:"http://pear.php.net/rest/";}i:2;a:2:{s:7:"attribs";a:1:{s:4:"type";s:7:"REST1.3";}s:8:"_content";s:25:"http://pear.php.net/rest/";}}}}}s:13:"_lastmodified";i:1747068539;}PKu]&#rr Net/IDNA2/Exception/Nameprep.phpnu[ | // | Jon Parise | // | Damian Alejandro Fernandez Sosa | // +----------------------------------------------------------------------+ require_once 'PEAR.php'; require_once 'Net/Socket.php'; /** * Provides an implementation of the SMTP protocol using PEAR's * Net_Socket class. * * @package Net_SMTP * @author Chuck Hagenbuch * @author Jon Parise * @author Damian Alejandro Fernandez Sosa * @license http://opensource.org/licenses/bsd-license.php BSD-2-Clause * * @example basic.php A basic implementation of the Net_SMTP package. */ class Net_SMTP { /** * The server to connect to. * @var string */ public $host = 'localhost'; /** * The port to connect to. * @var int */ public $port = 25; /** * The value to give when sending EHLO or HELO. * @var string */ public $localhost = 'localhost'; /** * List of supported authentication methods, in preferential order. * @var array */ public $auth_methods = array(); /** * Use SMTP command pipelining (specified in RFC 2920) if the SMTP * server supports it. * * When pipeling is enabled, rcptTo(), mailFrom(), sendFrom(), * somlFrom() and samlFrom() do not wait for a response from the * SMTP server but return immediately. * * @var bool */ public $pipelining = false; /** * Number of pipelined commands. * @var int */ protected $pipelined_commands = 0; /** * Should debugging output be enabled? * @var boolean */ protected $debug = false; /** * Debug output handler. * @var callback */ protected $debug_handler = null; /** * The socket resource being used to connect to the SMTP server. * @var resource */ protected $socket = null; /** * Array of socket options that will be passed to Net_Socket::connect(). * @see stream_context_create() * @var array */ protected $socket_options = null; /** * The socket I/O timeout value in seconds. * @var int */ protected $timeout = 0; /** * The most recent server response code. * @var int */ protected $code = -1; /** * The most recent server response arguments. * @var array */ protected $arguments = array(); /** * Stores the SMTP server's greeting string. * @var string */ protected $greeting = null; /** * Stores detected features of the SMTP server. * @var array */ protected $esmtp = array(); /** * Instantiates a new Net_SMTP object, overriding any defaults * with parameters that are passed in. * * If you have SSL support in PHP, you can connect to a server * over SSL using an 'ssl://' prefix: * * // 465 is a common smtps port. * $smtp = new Net_SMTP('ssl://mail.host.com', 465); * $smtp->connect(); * * @param string $host The server to connect to. * @param integer $port The port to connect to. * @param string $localhost The value to give when sending EHLO or HELO. * @param boolean $pipelining Use SMTP command pipelining * @param integer $timeout Socket I/O timeout in seconds. * @param array $socket_options Socket stream_context_create() options. * @param string $gssapi_principal GSSAPI service principal name * @param string $gssapi_cname GSSAPI credentials cache * * @since 1.0 */ public function __construct($host = null, $port = null, $localhost = null, $pipelining = false, $timeout = 0, $socket_options = null, $gssapi_principal=null, $gssapi_cname=null ) { if (isset($host)) { $this->host = $host; } if (isset($port)) { $this->port = $port; } if (isset($localhost)) { $this->localhost = $localhost; } $this->pipelining = $pipelining; $this->socket = new Net_Socket(); $this->socket_options = $socket_options; $this->timeout = $timeout; $this->gssapi_principal = $gssapi_principal; $this->gssapi_cname = $gssapi_cname; /* If PHP krb5 extension is loaded, we enable GSSAPI method. */ if (extension_loaded('krb5')) { $this->setAuthMethod('GSSAPI', array($this, 'authGSSAPI')); } /* Include the Auth_SASL package. If the package is available, we * enable the authentication methods that depend upon it. */ if (@include_once 'Auth/SASL.php') { $this->setAuthMethod('CRAM-MD5', array($this, 'authCramMD5')); $this->setAuthMethod('DIGEST-MD5', array($this, 'authDigestMD5')); } /* These standard authentication methods are always available. */ $this->setAuthMethod('LOGIN', array($this, 'authLogin'), false); $this->setAuthMethod('PLAIN', array($this, 'authPlain'), false); $this->setAuthMethod('XOAUTH2', array($this, 'authXOAuth2'), false); } /** * Set the socket I/O timeout value in seconds plus microseconds. * * @param integer $seconds Timeout value in seconds. * @param integer $microseconds Additional value in microseconds. * * @since 1.5.0 */ public function setTimeout($seconds, $microseconds = 0) { return $this->socket->setTimeout($seconds, $microseconds); } /** * Set the value of the debugging flag. * * @param boolean $debug New value for the debugging flag. * @param callback $handler Debug handler callback * * @since 1.1.0 */ public function setDebug($debug, $handler = null) { $this->debug = $debug; $this->debug_handler = $handler; } /** * Write the given debug text to the current debug output handler. * * @param string $message Debug mesage text. * * @since 1.3.3 */ protected function debug($message) { if ($this->debug) { if ($this->debug_handler) { call_user_func_array( $this->debug_handler, array(&$this, $message) ); } else { echo "DEBUG: $message\n"; } } } /** * Send the given string of data to the server. * * @param string $data The string of data to send. * * @return mixed The number of bytes that were actually written, * or a PEAR_Error object on failure. * * @since 1.1.0 */ protected function send($data) { $this->debug("Send: $data"); $result = $this->socket->write($data); if (!$result || PEAR::isError($result)) { $msg = $result ? $result->getMessage() : "unknown error"; return PEAR::raiseError("Failed to write to socket: $msg"); } return $result; } /** * Send a command to the server with an optional string of * arguments. A carriage return / linefeed (CRLF) sequence will * be appended to each command string before it is sent to the * SMTP server - an error will be thrown if the command string * already contains any newline characters. Use send() for * commands that must contain newlines. * * @param string $command The SMTP command to send to the server. * @param string $args A string of optional arguments to append * to the command. * * @return mixed The result of the send() call. * * @since 1.1.0 */ protected function put($command, $args = '') { if (!empty($args)) { $command .= ' ' . $args; } if (strcspn($command, "\r\n") !== strlen($command)) { return PEAR::raiseError('Commands cannot contain newlines'); } return $this->send($command . "\r\n"); } /** * Read a reply from the SMTP server. The reply consists of a response * code and a response message. * * @param mixed $valid The set of valid response codes. These * may be specified as an array of integer * values or as a single integer value. * @param bool $later Do not parse the response now, but wait * until the last command in the pipelined * command group * * @return mixed True if the server returned a valid response code or * a PEAR_Error object is an error condition is reached. * * @since 1.1.0 * * @see getResponse */ protected function parseResponse($valid, $later = false) { $this->code = -1; $this->arguments = array(); if ($later) { $this->pipelined_commands++; return true; } for ($i = 0; $i <= $this->pipelined_commands; $i++) { while ($line = $this->socket->readLine()) { $this->debug("Recv: $line"); /* If we receive an empty line, the connection was closed. */ if (empty($line)) { $this->disconnect(); return PEAR::raiseError('Connection was closed'); } /* Read the code and store the rest in the arguments array. */ $code = substr($line, 0, 3); $this->arguments[] = trim(substr($line, 4)); /* Check the syntax of the response code. */ if (is_numeric($code)) { $this->code = (int)$code; } else { $this->code = -1; break; } /* If this is not a multiline response, we're done. */ if (substr($line, 3, 1) != '-') { break; } } } $this->pipelined_commands = 0; /* Compare the server's response code with the valid code/codes. */ if (is_int($valid) && ($this->code === $valid)) { return true; } elseif (is_array($valid) && in_array($this->code, $valid, true)) { return true; } return PEAR::raiseError('Invalid response code received from server', $this->code); } /** * Issue an SMTP command and verify its response. * * @param string $command The SMTP command string or data. * @param mixed $valid The set of valid response codes. These * may be specified as an array of integer * values or as a single integer value. * * @return mixed True on success or a PEAR_Error object on failure. * * @since 1.6.0 */ public function command($command, $valid) { if (PEAR::isError($error = $this->put($command))) { return $error; } if (PEAR::isError($error = $this->parseResponse($valid))) { return $error; } return true; } /** * Return a 2-tuple containing the last response from the SMTP server. * * @return array A two-element array: the first element contains the * response code as an integer and the second element * contains the response's arguments as a string. * * @since 1.1.0 */ public function getResponse() { return array($this->code, join("\n", $this->arguments)); } /** * Return the SMTP server's greeting string. * * @return string A string containing the greeting string, or null if * a greeting has not been received. * * @since 1.3.3 */ public function getGreeting() { return $this->greeting; } /** * Attempt to connect to the SMTP server. * * @param int $timeout The timeout value (in seconds) for the * socket connection attempt. * @param bool $persistent Should a persistent socket connection * be used? * * @return mixed Returns a PEAR_Error with an error message on any * kind of failure, or true on success. * @since 1.0 */ public function connect($timeout = null, $persistent = false) { $this->greeting = null; $result = $this->socket->connect( $this->host, $this->port, $persistent, $timeout, $this->socket_options ); if (PEAR::isError($result)) { return PEAR::raiseError( 'Failed to connect socket: ' . $result->getMessage() ); } /* * Now that we're connected, reset the socket's timeout value for * future I/O operations. This allows us to have different socket * timeout values for the initial connection (our $timeout parameter) * and all other socket operations. */ if ($this->timeout > 0) { if (PEAR::isError($error = $this->setTimeout($this->timeout))) { return $error; } } if (PEAR::isError($error = $this->parseResponse(220))) { return $error; } /* Extract and store a copy of the server's greeting string. */ list(, $this->greeting) = $this->getResponse(); if (PEAR::isError($error = $this->negotiate())) { return $error; } return true; } /** * Attempt to disconnect from the SMTP server. * * @return mixed Returns a PEAR_Error with an error message on any * kind of failure, or true on success. * @since 1.0 */ public function disconnect() { if (PEAR::isError($error = $this->put('QUIT'))) { return $error; } if (PEAR::isError($error = $this->parseResponse(221))) { return $error; } if (PEAR::isError($error = $this->socket->disconnect())) { return PEAR::raiseError( 'Failed to disconnect socket: ' . $error->getMessage() ); } return true; } /** * Attempt to send the EHLO command and obtain a list of ESMTP * extensions available, and failing that just send HELO. * * @return mixed Returns a PEAR_Error with an error message on any * kind of failure, or true on success. * * @since 1.1.0 */ protected function negotiate() { if (PEAR::isError($error = $this->put('EHLO', $this->localhost))) { return $error; } if (PEAR::isError($this->parseResponse(250))) { /* If the EHLO failed, try the simpler HELO command. */ if (PEAR::isError($error = $this->put('HELO', $this->localhost))) { return $error; } if (PEAR::isError($this->parseResponse(250))) { return PEAR::raiseError('HELO was not accepted', $this->code); } return true; } foreach ($this->arguments as $argument) { $verb = strtok($argument, ' '); $len = strlen($verb); $arguments = substr($argument, $len + 1, strlen($argument) - $len - 1); $this->esmtp[$verb] = $arguments; } if (!isset($this->esmtp['PIPELINING'])) { $this->pipelining = false; } return true; } /** * Returns the name of the best authentication method that the server * has advertised. * * @return mixed Returns a string containing the name of the best * supported authentication method or a PEAR_Error object * if a failure condition is encountered. * @since 1.1.0 */ protected function getBestAuthMethod() { $available_methods = explode(' ', $this->esmtp['AUTH']); foreach ($this->auth_methods as $method => $callback) { if (in_array($method, $available_methods)) { return $method; } } return PEAR::raiseError('No supported authentication methods'); } /** * Establish STARTTLS Connection. * * @return mixed Returns a PEAR_Error with an error message on any * kind of failure, true on success, or false if SSL/TLS * isn't available. * @since 1.10.0 */ public function starttls() { /* We can only attempt a TLS connection if one has been requested, * we're running PHP 5.1.0 or later, have access to the OpenSSL * extension, are connected to an SMTP server which supports the * STARTTLS extension, and aren't already connected over a secure * (SSL) socket connection. */ if (version_compare(PHP_VERSION, '5.1.0', '>=') && extension_loaded('openssl') && isset($this->esmtp['STARTTLS']) && strncasecmp($this->host, 'ssl://', 6) !== 0 ) { /* Start the TLS connection attempt. */ if (PEAR::isError($result = $this->put('STARTTLS'))) { return $result; } if (PEAR::isError($result = $this->parseResponse(220))) { return $result; } if (isset($this->socket_options['ssl']['crypto_method'])) { $crypto_method = $this->socket_options['ssl']['crypto_method']; } else { /* STREAM_CRYPTO_METHOD_TLS_ANY_CLIENT constant does not exist * and STREAM_CRYPTO_METHOD_SSLv23_CLIENT constant is * inconsistent across PHP versions. */ $crypto_method = STREAM_CRYPTO_METHOD_TLS_CLIENT | @STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT | @STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT; } if (PEAR::isError($result = $this->socket->enableCrypto(true, $crypto_method))) { return $result; } elseif ($result !== true) { return PEAR::raiseError('STARTTLS failed'); } /* Send EHLO again to recieve the AUTH string from the * SMTP server. */ $this->negotiate(); } else { return false; } return true; } /** * Attempt to do SMTP authentication. * * @param string $uid The userid to authenticate as. * @param string $pwd The password to authenticate with. * @param string $method The requested authentication method. If none is * specified, the best supported method will be used. * @param bool $tls Flag indicating whether or not TLS should be attempted. * @param string $authz An optional authorization identifier. If specified, this * identifier will be used as the authorization proxy. * * @return mixed Returns a PEAR_Error with an error message on any * kind of failure, or true on success. * @since 1.0 */ public function auth($uid, $pwd , $method = '', $tls = true, $authz = '') { /* We can only attempt a TLS connection if one has been requested, * we're running PHP 5.1.0 or later, have access to the OpenSSL * extension, are connected to an SMTP server which supports the * STARTTLS extension, and aren't already connected over a secure * (SSL) socket connection. */ if ($tls) { /* Start the TLS connection attempt. */ if (PEAR::isError($starttls = $this->starttls())) { return $starttls; } } if (empty($this->esmtp['AUTH'])) { return PEAR::raiseError('SMTP server does not support authentication'); } /* If no method has been specified, get the name of the best * supported method advertised by the SMTP server. */ if (empty($method)) { if (PEAR::isError($method = $this->getBestAuthMethod())) { /* Return the PEAR_Error object from _getBestAuthMethod(). */ return $method; } } else { $method = strtoupper($method); if (!array_key_exists($method, $this->auth_methods)) { return PEAR::raiseError("$method is not a supported authentication method"); } } if (!isset($this->auth_methods[$method])) { return PEAR::raiseError("$method is not a supported authentication method"); } if (!is_callable($this->auth_methods[$method], false)) { return PEAR::raiseError("$method authentication method cannot be called"); } if (is_array($this->auth_methods[$method])) { list($object, $method) = $this->auth_methods[$method]; $result = $object->{$method}($uid, $pwd, $authz, $this); } else { $func = $this->auth_methods[$method]; $result = $func($uid, $pwd, $authz, $this); } /* If an error was encountered, return the PEAR_Error object. */ if (PEAR::isError($result)) { return $result; } return true; } /** * Add a new authentication method. * * @param string $name The authentication method name (e.g. 'PLAIN') * @param mixed $callback The authentication callback (given as the name of a * function or as an (object, method name) array). * @param bool $prepend Should the new method be prepended to the list of * available methods? This is the default behavior, * giving the new method the highest priority. * * @return mixed True on success or a PEAR_Error object on failure. * * @since 1.6.0 */ public function setAuthMethod($name, $callback, $prepend = true) { if (!is_string($name)) { return PEAR::raiseError('Method name is not a string'); } if (!is_string($callback) && !is_array($callback)) { return PEAR::raiseError('Method callback must be string or array'); } if (is_array($callback)) { if (!is_object($callback[0]) || !is_string($callback[1])) { return PEAR::raiseError('Bad mMethod callback array'); } } if ($prepend) { $this->auth_methods = array_merge( array($name => $callback), $this->auth_methods ); } else { $this->auth_methods[$name] = $callback; } return true; } /** * Authenticates the user using the DIGEST-MD5 method. * * @param string $uid The userid to authenticate as. * @param string $pwd The password to authenticate with. * @param string $authz The optional authorization proxy identifier. * * @return mixed Returns a PEAR_Error with an error message on any * kind of failure, or true on success. * @since 1.1.0 */ protected function authDigestMD5($uid, $pwd, $authz = '') { if (PEAR::isError($error = $this->put('AUTH', 'DIGEST-MD5'))) { return $error; } /* 334: Continue authentication request */ if (PEAR::isError($error = $this->parseResponse(334))) { /* 503: Error: already authenticated */ if ($this->code === 503) { return true; } return $error; } $auth_sasl = new Auth_SASL; $digest = $auth_sasl->factory('digest-md5'); $challenge = base64_decode($this->arguments[0]); $auth_str = base64_encode( $digest->getResponse($uid, $pwd, $challenge, $this->host, "smtp", $authz) ); if (PEAR::isError($error = $this->put($auth_str))) { return $error; } /* 334: Continue authentication request */ if (PEAR::isError($error = $this->parseResponse(334))) { return $error; } /* We don't use the protocol's third step because SMTP doesn't * allow subsequent authentication, so we just silently ignore * it. */ if (PEAR::isError($error = $this->put(''))) { return $error; } /* 235: Authentication successful */ if (PEAR::isError($error = $this->parseResponse(235))) { return $error; } } /** * Authenticates the user using the CRAM-MD5 method. * * @param string $uid The userid to authenticate as. * @param string $pwd The password to authenticate with. * @param string $authz The optional authorization proxy identifier. * * @return mixed Returns a PEAR_Error with an error message on any * kind of failure, or true on success. * @since 1.1.0 */ protected function authCRAMMD5($uid, $pwd, $authz = '') { if (PEAR::isError($error = $this->put('AUTH', 'CRAM-MD5'))) { return $error; } /* 334: Continue authentication request */ if (PEAR::isError($error = $this->parseResponse(334))) { /* 503: Error: already authenticated */ if ($this->code === 503) { return true; } return $error; } $auth_sasl = new Auth_SASL; $challenge = base64_decode($this->arguments[0]); $cram = $auth_sasl->factory('cram-md5'); $auth_str = base64_encode($cram->getResponse($uid, $pwd, $challenge)); if (PEAR::isError($error = $this->put($auth_str))) { return $error; } /* 235: Authentication successful */ if (PEAR::isError($error = $this->parseResponse(235))) { return $error; } } /** * Authenticates the user using the LOGIN method. * * @param string $uid The userid to authenticate as. * @param string $pwd The password to authenticate with. * @param string $authz The optional authorization proxy identifier. * * @return mixed Returns a PEAR_Error with an error message on any * kind of failure, or true on success. * @since 1.1.0 */ protected function authLogin($uid, $pwd, $authz = '') { if (PEAR::isError($error = $this->put('AUTH', 'LOGIN'))) { return $error; } /* 334: Continue authentication request */ if (PEAR::isError($error = $this->parseResponse(334))) { /* 503: Error: already authenticated */ if ($this->code === 503) { return true; } return $error; } if (PEAR::isError($error = $this->put(base64_encode($uid)))) { return $error; } /* 334: Continue authentication request */ if (PEAR::isError($error = $this->parseResponse(334))) { return $error; } if (PEAR::isError($error = $this->put(base64_encode($pwd)))) { return $error; } /* 235: Authentication successful */ if (PEAR::isError($error = $this->parseResponse(235))) { return $error; } return true; } /** * Authenticates the user using the PLAIN method. * * @param string $uid The userid to authenticate as. * @param string $pwd The password to authenticate with. * @param string $authz The optional authorization proxy identifier. * * @return mixed Returns a PEAR_Error with an error message on any * kind of failure, or true on success. * @since 1.1.0 */ protected function authPlain($uid, $pwd, $authz = '') { if (PEAR::isError($error = $this->put('AUTH', 'PLAIN'))) { return $error; } /* 334: Continue authentication request */ if (PEAR::isError($error = $this->parseResponse(334))) { /* 503: Error: already authenticated */ if ($this->code === 503) { return true; } return $error; } $auth_str = base64_encode($authz . chr(0) . $uid . chr(0) . $pwd); if (PEAR::isError($error = $this->put($auth_str))) { return $error; } /* 235: Authentication successful */ if (PEAR::isError($error = $this->parseResponse(235))) { return $error; } return true; } /** * Authenticates the user using the GSSAPI method. * * PHP krb5 extension is required, * service principal and credentials cache must be set. * * @param string $uid The userid to authenticate as. * @param string $pwd The password to authenticate with. * @param string $authz The optional authorization proxy identifier. * * @return mixed Returns a PEAR_Error with an error message on any * kind of failure, or true on success. */ protected function authGSSAPI($uid, $pwd, $authz = '') { if (PEAR::isError($error = $this->put('AUTH', 'GSSAPI'))) { return $error; } /* 334: Continue authentication request */ if (PEAR::isError($error = $this->parseResponse(334))) { /* 503: Error: already authenticated */ if ($this->code === 503) { return true; } return $error; } if (!$this->gssapi_principal) { return PEAR::raiseError('No Kerberos service principal set', 2); } if (!empty($this->gssapi_cname)) { putenv('KRB5CCNAME=' . $this->gssapi_cname); } try { $ccache = new KRB5CCache(); if (!empty($this->gssapi_cname)) { $ccache->open($this->gssapi_cname); } $gssapicontext = new GSSAPIContext(); $gssapicontext->acquireCredentials($ccache); $token = ''; $success = $gssapicontext->initSecContext($this->gssapi_principal, null, null, null, $token); $token = base64_encode($token); } catch (Exception $e) { return PEAR::raiseError('GSSAPI authentication failed: ' . $e->getMessage()); } if (PEAR::isError($error = $this->put($token))) { return $error; } /* 334: Continue authentication request */ if (PEAR::isError($error = $this->parseResponse(334))) { return $error; } $response = $this->arguments[0]; try { $challenge = base64_decode($response); $gssapicontext->unwrap($challenge, $challenge); $gssapicontext->wrap($challenge, $challenge, true); } catch (Exception $e) { return PEAR::raiseError('GSSAPI authentication failed: ' . $e->getMessage()); } if (PEAR::isError($error = $this->put(base64_encode($challenge)))) { return $error; } /* 235: Authentication successful */ if (PEAR::isError($error = $this->parseResponse(235))) { return $error; } return true; } /** * Authenticates the user using the XOAUTH2 method. * * @param string $uid The userid to authenticate as. * @param string $token The access token to authenticate with. * @param string $authz The optional authorization proxy identifier. * * @return mixed Returns a PEAR_Error with an error message on any * kind of failure, or true on success. * @since 1.9.0 */ public function authXOAuth2($uid, $token, $authz, $conn) { $auth = base64_encode("user=$uid\1auth=$token\1\1"); if (PEAR::isError($error = $this->put('AUTH', 'XOAUTH2 ' . $auth))) { return $error; } /* 235: Authentication successful or 334: Continue authentication */ if (PEAR::isError($error = $this->parseResponse([235, 334]))) { return $error; } /* 334: Continue authentication request */ if ($this->code === 334) { /* Send an empty line as response to 334 */ if (PEAR::isError($error = $this->put(''))) { return $error; } /* Expect 235: Authentication successful */ if (PEAR::isError($error = $this->parseResponse(235))) { return $error; } } return true; } /** * Send the HELO command. * * @param string $domain The domain name to say we are. * * @return mixed Returns a PEAR_Error with an error message on any * kind of failure, or true on success. * @since 1.0 */ public function helo($domain) { if (PEAR::isError($error = $this->put('HELO', $domain))) { return $error; } if (PEAR::isError($error = $this->parseResponse(250))) { return $error; } return true; } /** * Return the list of SMTP service extensions advertised by the server. * * @return array The list of SMTP service extensions. * @since 1.3 */ public function getServiceExtensions() { return $this->esmtp; } /** * Send the MAIL FROM: command. * * @param string $sender The sender (reverse path) to set. * @param string $params String containing additional MAIL parameters, * such as the NOTIFY flags defined by RFC 1891 * or the VERP protocol. * * If $params is an array, only the 'verp' option * is supported. If 'verp' is true, the XVERP * parameter is appended to the MAIL command. * If the 'verp' value is a string, the full * XVERP=value parameter is appended. * * @return mixed Returns a PEAR_Error with an error message on any * kind of failure, or true on success. * @since 1.0 */ public function mailFrom($sender, $params = null) { $args = "FROM:<$sender>"; /* Support the deprecated array form of $params. */ if (is_array($params) && isset($params['verp'])) { if ($params['verp'] === true) { $args .= ' XVERP'; } elseif (trim($params['verp'])) { $args .= ' XVERP=' . $params['verp']; } } elseif (is_string($params) && !empty($params)) { $args .= ' ' . $params; } if (PEAR::isError($error = $this->put('MAIL', $args))) { return $error; } if (PEAR::isError($error = $this->parseResponse(250, $this->pipelining))) { return $error; } return true; } /** * Send the RCPT TO: command. * * @param string $recipient The recipient (forward path) to add. * @param string $params String containing additional RCPT parameters, * such as the NOTIFY flags defined by RFC 1891. * * @return mixed Returns a PEAR_Error with an error message on any * kind of failure, or true on success. * * @since 1.0 */ public function rcptTo($recipient, $params = null) { $args = "TO:<$recipient>"; if (is_string($params)) { $args .= ' ' . $params; } if (PEAR::isError($error = $this->put('RCPT', $args))) { return $error; } if (PEAR::isError($error = $this->parseResponse(array(250, 251), $this->pipelining))) { return $error; } return true; } /** * Quote the data so that it meets SMTP standards. * * This is provided as a separate public function to facilitate * easier overloading for the cases where it is desirable to * customize the quoting behavior. * * @param string &$data The message text to quote. The string must be passed * by reference, and the text will be modified in place. * * @since 1.2 */ public function quotedata(&$data) { /* Because a single leading period (.) signifies an end to the * data, legitimate leading periods need to be "doubled" ('..'). */ $data = preg_replace('/^\./m', '..', $data); /* Change Unix (\n) and Mac (\r) linefeeds into CRLF's (\r\n). */ $data = preg_replace('/(?:\r\n|\n|\r(?!\n))/', "\r\n", $data); } /** * Send the DATA command. * * @param mixed $data The message data, either as a string or an open * file resource. * @param string $headers The message headers. If $headers is provided, * $data is assumed to contain only body data. * * @return mixed Returns a PEAR_Error with an error message on any * kind of failure, or true on success. * @since 1.0 */ public function data($data, $headers = null) { /* Verify that $data is a supported type. */ if (!is_string($data) && !is_resource($data)) { return PEAR::raiseError('Expected a string or file resource'); } /* Start by considering the size of the optional headers string. We * also account for the addition 4 character "\r\n\r\n" separator * sequence. */ $size = $headers_size = (is_null($headers)) ? 0 : strlen($headers) + 4; if (is_resource($data)) { $stat = fstat($data); if ($stat === false) { return PEAR::raiseError('Failed to get file size'); } $size += $stat['size']; } else { $size += strlen($data); } /* RFC 1870, section 3, subsection 3 states "a value of zero indicates * that no fixed maximum message size is in force". Furthermore, it * says that if "the parameter is omitted no information is conveyed * about the server's fixed maximum message size". */ $limit = (isset($this->esmtp['SIZE'])) ? $this->esmtp['SIZE'] : 0; if ($limit > 0 && $size >= $limit) { return PEAR::raiseError('Message size exceeds server limit'); } /* Initiate the DATA command. */ if (PEAR::isError($error = $this->put('DATA'))) { return $error; } if (PEAR::isError($error = $this->parseResponse(354))) { return $error; } /* If we have a separate headers string, send it first. */ if (!is_null($headers)) { $this->quotedata($headers); if (PEAR::isError($result = $this->send($headers . "\r\n\r\n"))) { return $result; } /* Subtract the headers size now that they've been sent. */ $size -= $headers_size; } /* Now we can send the message body data. */ if (is_resource($data)) { /* Stream the contents of the file resource out over our socket * connection, line by line. Each line must be run through the * quoting routine. */ while (strlen($line = fread($data, 8192)) > 0) { /* If the last character is an newline, we need to grab the * next character to check to see if it is a period. */ while (!feof($data)) { $char = fread($data, 1); $line .= $char; if ($char != "\n") { break; } } $this->quotedata($line); if (PEAR::isError($result = $this->send($line))) { return $result; } } $last = $line; } else { /* * Break up the data by sending one chunk (up to 512k) at a time. * This approach reduces our peak memory usage. */ for ($offset = 0; $offset < $size;) { $end = $offset + 512000; /* * Ensure we don't read beyond our data size or span multiple * lines. quotedata() can't properly handle character data * that's split across two line break boundaries. */ if ($end >= $size) { $end = $size; } else { for (; $end < $size; $end++) { if ($data[$end] != "\n") { break; } } } /* Extract our chunk and run it through the quoting routine. */ $chunk = substr($data, $offset, $end - $offset); $this->quotedata($chunk); /* If we run into a problem along the way, abort. */ if (PEAR::isError($result = $this->send($chunk))) { return $result; } /* Advance the offset to the end of this chunk. */ $offset = $end; } $last = $chunk; } /* Don't add another CRLF sequence if it's already in the data */ $terminator = (substr($last, -2) == "\r\n" ? '' : "\r\n") . ".\r\n"; /* Finally, send the DATA terminator sequence. */ if (PEAR::isError($result = $this->send($terminator))) { return $result; } /* Verify that the data was successfully received by the server. */ if (PEAR::isError($error = $this->parseResponse(250, $this->pipelining))) { return $error; } return true; } /** * Send the SEND FROM: command. * * @param string $path The reverse path to send. * * @return mixed Returns a PEAR_Error with an error message on any * kind of failure, or true on success. * @since 1.2.6 */ public function sendFrom($path) { if (PEAR::isError($error = $this->put('SEND', "FROM:<$path>"))) { return $error; } if (PEAR::isError($error = $this->parseResponse(250, $this->pipelining))) { return $error; } return true; } /** * Send the SOML FROM: command. * * @param string $path The reverse path to send. * * @return mixed Returns a PEAR_Error with an error message on any * kind of failure, or true on success. * @since 1.2.6 */ public function somlFrom($path) { if (PEAR::isError($error = $this->put('SOML', "FROM:<$path>"))) { return $error; } if (PEAR::isError($error = $this->parseResponse(250, $this->pipelining))) { return $error; } return true; } /** * Send the SAML FROM: command. * * @param string $path The reverse path to send. * * @return mixed Returns a PEAR_Error with an error message on any * kind of failure, or true on success. * @since 1.2.6 */ public function samlFrom($path) { if (PEAR::isError($error = $this->put('SAML', "FROM:<$path>"))) { return $error; } if (PEAR::isError($error = $this->parseResponse(250, $this->pipelining))) { return $error; } return true; } /** * Send the RSET command. * * @return mixed Returns a PEAR_Error with an error message on any * kind of failure, or true on success. * @since 1.0 */ public function rset() { if (PEAR::isError($error = $this->put('RSET'))) { return $error; } if (PEAR::isError($error = $this->parseResponse(250, $this->pipelining))) { return $error; } return true; } /** * Send the VRFY command. * * @param string $string The string to verify * * @return mixed Returns a PEAR_Error with an error message on any * kind of failure, or true on success. * @since 1.0 */ public function vrfy($string) { /* Note: 251 is also a valid response code */ if (PEAR::isError($error = $this->put('VRFY', $string))) { return $error; } if (PEAR::isError($error = $this->parseResponse(array(250, 252)))) { return $error; } return true; } /** * Send the NOOP command. * * @return mixed Returns a PEAR_Error with an error message on any * kind of failure, or true on success. * @since 1.0 */ public function noop() { if (PEAR::isError($error = $this->put('NOOP'))) { return $error; } if (PEAR::isError($error = $this->parseResponse(250))) { return $error; } return true; } /** * Backwards-compatibility method. identifySender()'s functionality is * now handled internally. * * @return boolean This method always return true. * * @since 1.0 */ public function identifySender() { return true; } } PKu]  Net/IDNA2.phpnu[ * @author Matthias Sommerfeld * @author Stefan Neufeind * @version $Id$ */ class Net_IDNA2 { // {{{ npdata /** * These Unicode codepoints are * mapped to nothing, See RFC3454 for details * * @static * @var array * @access private */ private static $_np_map_nothing = array( 0xAD, 0x34F, 0x1806, 0x180B, 0x180C, 0x180D, 0x200B, 0x200C, 0x200D, 0x2060, 0xFE00, 0xFE01, 0xFE02, 0xFE03, 0xFE04, 0xFE05, 0xFE06, 0xFE07, 0xFE08, 0xFE09, 0xFE0A, 0xFE0B, 0xFE0C, 0xFE0D, 0xFE0E, 0xFE0F, 0xFEFF ); /** * Prohibited codepints * * @static * @var array * @access private */ private static $_general_prohibited = array( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2F, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x3002 ); /** * Codepints prohibited by Nameprep * @static * @var array * @access private */ private static $_np_prohibit = array( 0xA0, 0x1680, 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008, 0x2009, 0x200A, 0x200B, 0x202F, 0x205F, 0x3000, 0x6DD, 0x70F, 0x180E, 0x200C, 0x200D, 0x2028, 0x2029, 0xFEFF, 0xFFF9, 0xFFFA, 0xFFFB, 0xFFFC, 0xFFFE, 0xFFFF, 0x1FFFE, 0x1FFFF, 0x2FFFE, 0x2FFFF, 0x3FFFE, 0x3FFFF, 0x4FFFE, 0x4FFFF, 0x5FFFE, 0x5FFFF, 0x6FFFE, 0x6FFFF, 0x7FFFE, 0x7FFFF, 0x8FFFE, 0x8FFFF, 0x9FFFE, 0x9FFFF, 0xAFFFE, 0xAFFFF, 0xBFFFE, 0xBFFFF, 0xCFFFE, 0xCFFFF, 0xDFFFE, 0xDFFFF, 0xEFFFE, 0xEFFFF, 0xFFFFE, 0xFFFFF, 0x10FFFE, 0x10FFFF, 0xFFF9, 0xFFFA, 0xFFFB, 0xFFFC, 0xFFFD, 0x340, 0x341, 0x200E, 0x200F, 0x202A, 0x202B, 0x202C, 0x202D, 0x202E, 0x206A, 0x206B, 0x206C, 0x206D, 0x206E, 0x206F, 0xE0001 ); /** * Codepoint ranges prohibited by nameprep * * @static * @var array * @access private */ private static $_np_prohibit_ranges = array( array(0x80, 0x9F ), array(0x2060, 0x206F ), array(0x1D173, 0x1D17A ), array(0xE000, 0xF8FF ), array(0xF0000, 0xFFFFD ), array(0x100000, 0x10FFFD), array(0xFDD0, 0xFDEF ), array(0xD800, 0xDFFF ), array(0x2FF0, 0x2FFB ), array(0xE0020, 0xE007F ) ); /** * Replacement mappings (casemapping, replacement sequences, ...) * * @static * @var array * @access private */ private static $_np_replacemaps = array( 0x41 => array(0x61), 0x42 => array(0x62), 0x43 => array(0x63), 0x44 => array(0x64), 0x45 => array(0x65), 0x46 => array(0x66), 0x47 => array(0x67), 0x48 => array(0x68), 0x49 => array(0x69), 0x4A => array(0x6A), 0x4B => array(0x6B), 0x4C => array(0x6C), 0x4D => array(0x6D), 0x4E => array(0x6E), 0x4F => array(0x6F), 0x50 => array(0x70), 0x51 => array(0x71), 0x52 => array(0x72), 0x53 => array(0x73), 0x54 => array(0x74), 0x55 => array(0x75), 0x56 => array(0x76), 0x57 => array(0x77), 0x58 => array(0x78), 0x59 => array(0x79), 0x5A => array(0x7A), 0xB5 => array(0x3BC), 0xC0 => array(0xE0), 0xC1 => array(0xE1), 0xC2 => array(0xE2), 0xC3 => array(0xE3), 0xC4 => array(0xE4), 0xC5 => array(0xE5), 0xC6 => array(0xE6), 0xC7 => array(0xE7), 0xC8 => array(0xE8), 0xC9 => array(0xE9), 0xCA => array(0xEA), 0xCB => array(0xEB), 0xCC => array(0xEC), 0xCD => array(0xED), 0xCE => array(0xEE), 0xCF => array(0xEF), 0xD0 => array(0xF0), 0xD1 => array(0xF1), 0xD2 => array(0xF2), 0xD3 => array(0xF3), 0xD4 => array(0xF4), 0xD5 => array(0xF5), 0xD6 => array(0xF6), 0xD8 => array(0xF8), 0xD9 => array(0xF9), 0xDA => array(0xFA), 0xDB => array(0xFB), 0xDC => array(0xFC), 0xDD => array(0xFD), 0xDE => array(0xFE), 0xDF => array(0x73, 0x73), 0x100 => array(0x101), 0x102 => array(0x103), 0x104 => array(0x105), 0x106 => array(0x107), 0x108 => array(0x109), 0x10A => array(0x10B), 0x10C => array(0x10D), 0x10E => array(0x10F), 0x110 => array(0x111), 0x112 => array(0x113), 0x114 => array(0x115), 0x116 => array(0x117), 0x118 => array(0x119), 0x11A => array(0x11B), 0x11C => array(0x11D), 0x11E => array(0x11F), 0x120 => array(0x121), 0x122 => array(0x123), 0x124 => array(0x125), 0x126 => array(0x127), 0x128 => array(0x129), 0x12A => array(0x12B), 0x12C => array(0x12D), 0x12E => array(0x12F), 0x130 => array(0x69, 0x307), 0x132 => array(0x133), 0x134 => array(0x135), 0x136 => array(0x137), 0x139 => array(0x13A), 0x13B => array(0x13C), 0x13D => array(0x13E), 0x13F => array(0x140), 0x141 => array(0x142), 0x143 => array(0x144), 0x145 => array(0x146), 0x147 => array(0x148), 0x149 => array(0x2BC, 0x6E), 0x14A => array(0x14B), 0x14C => array(0x14D), 0x14E => array(0x14F), 0x150 => array(0x151), 0x152 => array(0x153), 0x154 => array(0x155), 0x156 => array(0x157), 0x158 => array(0x159), 0x15A => array(0x15B), 0x15C => array(0x15D), 0x15E => array(0x15F), 0x160 => array(0x161), 0x162 => array(0x163), 0x164 => array(0x165), 0x166 => array(0x167), 0x168 => array(0x169), 0x16A => array(0x16B), 0x16C => array(0x16D), 0x16E => array(0x16F), 0x170 => array(0x171), 0x172 => array(0x173), 0x174 => array(0x175), 0x176 => array(0x177), 0x178 => array(0xFF), 0x179 => array(0x17A), 0x17B => array(0x17C), 0x17D => array(0x17E), 0x17F => array(0x73), 0x181 => array(0x253), 0x182 => array(0x183), 0x184 => array(0x185), 0x186 => array(0x254), 0x187 => array(0x188), 0x189 => array(0x256), 0x18A => array(0x257), 0x18B => array(0x18C), 0x18E => array(0x1DD), 0x18F => array(0x259), 0x190 => array(0x25B), 0x191 => array(0x192), 0x193 => array(0x260), 0x194 => array(0x263), 0x196 => array(0x269), 0x197 => array(0x268), 0x198 => array(0x199), 0x19C => array(0x26F), 0x19D => array(0x272), 0x19F => array(0x275), 0x1A0 => array(0x1A1), 0x1A2 => array(0x1A3), 0x1A4 => array(0x1A5), 0x1A6 => array(0x280), 0x1A7 => array(0x1A8), 0x1A9 => array(0x283), 0x1AC => array(0x1AD), 0x1AE => array(0x288), 0x1AF => array(0x1B0), 0x1B1 => array(0x28A), 0x1B2 => array(0x28B), 0x1B3 => array(0x1B4), 0x1B5 => array(0x1B6), 0x1B7 => array(0x292), 0x1B8 => array(0x1B9), 0x1BC => array(0x1BD), 0x1C4 => array(0x1C6), 0x1C5 => array(0x1C6), 0x1C7 => array(0x1C9), 0x1C8 => array(0x1C9), 0x1CA => array(0x1CC), 0x1CB => array(0x1CC), 0x1CD => array(0x1CE), 0x1CF => array(0x1D0), 0x1D1 => array(0x1D2), 0x1D3 => array(0x1D4), 0x1D5 => array(0x1D6), 0x1D7 => array(0x1D8), 0x1D9 => array(0x1DA), 0x1DB => array(0x1DC), 0x1DE => array(0x1DF), 0x1E0 => array(0x1E1), 0x1E2 => array(0x1E3), 0x1E4 => array(0x1E5), 0x1E6 => array(0x1E7), 0x1E8 => array(0x1E9), 0x1EA => array(0x1EB), 0x1EC => array(0x1ED), 0x1EE => array(0x1EF), 0x1F0 => array(0x6A, 0x30C), 0x1F1 => array(0x1F3), 0x1F2 => array(0x1F3), 0x1F4 => array(0x1F5), 0x1F6 => array(0x195), 0x1F7 => array(0x1BF), 0x1F8 => array(0x1F9), 0x1FA => array(0x1FB), 0x1FC => array(0x1FD), 0x1FE => array(0x1FF), 0x200 => array(0x201), 0x202 => array(0x203), 0x204 => array(0x205), 0x206 => array(0x207), 0x208 => array(0x209), 0x20A => array(0x20B), 0x20C => array(0x20D), 0x20E => array(0x20F), 0x210 => array(0x211), 0x212 => array(0x213), 0x214 => array(0x215), 0x216 => array(0x217), 0x218 => array(0x219), 0x21A => array(0x21B), 0x21C => array(0x21D), 0x21E => array(0x21F), 0x220 => array(0x19E), 0x222 => array(0x223), 0x224 => array(0x225), 0x226 => array(0x227), 0x228 => array(0x229), 0x22A => array(0x22B), 0x22C => array(0x22D), 0x22E => array(0x22F), 0x230 => array(0x231), 0x232 => array(0x233), 0x345 => array(0x3B9), 0x37A => array(0x20, 0x3B9), 0x386 => array(0x3AC), 0x388 => array(0x3AD), 0x389 => array(0x3AE), 0x38A => array(0x3AF), 0x38C => array(0x3CC), 0x38E => array(0x3CD), 0x38F => array(0x3CE), 0x390 => array(0x3B9, 0x308, 0x301), 0x391 => array(0x3B1), 0x392 => array(0x3B2), 0x393 => array(0x3B3), 0x394 => array(0x3B4), 0x395 => array(0x3B5), 0x396 => array(0x3B6), 0x397 => array(0x3B7), 0x398 => array(0x3B8), 0x399 => array(0x3B9), 0x39A => array(0x3BA), 0x39B => array(0x3BB), 0x39C => array(0x3BC), 0x39D => array(0x3BD), 0x39E => array(0x3BE), 0x39F => array(0x3BF), 0x3A0 => array(0x3C0), 0x3A1 => array(0x3C1), 0x3A3 => array(0x3C3), 0x3A4 => array(0x3C4), 0x3A5 => array(0x3C5), 0x3A6 => array(0x3C6), 0x3A7 => array(0x3C7), 0x3A8 => array(0x3C8), 0x3A9 => array(0x3C9), 0x3AA => array(0x3CA), 0x3AB => array(0x3CB), 0x3B0 => array(0x3C5, 0x308, 0x301), 0x3C2 => array(0x3C3), 0x3D0 => array(0x3B2), 0x3D1 => array(0x3B8), 0x3D2 => array(0x3C5), 0x3D3 => array(0x3CD), 0x3D4 => array(0x3CB), 0x3D5 => array(0x3C6), 0x3D6 => array(0x3C0), 0x3D8 => array(0x3D9), 0x3DA => array(0x3DB), 0x3DC => array(0x3DD), 0x3DE => array(0x3DF), 0x3E0 => array(0x3E1), 0x3E2 => array(0x3E3), 0x3E4 => array(0x3E5), 0x3E6 => array(0x3E7), 0x3E8 => array(0x3E9), 0x3EA => array(0x3EB), 0x3EC => array(0x3ED), 0x3EE => array(0x3EF), 0x3F0 => array(0x3BA), 0x3F1 => array(0x3C1), 0x3F2 => array(0x3C3), 0x3F4 => array(0x3B8), 0x3F5 => array(0x3B5), 0x400 => array(0x450), 0x401 => array(0x451), 0x402 => array(0x452), 0x403 => array(0x453), 0x404 => array(0x454), 0x405 => array(0x455), 0x406 => array(0x456), 0x407 => array(0x457), 0x408 => array(0x458), 0x409 => array(0x459), 0x40A => array(0x45A), 0x40B => array(0x45B), 0x40C => array(0x45C), 0x40D => array(0x45D), 0x40E => array(0x45E), 0x40F => array(0x45F), 0x410 => array(0x430), 0x411 => array(0x431), 0x412 => array(0x432), 0x413 => array(0x433), 0x414 => array(0x434), 0x415 => array(0x435), 0x416 => array(0x436), 0x417 => array(0x437), 0x418 => array(0x438), 0x419 => array(0x439), 0x41A => array(0x43A), 0x41B => array(0x43B), 0x41C => array(0x43C), 0x41D => array(0x43D), 0x41E => array(0x43E), 0x41F => array(0x43F), 0x420 => array(0x440), 0x421 => array(0x441), 0x422 => array(0x442), 0x423 => array(0x443), 0x424 => array(0x444), 0x425 => array(0x445), 0x426 => array(0x446), 0x427 => array(0x447), 0x428 => array(0x448), 0x429 => array(0x449), 0x42A => array(0x44A), 0x42B => array(0x44B), 0x42C => array(0x44C), 0x42D => array(0x44D), 0x42E => array(0x44E), 0x42F => array(0x44F), 0x460 => array(0x461), 0x462 => array(0x463), 0x464 => array(0x465), 0x466 => array(0x467), 0x468 => array(0x469), 0x46A => array(0x46B), 0x46C => array(0x46D), 0x46E => array(0x46F), 0x470 => array(0x471), 0x472 => array(0x473), 0x474 => array(0x475), 0x476 => array(0x477), 0x478 => array(0x479), 0x47A => array(0x47B), 0x47C => array(0x47D), 0x47E => array(0x47F), 0x480 => array(0x481), 0x48A => array(0x48B), 0x48C => array(0x48D), 0x48E => array(0x48F), 0x490 => array(0x491), 0x492 => array(0x493), 0x494 => array(0x495), 0x496 => array(0x497), 0x498 => array(0x499), 0x49A => array(0x49B), 0x49C => array(0x49D), 0x49E => array(0x49F), 0x4A0 => array(0x4A1), 0x4A2 => array(0x4A3), 0x4A4 => array(0x4A5), 0x4A6 => array(0x4A7), 0x4A8 => array(0x4A9), 0x4AA => array(0x4AB), 0x4AC => array(0x4AD), 0x4AE => array(0x4AF), 0x4B0 => array(0x4B1), 0x4B2 => array(0x4B3), 0x4B4 => array(0x4B5), 0x4B6 => array(0x4B7), 0x4B8 => array(0x4B9), 0x4BA => array(0x4BB), 0x4BC => array(0x4BD), 0x4BE => array(0x4BF), 0x4C1 => array(0x4C2), 0x4C3 => array(0x4C4), 0x4C5 => array(0x4C6), 0x4C7 => array(0x4C8), 0x4C9 => array(0x4CA), 0x4CB => array(0x4CC), 0x4CD => array(0x4CE), 0x4D0 => array(0x4D1), 0x4D2 => array(0x4D3), 0x4D4 => array(0x4D5), 0x4D6 => array(0x4D7), 0x4D8 => array(0x4D9), 0x4DA => array(0x4DB), 0x4DC => array(0x4DD), 0x4DE => array(0x4DF), 0x4E0 => array(0x4E1), 0x4E2 => array(0x4E3), 0x4E4 => array(0x4E5), 0x4E6 => array(0x4E7), 0x4E8 => array(0x4E9), 0x4EA => array(0x4EB), 0x4EC => array(0x4ED), 0x4EE => array(0x4EF), 0x4F0 => array(0x4F1), 0x4F2 => array(0x4F3), 0x4F4 => array(0x4F5), 0x4F8 => array(0x4F9), 0x500 => array(0x501), 0x502 => array(0x503), 0x504 => array(0x505), 0x506 => array(0x507), 0x508 => array(0x509), 0x50A => array(0x50B), 0x50C => array(0x50D), 0x50E => array(0x50F), 0x531 => array(0x561), 0x532 => array(0x562), 0x533 => array(0x563), 0x534 => array(0x564), 0x535 => array(0x565), 0x536 => array(0x566), 0x537 => array(0x567), 0x538 => array(0x568), 0x539 => array(0x569), 0x53A => array(0x56A), 0x53B => array(0x56B), 0x53C => array(0x56C), 0x53D => array(0x56D), 0x53E => array(0x56E), 0x53F => array(0x56F), 0x540 => array(0x570), 0x541 => array(0x571), 0x542 => array(0x572), 0x543 => array(0x573), 0x544 => array(0x574), 0x545 => array(0x575), 0x546 => array(0x576), 0x547 => array(0x577), 0x548 => array(0x578), 0x549 => array(0x579), 0x54A => array(0x57A), 0x54B => array(0x57B), 0x54C => array(0x57C), 0x54D => array(0x57D), 0x54E => array(0x57E), 0x54F => array(0x57F), 0x550 => array(0x580), 0x551 => array(0x581), 0x552 => array(0x582), 0x553 => array(0x583), 0x554 => array(0x584), 0x555 => array(0x585), 0x556 => array(0x586), 0x587 => array(0x565, 0x582), 0x1E00 => array(0x1E01), 0x1E02 => array(0x1E03), 0x1E04 => array(0x1E05), 0x1E06 => array(0x1E07), 0x1E08 => array(0x1E09), 0x1E0A => array(0x1E0B), 0x1E0C => array(0x1E0D), 0x1E0E => array(0x1E0F), 0x1E10 => array(0x1E11), 0x1E12 => array(0x1E13), 0x1E14 => array(0x1E15), 0x1E16 => array(0x1E17), 0x1E18 => array(0x1E19), 0x1E1A => array(0x1E1B), 0x1E1C => array(0x1E1D), 0x1E1E => array(0x1E1F), 0x1E20 => array(0x1E21), 0x1E22 => array(0x1E23), 0x1E24 => array(0x1E25), 0x1E26 => array(0x1E27), 0x1E28 => array(0x1E29), 0x1E2A => array(0x1E2B), 0x1E2C => array(0x1E2D), 0x1E2E => array(0x1E2F), 0x1E30 => array(0x1E31), 0x1E32 => array(0x1E33), 0x1E34 => array(0x1E35), 0x1E36 => array(0x1E37), 0x1E38 => array(0x1E39), 0x1E3A => array(0x1E3B), 0x1E3C => array(0x1E3D), 0x1E3E => array(0x1E3F), 0x1E40 => array(0x1E41), 0x1E42 => array(0x1E43), 0x1E44 => array(0x1E45), 0x1E46 => array(0x1E47), 0x1E48 => array(0x1E49), 0x1E4A => array(0x1E4B), 0x1E4C => array(0x1E4D), 0x1E4E => array(0x1E4F), 0x1E50 => array(0x1E51), 0x1E52 => array(0x1E53), 0x1E54 => array(0x1E55), 0x1E56 => array(0x1E57), 0x1E58 => array(0x1E59), 0x1E5A => array(0x1E5B), 0x1E5C => array(0x1E5D), 0x1E5E => array(0x1E5F), 0x1E60 => array(0x1E61), 0x1E62 => array(0x1E63), 0x1E64 => array(0x1E65), 0x1E66 => array(0x1E67), 0x1E68 => array(0x1E69), 0x1E6A => array(0x1E6B), 0x1E6C => array(0x1E6D), 0x1E6E => array(0x1E6F), 0x1E70 => array(0x1E71), 0x1E72 => array(0x1E73), 0x1E74 => array(0x1E75), 0x1E76 => array(0x1E77), 0x1E78 => array(0x1E79), 0x1E7A => array(0x1E7B), 0x1E7C => array(0x1E7D), 0x1E7E => array(0x1E7F), 0x1E80 => array(0x1E81), 0x1E82 => array(0x1E83), 0x1E84 => array(0x1E85), 0x1E86 => array(0x1E87), 0x1E88 => array(0x1E89), 0x1E8A => array(0x1E8B), 0x1E8C => array(0x1E8D), 0x1E8E => array(0x1E8F), 0x1E90 => array(0x1E91), 0x1E92 => array(0x1E93), 0x1E94 => array(0x1E95), 0x1E96 => array(0x68, 0x331), 0x1E97 => array(0x74, 0x308), 0x1E98 => array(0x77, 0x30A), 0x1E99 => array(0x79, 0x30A), 0x1E9A => array(0x61, 0x2BE), 0x1E9B => array(0x1E61), 0x1EA0 => array(0x1EA1), 0x1EA2 => array(0x1EA3), 0x1EA4 => array(0x1EA5), 0x1EA6 => array(0x1EA7), 0x1EA8 => array(0x1EA9), 0x1EAA => array(0x1EAB), 0x1EAC => array(0x1EAD), 0x1EAE => array(0x1EAF), 0x1EB0 => array(0x1EB1), 0x1EB2 => array(0x1EB3), 0x1EB4 => array(0x1EB5), 0x1EB6 => array(0x1EB7), 0x1EB8 => array(0x1EB9), 0x1EBA => array(0x1EBB), 0x1EBC => array(0x1EBD), 0x1EBE => array(0x1EBF), 0x1EC0 => array(0x1EC1), 0x1EC2 => array(0x1EC3), 0x1EC4 => array(0x1EC5), 0x1EC6 => array(0x1EC7), 0x1EC8 => array(0x1EC9), 0x1ECA => array(0x1ECB), 0x1ECC => array(0x1ECD), 0x1ECE => array(0x1ECF), 0x1ED0 => array(0x1ED1), 0x1ED2 => array(0x1ED3), 0x1ED4 => array(0x1ED5), 0x1ED6 => array(0x1ED7), 0x1ED8 => array(0x1ED9), 0x1EDA => array(0x1EDB), 0x1EDC => array(0x1EDD), 0x1EDE => array(0x1EDF), 0x1EE0 => array(0x1EE1), 0x1EE2 => array(0x1EE3), 0x1EE4 => array(0x1EE5), 0x1EE6 => array(0x1EE7), 0x1EE8 => array(0x1EE9), 0x1EEA => array(0x1EEB), 0x1EEC => array(0x1EED), 0x1EEE => array(0x1EEF), 0x1EF0 => array(0x1EF1), 0x1EF2 => array(0x1EF3), 0x1EF4 => array(0x1EF5), 0x1EF6 => array(0x1EF7), 0x1EF8 => array(0x1EF9), 0x1F08 => array(0x1F00), 0x1F09 => array(0x1F01), 0x1F0A => array(0x1F02), 0x1F0B => array(0x1F03), 0x1F0C => array(0x1F04), 0x1F0D => array(0x1F05), 0x1F0E => array(0x1F06), 0x1F0F => array(0x1F07), 0x1F18 => array(0x1F10), 0x1F19 => array(0x1F11), 0x1F1A => array(0x1F12), 0x1F1B => array(0x1F13), 0x1F1C => array(0x1F14), 0x1F1D => array(0x1F15), 0x1F28 => array(0x1F20), 0x1F29 => array(0x1F21), 0x1F2A => array(0x1F22), 0x1F2B => array(0x1F23), 0x1F2C => array(0x1F24), 0x1F2D => array(0x1F25), 0x1F2E => array(0x1F26), 0x1F2F => array(0x1F27), 0x1F38 => array(0x1F30), 0x1F39 => array(0x1F31), 0x1F3A => array(0x1F32), 0x1F3B => array(0x1F33), 0x1F3C => array(0x1F34), 0x1F3D => array(0x1F35), 0x1F3E => array(0x1F36), 0x1F3F => array(0x1F37), 0x1F48 => array(0x1F40), 0x1F49 => array(0x1F41), 0x1F4A => array(0x1F42), 0x1F4B => array(0x1F43), 0x1F4C => array(0x1F44), 0x1F4D => array(0x1F45), 0x1F50 => array(0x3C5, 0x313), 0x1F52 => array(0x3C5, 0x313, 0x300), 0x1F54 => array(0x3C5, 0x313, 0x301), 0x1F56 => array(0x3C5, 0x313, 0x342), 0x1F59 => array(0x1F51), 0x1F5B => array(0x1F53), 0x1F5D => array(0x1F55), 0x1F5F => array(0x1F57), 0x1F68 => array(0x1F60), 0x1F69 => array(0x1F61), 0x1F6A => array(0x1F62), 0x1F6B => array(0x1F63), 0x1F6C => array(0x1F64), 0x1F6D => array(0x1F65), 0x1F6E => array(0x1F66), 0x1F6F => array(0x1F67), 0x1F80 => array(0x1F00, 0x3B9), 0x1F81 => array(0x1F01, 0x3B9), 0x1F82 => array(0x1F02, 0x3B9), 0x1F83 => array(0x1F03, 0x3B9), 0x1F84 => array(0x1F04, 0x3B9), 0x1F85 => array(0x1F05, 0x3B9), 0x1F86 => array(0x1F06, 0x3B9), 0x1F87 => array(0x1F07, 0x3B9), 0x1F88 => array(0x1F00, 0x3B9), 0x1F89 => array(0x1F01, 0x3B9), 0x1F8A => array(0x1F02, 0x3B9), 0x1F8B => array(0x1F03, 0x3B9), 0x1F8C => array(0x1F04, 0x3B9), 0x1F8D => array(0x1F05, 0x3B9), 0x1F8E => array(0x1F06, 0x3B9), 0x1F8F => array(0x1F07, 0x3B9), 0x1F90 => array(0x1F20, 0x3B9), 0x1F91 => array(0x1F21, 0x3B9), 0x1F92 => array(0x1F22, 0x3B9), 0x1F93 => array(0x1F23, 0x3B9), 0x1F94 => array(0x1F24, 0x3B9), 0x1F95 => array(0x1F25, 0x3B9), 0x1F96 => array(0x1F26, 0x3B9), 0x1F97 => array(0x1F27, 0x3B9), 0x1F98 => array(0x1F20, 0x3B9), 0x1F99 => array(0x1F21, 0x3B9), 0x1F9A => array(0x1F22, 0x3B9), 0x1F9B => array(0x1F23, 0x3B9), 0x1F9C => array(0x1F24, 0x3B9), 0x1F9D => array(0x1F25, 0x3B9), 0x1F9E => array(0x1F26, 0x3B9), 0x1F9F => array(0x1F27, 0x3B9), 0x1FA0 => array(0x1F60, 0x3B9), 0x1FA1 => array(0x1F61, 0x3B9), 0x1FA2 => array(0x1F62, 0x3B9), 0x1FA3 => array(0x1F63, 0x3B9), 0x1FA4 => array(0x1F64, 0x3B9), 0x1FA5 => array(0x1F65, 0x3B9), 0x1FA6 => array(0x1F66, 0x3B9), 0x1FA7 => array(0x1F67, 0x3B9), 0x1FA8 => array(0x1F60, 0x3B9), 0x1FA9 => array(0x1F61, 0x3B9), 0x1FAA => array(0x1F62, 0x3B9), 0x1FAB => array(0x1F63, 0x3B9), 0x1FAC => array(0x1F64, 0x3B9), 0x1FAD => array(0x1F65, 0x3B9), 0x1FAE => array(0x1F66, 0x3B9), 0x1FAF => array(0x1F67, 0x3B9), 0x1FB2 => array(0x1F70, 0x3B9), 0x1FB3 => array(0x3B1, 0x3B9), 0x1FB4 => array(0x3AC, 0x3B9), 0x1FB6 => array(0x3B1, 0x342), 0x1FB7 => array(0x3B1, 0x342, 0x3B9), 0x1FB8 => array(0x1FB0), 0x1FB9 => array(0x1FB1), 0x1FBA => array(0x1F70), 0x1FBB => array(0x1F71), 0x1FBC => array(0x3B1, 0x3B9), 0x1FBE => array(0x3B9), 0x1FC2 => array(0x1F74, 0x3B9), 0x1FC3 => array(0x3B7, 0x3B9), 0x1FC4 => array(0x3AE, 0x3B9), 0x1FC6 => array(0x3B7, 0x342), 0x1FC7 => array(0x3B7, 0x342, 0x3B9), 0x1FC8 => array(0x1F72), 0x1FC9 => array(0x1F73), 0x1FCA => array(0x1F74), 0x1FCB => array(0x1F75), 0x1FCC => array(0x3B7, 0x3B9), 0x1FD2 => array(0x3B9, 0x308, 0x300), 0x1FD3 => array(0x3B9, 0x308, 0x301), 0x1FD6 => array(0x3B9, 0x342), 0x1FD7 => array(0x3B9, 0x308, 0x342), 0x1FD8 => array(0x1FD0), 0x1FD9 => array(0x1FD1), 0x1FDA => array(0x1F76), 0x1FDB => array(0x1F77), 0x1FE2 => array(0x3C5, 0x308, 0x300), 0x1FE3 => array(0x3C5, 0x308, 0x301), 0x1FE4 => array(0x3C1, 0x313), 0x1FE6 => array(0x3C5, 0x342), 0x1FE7 => array(0x3C5, 0x308, 0x342), 0x1FE8 => array(0x1FE0), 0x1FE9 => array(0x1FE1), 0x1FEA => array(0x1F7A), 0x1FEB => array(0x1F7B), 0x1FEC => array(0x1FE5), 0x1FF2 => array(0x1F7C, 0x3B9), 0x1FF3 => array(0x3C9, 0x3B9), 0x1FF4 => array(0x3CE, 0x3B9), 0x1FF6 => array(0x3C9, 0x342), 0x1FF7 => array(0x3C9, 0x342, 0x3B9), 0x1FF8 => array(0x1F78), 0x1FF9 => array(0x1F79), 0x1FFA => array(0x1F7C), 0x1FFB => array(0x1F7D), 0x1FFC => array(0x3C9, 0x3B9), 0x20A8 => array(0x72, 0x73), 0x2102 => array(0x63), 0x2103 => array(0xB0, 0x63), 0x2107 => array(0x25B), 0x2109 => array(0xB0, 0x66), 0x210B => array(0x68), 0x210C => array(0x68), 0x210D => array(0x68), 0x2110 => array(0x69), 0x2111 => array(0x69), 0x2112 => array(0x6C), 0x2115 => array(0x6E), 0x2116 => array(0x6E, 0x6F), 0x2119 => array(0x70), 0x211A => array(0x71), 0x211B => array(0x72), 0x211C => array(0x72), 0x211D => array(0x72), 0x2120 => array(0x73, 0x6D), 0x2121 => array(0x74, 0x65, 0x6C), 0x2122 => array(0x74, 0x6D), 0x2124 => array(0x7A), 0x2126 => array(0x3C9), 0x2128 => array(0x7A), 0x212A => array(0x6B), 0x212B => array(0xE5), 0x212C => array(0x62), 0x212D => array(0x63), 0x2130 => array(0x65), 0x2131 => array(0x66), 0x2133 => array(0x6D), 0x213E => array(0x3B3), 0x213F => array(0x3C0), 0x2145 => array(0x64), 0x2160 => array(0x2170), 0x2161 => array(0x2171), 0x2162 => array(0x2172), 0x2163 => array(0x2173), 0x2164 => array(0x2174), 0x2165 => array(0x2175), 0x2166 => array(0x2176), 0x2167 => array(0x2177), 0x2168 => array(0x2178), 0x2169 => array(0x2179), 0x216A => array(0x217A), 0x216B => array(0x217B), 0x216C => array(0x217C), 0x216D => array(0x217D), 0x216E => array(0x217E), 0x216F => array(0x217F), 0x24B6 => array(0x24D0), 0x24B7 => array(0x24D1), 0x24B8 => array(0x24D2), 0x24B9 => array(0x24D3), 0x24BA => array(0x24D4), 0x24BB => array(0x24D5), 0x24BC => array(0x24D6), 0x24BD => array(0x24D7), 0x24BE => array(0x24D8), 0x24BF => array(0x24D9), 0x24C0 => array(0x24DA), 0x24C1 => array(0x24DB), 0x24C2 => array(0x24DC), 0x24C3 => array(0x24DD), 0x24C4 => array(0x24DE), 0x24C5 => array(0x24DF), 0x24C6 => array(0x24E0), 0x24C7 => array(0x24E1), 0x24C8 => array(0x24E2), 0x24C9 => array(0x24E3), 0x24CA => array(0x24E4), 0x24CB => array(0x24E5), 0x24CC => array(0x24E6), 0x24CD => array(0x24E7), 0x24CE => array(0x24E8), 0x24CF => array(0x24E9), 0x3371 => array(0x68, 0x70, 0x61), 0x3373 => array(0x61, 0x75), 0x3375 => array(0x6F, 0x76), 0x3380 => array(0x70, 0x61), 0x3381 => array(0x6E, 0x61), 0x3382 => array(0x3BC, 0x61), 0x3383 => array(0x6D, 0x61), 0x3384 => array(0x6B, 0x61), 0x3385 => array(0x6B, 0x62), 0x3386 => array(0x6D, 0x62), 0x3387 => array(0x67, 0x62), 0x338A => array(0x70, 0x66), 0x338B => array(0x6E, 0x66), 0x338C => array(0x3BC, 0x66), 0x3390 => array(0x68, 0x7A), 0x3391 => array(0x6B, 0x68, 0x7A), 0x3392 => array(0x6D, 0x68, 0x7A), 0x3393 => array(0x67, 0x68, 0x7A), 0x3394 => array(0x74, 0x68, 0x7A), 0x33A9 => array(0x70, 0x61), 0x33AA => array(0x6B, 0x70, 0x61), 0x33AB => array(0x6D, 0x70, 0x61), 0x33AC => array(0x67, 0x70, 0x61), 0x33B4 => array(0x70, 0x76), 0x33B5 => array(0x6E, 0x76), 0x33B6 => array(0x3BC, 0x76), 0x33B7 => array(0x6D, 0x76), 0x33B8 => array(0x6B, 0x76), 0x33B9 => array(0x6D, 0x76), 0x33BA => array(0x70, 0x77), 0x33BB => array(0x6E, 0x77), 0x33BC => array(0x3BC, 0x77), 0x33BD => array(0x6D, 0x77), 0x33BE => array(0x6B, 0x77), 0x33BF => array(0x6D, 0x77), 0x33C0 => array(0x6B, 0x3C9), 0x33C1 => array(0x6D, 0x3C9), /* 0x33C2 => array(0x61, 0x2E, 0x6D, 0x2E), */ 0x33C3 => array(0x62, 0x71), 0x33C6 => array(0x63, 0x2215, 0x6B, 0x67), 0x33C7 => array(0x63, 0x6F, 0x2E), 0x33C8 => array(0x64, 0x62), 0x33C9 => array(0x67, 0x79), 0x33CB => array(0x68, 0x70), 0x33CD => array(0x6B, 0x6B), 0x33CE => array(0x6B, 0x6D), 0x33D7 => array(0x70, 0x68), 0x33D9 => array(0x70, 0x70, 0x6D), 0x33DA => array(0x70, 0x72), 0x33DC => array(0x73, 0x76), 0x33DD => array(0x77, 0x62), 0xFB00 => array(0x66, 0x66), 0xFB01 => array(0x66, 0x69), 0xFB02 => array(0x66, 0x6C), 0xFB03 => array(0x66, 0x66, 0x69), 0xFB04 => array(0x66, 0x66, 0x6C), 0xFB05 => array(0x73, 0x74), 0xFB06 => array(0x73, 0x74), 0xFB13 => array(0x574, 0x576), 0xFB14 => array(0x574, 0x565), 0xFB15 => array(0x574, 0x56B), 0xFB16 => array(0x57E, 0x576), 0xFB17 => array(0x574, 0x56D), 0xFF21 => array(0xFF41), 0xFF22 => array(0xFF42), 0xFF23 => array(0xFF43), 0xFF24 => array(0xFF44), 0xFF25 => array(0xFF45), 0xFF26 => array(0xFF46), 0xFF27 => array(0xFF47), 0xFF28 => array(0xFF48), 0xFF29 => array(0xFF49), 0xFF2A => array(0xFF4A), 0xFF2B => array(0xFF4B), 0xFF2C => array(0xFF4C), 0xFF2D => array(0xFF4D), 0xFF2E => array(0xFF4E), 0xFF2F => array(0xFF4F), 0xFF30 => array(0xFF50), 0xFF31 => array(0xFF51), 0xFF32 => array(0xFF52), 0xFF33 => array(0xFF53), 0xFF34 => array(0xFF54), 0xFF35 => array(0xFF55), 0xFF36 => array(0xFF56), 0xFF37 => array(0xFF57), 0xFF38 => array(0xFF58), 0xFF39 => array(0xFF59), 0xFF3A => array(0xFF5A), 0x10400 => array(0x10428), 0x10401 => array(0x10429), 0x10402 => array(0x1042A), 0x10403 => array(0x1042B), 0x10404 => array(0x1042C), 0x10405 => array(0x1042D), 0x10406 => array(0x1042E), 0x10407 => array(0x1042F), 0x10408 => array(0x10430), 0x10409 => array(0x10431), 0x1040A => array(0x10432), 0x1040B => array(0x10433), 0x1040C => array(0x10434), 0x1040D => array(0x10435), 0x1040E => array(0x10436), 0x1040F => array(0x10437), 0x10410 => array(0x10438), 0x10411 => array(0x10439), 0x10412 => array(0x1043A), 0x10413 => array(0x1043B), 0x10414 => array(0x1043C), 0x10415 => array(0x1043D), 0x10416 => array(0x1043E), 0x10417 => array(0x1043F), 0x10418 => array(0x10440), 0x10419 => array(0x10441), 0x1041A => array(0x10442), 0x1041B => array(0x10443), 0x1041C => array(0x10444), 0x1041D => array(0x10445), 0x1041E => array(0x10446), 0x1041F => array(0x10447), 0x10420 => array(0x10448), 0x10421 => array(0x10449), 0x10422 => array(0x1044A), 0x10423 => array(0x1044B), 0x10424 => array(0x1044C), 0x10425 => array(0x1044D), 0x1D400 => array(0x61), 0x1D401 => array(0x62), 0x1D402 => array(0x63), 0x1D403 => array(0x64), 0x1D404 => array(0x65), 0x1D405 => array(0x66), 0x1D406 => array(0x67), 0x1D407 => array(0x68), 0x1D408 => array(0x69), 0x1D409 => array(0x6A), 0x1D40A => array(0x6B), 0x1D40B => array(0x6C), 0x1D40C => array(0x6D), 0x1D40D => array(0x6E), 0x1D40E => array(0x6F), 0x1D40F => array(0x70), 0x1D410 => array(0x71), 0x1D411 => array(0x72), 0x1D412 => array(0x73), 0x1D413 => array(0x74), 0x1D414 => array(0x75), 0x1D415 => array(0x76), 0x1D416 => array(0x77), 0x1D417 => array(0x78), 0x1D418 => array(0x79), 0x1D419 => array(0x7A), 0x1D434 => array(0x61), 0x1D435 => array(0x62), 0x1D436 => array(0x63), 0x1D437 => array(0x64), 0x1D438 => array(0x65), 0x1D439 => array(0x66), 0x1D43A => array(0x67), 0x1D43B => array(0x68), 0x1D43C => array(0x69), 0x1D43D => array(0x6A), 0x1D43E => array(0x6B), 0x1D43F => array(0x6C), 0x1D440 => array(0x6D), 0x1D441 => array(0x6E), 0x1D442 => array(0x6F), 0x1D443 => array(0x70), 0x1D444 => array(0x71), 0x1D445 => array(0x72), 0x1D446 => array(0x73), 0x1D447 => array(0x74), 0x1D448 => array(0x75), 0x1D449 => array(0x76), 0x1D44A => array(0x77), 0x1D44B => array(0x78), 0x1D44C => array(0x79), 0x1D44D => array(0x7A), 0x1D468 => array(0x61), 0x1D469 => array(0x62), 0x1D46A => array(0x63), 0x1D46B => array(0x64), 0x1D46C => array(0x65), 0x1D46D => array(0x66), 0x1D46E => array(0x67), 0x1D46F => array(0x68), 0x1D470 => array(0x69), 0x1D471 => array(0x6A), 0x1D472 => array(0x6B), 0x1D473 => array(0x6C), 0x1D474 => array(0x6D), 0x1D475 => array(0x6E), 0x1D476 => array(0x6F), 0x1D477 => array(0x70), 0x1D478 => array(0x71), 0x1D479 => array(0x72), 0x1D47A => array(0x73), 0x1D47B => array(0x74), 0x1D47C => array(0x75), 0x1D47D => array(0x76), 0x1D47E => array(0x77), 0x1D47F => array(0x78), 0x1D480 => array(0x79), 0x1D481 => array(0x7A), 0x1D49C => array(0x61), 0x1D49E => array(0x63), 0x1D49F => array(0x64), 0x1D4A2 => array(0x67), 0x1D4A5 => array(0x6A), 0x1D4A6 => array(0x6B), 0x1D4A9 => array(0x6E), 0x1D4AA => array(0x6F), 0x1D4AB => array(0x70), 0x1D4AC => array(0x71), 0x1D4AE => array(0x73), 0x1D4AF => array(0x74), 0x1D4B0 => array(0x75), 0x1D4B1 => array(0x76), 0x1D4B2 => array(0x77), 0x1D4B3 => array(0x78), 0x1D4B4 => array(0x79), 0x1D4B5 => array(0x7A), 0x1D4D0 => array(0x61), 0x1D4D1 => array(0x62), 0x1D4D2 => array(0x63), 0x1D4D3 => array(0x64), 0x1D4D4 => array(0x65), 0x1D4D5 => array(0x66), 0x1D4D6 => array(0x67), 0x1D4D7 => array(0x68), 0x1D4D8 => array(0x69), 0x1D4D9 => array(0x6A), 0x1D4DA => array(0x6B), 0x1D4DB => array(0x6C), 0x1D4DC => array(0x6D), 0x1D4DD => array(0x6E), 0x1D4DE => array(0x6F), 0x1D4DF => array(0x70), 0x1D4E0 => array(0x71), 0x1D4E1 => array(0x72), 0x1D4E2 => array(0x73), 0x1D4E3 => array(0x74), 0x1D4E4 => array(0x75), 0x1D4E5 => array(0x76), 0x1D4E6 => array(0x77), 0x1D4E7 => array(0x78), 0x1D4E8 => array(0x79), 0x1D4E9 => array(0x7A), 0x1D504 => array(0x61), 0x1D505 => array(0x62), 0x1D507 => array(0x64), 0x1D508 => array(0x65), 0x1D509 => array(0x66), 0x1D50A => array(0x67), 0x1D50D => array(0x6A), 0x1D50E => array(0x6B), 0x1D50F => array(0x6C), 0x1D510 => array(0x6D), 0x1D511 => array(0x6E), 0x1D512 => array(0x6F), 0x1D513 => array(0x70), 0x1D514 => array(0x71), 0x1D516 => array(0x73), 0x1D517 => array(0x74), 0x1D518 => array(0x75), 0x1D519 => array(0x76), 0x1D51A => array(0x77), 0x1D51B => array(0x78), 0x1D51C => array(0x79), 0x1D538 => array(0x61), 0x1D539 => array(0x62), 0x1D53B => array(0x64), 0x1D53C => array(0x65), 0x1D53D => array(0x66), 0x1D53E => array(0x67), 0x1D540 => array(0x69), 0x1D541 => array(0x6A), 0x1D542 => array(0x6B), 0x1D543 => array(0x6C), 0x1D544 => array(0x6D), 0x1D546 => array(0x6F), 0x1D54A => array(0x73), 0x1D54B => array(0x74), 0x1D54C => array(0x75), 0x1D54D => array(0x76), 0x1D54E => array(0x77), 0x1D54F => array(0x78), 0x1D550 => array(0x79), 0x1D56C => array(0x61), 0x1D56D => array(0x62), 0x1D56E => array(0x63), 0x1D56F => array(0x64), 0x1D570 => array(0x65), 0x1D571 => array(0x66), 0x1D572 => array(0x67), 0x1D573 => array(0x68), 0x1D574 => array(0x69), 0x1D575 => array(0x6A), 0x1D576 => array(0x6B), 0x1D577 => array(0x6C), 0x1D578 => array(0x6D), 0x1D579 => array(0x6E), 0x1D57A => array(0x6F), 0x1D57B => array(0x70), 0x1D57C => array(0x71), 0x1D57D => array(0x72), 0x1D57E => array(0x73), 0x1D57F => array(0x74), 0x1D580 => array(0x75), 0x1D581 => array(0x76), 0x1D582 => array(0x77), 0x1D583 => array(0x78), 0x1D584 => array(0x79), 0x1D585 => array(0x7A), 0x1D5A0 => array(0x61), 0x1D5A1 => array(0x62), 0x1D5A2 => array(0x63), 0x1D5A3 => array(0x64), 0x1D5A4 => array(0x65), 0x1D5A5 => array(0x66), 0x1D5A6 => array(0x67), 0x1D5A7 => array(0x68), 0x1D5A8 => array(0x69), 0x1D5A9 => array(0x6A), 0x1D5AA => array(0x6B), 0x1D5AB => array(0x6C), 0x1D5AC => array(0x6D), 0x1D5AD => array(0x6E), 0x1D5AE => array(0x6F), 0x1D5AF => array(0x70), 0x1D5B0 => array(0x71), 0x1D5B1 => array(0x72), 0x1D5B2 => array(0x73), 0x1D5B3 => array(0x74), 0x1D5B4 => array(0x75), 0x1D5B5 => array(0x76), 0x1D5B6 => array(0x77), 0x1D5B7 => array(0x78), 0x1D5B8 => array(0x79), 0x1D5B9 => array(0x7A), 0x1D5D4 => array(0x61), 0x1D5D5 => array(0x62), 0x1D5D6 => array(0x63), 0x1D5D7 => array(0x64), 0x1D5D8 => array(0x65), 0x1D5D9 => array(0x66), 0x1D5DA => array(0x67), 0x1D5DB => array(0x68), 0x1D5DC => array(0x69), 0x1D5DD => array(0x6A), 0x1D5DE => array(0x6B), 0x1D5DF => array(0x6C), 0x1D5E0 => array(0x6D), 0x1D5E1 => array(0x6E), 0x1D5E2 => array(0x6F), 0x1D5E3 => array(0x70), 0x1D5E4 => array(0x71), 0x1D5E5 => array(0x72), 0x1D5E6 => array(0x73), 0x1D5E7 => array(0x74), 0x1D5E8 => array(0x75), 0x1D5E9 => array(0x76), 0x1D5EA => array(0x77), 0x1D5EB => array(0x78), 0x1D5EC => array(0x79), 0x1D5ED => array(0x7A), 0x1D608 => array(0x61), 0x1D609 => array(0x62), 0x1D60A => array(0x63), 0x1D60B => array(0x64), 0x1D60C => array(0x65), 0x1D60D => array(0x66), 0x1D60E => array(0x67), 0x1D60F => array(0x68), 0x1D610 => array(0x69), 0x1D611 => array(0x6A), 0x1D612 => array(0x6B), 0x1D613 => array(0x6C), 0x1D614 => array(0x6D), 0x1D615 => array(0x6E), 0x1D616 => array(0x6F), 0x1D617 => array(0x70), 0x1D618 => array(0x71), 0x1D619 => array(0x72), 0x1D61A => array(0x73), 0x1D61B => array(0x74), 0x1D61C => array(0x75), 0x1D61D => array(0x76), 0x1D61E => array(0x77), 0x1D61F => array(0x78), 0x1D620 => array(0x79), 0x1D621 => array(0x7A), 0x1D63C => array(0x61), 0x1D63D => array(0x62), 0x1D63E => array(0x63), 0x1D63F => array(0x64), 0x1D640 => array(0x65), 0x1D641 => array(0x66), 0x1D642 => array(0x67), 0x1D643 => array(0x68), 0x1D644 => array(0x69), 0x1D645 => array(0x6A), 0x1D646 => array(0x6B), 0x1D647 => array(0x6C), 0x1D648 => array(0x6D), 0x1D649 => array(0x6E), 0x1D64A => array(0x6F), 0x1D64B => array(0x70), 0x1D64C => array(0x71), 0x1D64D => array(0x72), 0x1D64E => array(0x73), 0x1D64F => array(0x74), 0x1D650 => array(0x75), 0x1D651 => array(0x76), 0x1D652 => array(0x77), 0x1D653 => array(0x78), 0x1D654 => array(0x79), 0x1D655 => array(0x7A), 0x1D670 => array(0x61), 0x1D671 => array(0x62), 0x1D672 => array(0x63), 0x1D673 => array(0x64), 0x1D674 => array(0x65), 0x1D675 => array(0x66), 0x1D676 => array(0x67), 0x1D677 => array(0x68), 0x1D678 => array(0x69), 0x1D679 => array(0x6A), 0x1D67A => array(0x6B), 0x1D67B => array(0x6C), 0x1D67C => array(0x6D), 0x1D67D => array(0x6E), 0x1D67E => array(0x6F), 0x1D67F => array(0x70), 0x1D680 => array(0x71), 0x1D681 => array(0x72), 0x1D682 => array(0x73), 0x1D683 => array(0x74), 0x1D684 => array(0x75), 0x1D685 => array(0x76), 0x1D686 => array(0x77), 0x1D687 => array(0x78), 0x1D688 => array(0x79), 0x1D689 => array(0x7A), 0x1D6A8 => array(0x3B1), 0x1D6A9 => array(0x3B2), 0x1D6AA => array(0x3B3), 0x1D6AB => array(0x3B4), 0x1D6AC => array(0x3B5), 0x1D6AD => array(0x3B6), 0x1D6AE => array(0x3B7), 0x1D6AF => array(0x3B8), 0x1D6B0 => array(0x3B9), 0x1D6B1 => array(0x3BA), 0x1D6B2 => array(0x3BB), 0x1D6B3 => array(0x3BC), 0x1D6B4 => array(0x3BD), 0x1D6B5 => array(0x3BE), 0x1D6B6 => array(0x3BF), 0x1D6B7 => array(0x3C0), 0x1D6B8 => array(0x3C1), 0x1D6B9 => array(0x3B8), 0x1D6BA => array(0x3C3), 0x1D6BB => array(0x3C4), 0x1D6BC => array(0x3C5), 0x1D6BD => array(0x3C6), 0x1D6BE => array(0x3C7), 0x1D6BF => array(0x3C8), 0x1D6C0 => array(0x3C9), 0x1D6D3 => array(0x3C3), 0x1D6E2 => array(0x3B1), 0x1D6E3 => array(0x3B2), 0x1D6E4 => array(0x3B3), 0x1D6E5 => array(0x3B4), 0x1D6E6 => array(0x3B5), 0x1D6E7 => array(0x3B6), 0x1D6E8 => array(0x3B7), 0x1D6E9 => array(0x3B8), 0x1D6EA => array(0x3B9), 0x1D6EB => array(0x3BA), 0x1D6EC => array(0x3BB), 0x1D6ED => array(0x3BC), 0x1D6EE => array(0x3BD), 0x1D6EF => array(0x3BE), 0x1D6F0 => array(0x3BF), 0x1D6F1 => array(0x3C0), 0x1D6F2 => array(0x3C1), 0x1D6F3 => array(0x3B8), 0x1D6F4 => array(0x3C3), 0x1D6F5 => array(0x3C4), 0x1D6F6 => array(0x3C5), 0x1D6F7 => array(0x3C6), 0x1D6F8 => array(0x3C7), 0x1D6F9 => array(0x3C8), 0x1D6FA => array(0x3C9), 0x1D70D => array(0x3C3), 0x1D71C => array(0x3B1), 0x1D71D => array(0x3B2), 0x1D71E => array(0x3B3), 0x1D71F => array(0x3B4), 0x1D720 => array(0x3B5), 0x1D721 => array(0x3B6), 0x1D722 => array(0x3B7), 0x1D723 => array(0x3B8), 0x1D724 => array(0x3B9), 0x1D725 => array(0x3BA), 0x1D726 => array(0x3BB), 0x1D727 => array(0x3BC), 0x1D728 => array(0x3BD), 0x1D729 => array(0x3BE), 0x1D72A => array(0x3BF), 0x1D72B => array(0x3C0), 0x1D72C => array(0x3C1), 0x1D72D => array(0x3B8), 0x1D72E => array(0x3C3), 0x1D72F => array(0x3C4), 0x1D730 => array(0x3C5), 0x1D731 => array(0x3C6), 0x1D732 => array(0x3C7), 0x1D733 => array(0x3C8), 0x1D734 => array(0x3C9), 0x1D747 => array(0x3C3), 0x1D756 => array(0x3B1), 0x1D757 => array(0x3B2), 0x1D758 => array(0x3B3), 0x1D759 => array(0x3B4), 0x1D75A => array(0x3B5), 0x1D75B => array(0x3B6), 0x1D75C => array(0x3B7), 0x1D75D => array(0x3B8), 0x1D75E => array(0x3B9), 0x1D75F => array(0x3BA), 0x1D760 => array(0x3BB), 0x1D761 => array(0x3BC), 0x1D762 => array(0x3BD), 0x1D763 => array(0x3BE), 0x1D764 => array(0x3BF), 0x1D765 => array(0x3C0), 0x1D766 => array(0x3C1), 0x1D767 => array(0x3B8), 0x1D768 => array(0x3C3), 0x1D769 => array(0x3C4), 0x1D76A => array(0x3C5), 0x1D76B => array(0x3C6), 0x1D76C => array(0x3C7), 0x1D76D => array(0x3C8), 0x1D76E => array(0x3C9), 0x1D781 => array(0x3C3), 0x1D790 => array(0x3B1), 0x1D791 => array(0x3B2), 0x1D792 => array(0x3B3), 0x1D793 => array(0x3B4), 0x1D794 => array(0x3B5), 0x1D795 => array(0x3B6), 0x1D796 => array(0x3B7), 0x1D797 => array(0x3B8), 0x1D798 => array(0x3B9), 0x1D799 => array(0x3BA), 0x1D79A => array(0x3BB), 0x1D79B => array(0x3BC), 0x1D79C => array(0x3BD), 0x1D79D => array(0x3BE), 0x1D79E => array(0x3BF), 0x1D79F => array(0x3C0), 0x1D7A0 => array(0x3C1), 0x1D7A1 => array(0x3B8), 0x1D7A2 => array(0x3C3), 0x1D7A3 => array(0x3C4), 0x1D7A4 => array(0x3C5), 0x1D7A5 => array(0x3C6), 0x1D7A6 => array(0x3C7), 0x1D7A7 => array(0x3C8), 0x1D7A8 => array(0x3C9), 0x1D7BB => array(0x3C3), 0x3F9 => array(0x3C3), 0x1D2C => array(0x61), 0x1D2D => array(0xE6), 0x1D2E => array(0x62), 0x1D30 => array(0x64), 0x1D31 => array(0x65), 0x1D32 => array(0x1DD), 0x1D33 => array(0x67), 0x1D34 => array(0x68), 0x1D35 => array(0x69), 0x1D36 => array(0x6A), 0x1D37 => array(0x6B), 0x1D38 => array(0x6C), 0x1D39 => array(0x6D), 0x1D3A => array(0x6E), 0x1D3C => array(0x6F), 0x1D3D => array(0x223), 0x1D3E => array(0x70), 0x1D3F => array(0x72), 0x1D40 => array(0x74), 0x1D41 => array(0x75), 0x1D42 => array(0x77), 0x213B => array(0x66, 0x61, 0x78), 0x3250 => array(0x70, 0x74, 0x65), 0x32CC => array(0x68, 0x67), 0x32CE => array(0x65, 0x76), 0x32CF => array(0x6C, 0x74, 0x64), 0x337A => array(0x69, 0x75), 0x33DE => array(0x76, 0x2215, 0x6D), 0x33DF => array(0x61, 0x2215, 0x6D) ); /** * Normalization Combining Classes; Code Points not listed * got Combining Class 0. * * @static * @var array * @access private */ private static $_np_norm_combcls = array( 0x334 => 1, 0x335 => 1, 0x336 => 1, 0x337 => 1, 0x338 => 1, 0x93C => 7, 0x9BC => 7, 0xA3C => 7, 0xABC => 7, 0xB3C => 7, 0xCBC => 7, 0x1037 => 7, 0x3099 => 8, 0x309A => 8, 0x94D => 9, 0x9CD => 9, 0xA4D => 9, 0xACD => 9, 0xB4D => 9, 0xBCD => 9, 0xC4D => 9, 0xCCD => 9, 0xD4D => 9, 0xDCA => 9, 0xE3A => 9, 0xF84 => 9, 0x1039 => 9, 0x1714 => 9, 0x1734 => 9, 0x17D2 => 9, 0x5B0 => 10, 0x5B1 => 11, 0x5B2 => 12, 0x5B3 => 13, 0x5B4 => 14, 0x5B5 => 15, 0x5B6 => 16, 0x5B7 => 17, 0x5B8 => 18, 0x5B9 => 19, 0x5BB => 20, 0x5Bc => 21, 0x5BD => 22, 0x5BF => 23, 0x5C1 => 24, 0x5C2 => 25, 0xFB1E => 26, 0x64B => 27, 0x64C => 28, 0x64D => 29, 0x64E => 30, 0x64F => 31, 0x650 => 32, 0x651 => 33, 0x652 => 34, 0x670 => 35, 0x711 => 36, 0xC55 => 84, 0xC56 => 91, 0xE38 => 103, 0xE39 => 103, 0xE48 => 107, 0xE49 => 107, 0xE4A => 107, 0xE4B => 107, 0xEB8 => 118, 0xEB9 => 118, 0xEC8 => 122, 0xEC9 => 122, 0xECA => 122, 0xECB => 122, 0xF71 => 129, 0xF72 => 130, 0xF7A => 130, 0xF7B => 130, 0xF7C => 130, 0xF7D => 130, 0xF80 => 130, 0xF74 => 132, 0x321 => 202, 0x322 => 202, 0x327 => 202, 0x328 => 202, 0x31B => 216, 0xF39 => 216, 0x1D165 => 216, 0x1D166 => 216, 0x1D16E => 216, 0x1D16F => 216, 0x1D170 => 216, 0x1D171 => 216, 0x1D172 => 216, 0x302A => 218, 0x316 => 220, 0x317 => 220, 0x318 => 220, 0x319 => 220, 0x31C => 220, 0x31D => 220, 0x31E => 220, 0x31F => 220, 0x320 => 220, 0x323 => 220, 0x324 => 220, 0x325 => 220, 0x326 => 220, 0x329 => 220, 0x32A => 220, 0x32B => 220, 0x32C => 220, 0x32D => 220, 0x32E => 220, 0x32F => 220, 0x330 => 220, 0x331 => 220, 0x332 => 220, 0x333 => 220, 0x339 => 220, 0x33A => 220, 0x33B => 220, 0x33C => 220, 0x347 => 220, 0x348 => 220, 0x349 => 220, 0x34D => 220, 0x34E => 220, 0x353 => 220, 0x354 => 220, 0x355 => 220, 0x356 => 220, 0x591 => 220, 0x596 => 220, 0x59B => 220, 0x5A3 => 220, 0x5A4 => 220, 0x5A5 => 220, 0x5A6 => 220, 0x5A7 => 220, 0x5AA => 220, 0x655 => 220, 0x656 => 220, 0x6E3 => 220, 0x6EA => 220, 0x6ED => 220, 0x731 => 220, 0x734 => 220, 0x737 => 220, 0x738 => 220, 0x739 => 220, 0x73B => 220, 0x73C => 220, 0x73E => 220, 0x742 => 220, 0x744 => 220, 0x746 => 220, 0x748 => 220, 0x952 => 220, 0xF18 => 220, 0xF19 => 220, 0xF35 => 220, 0xF37 => 220, 0xFC6 => 220, 0x193B => 220, 0x20E8 => 220, 0x1D17B => 220, 0x1D17C => 220, 0x1D17D => 220, 0x1D17E => 220, 0x1D17F => 220, 0x1D180 => 220, 0x1D181 => 220, 0x1D182 => 220, 0x1D18A => 220, 0x1D18B => 220, 0x59A => 222, 0x5AD => 222, 0x1929 => 222, 0x302D => 222, 0x302E => 224, 0x302F => 224, 0x1D16D => 226, 0x5AE => 228, 0x18A9 => 228, 0x302B => 228, 0x300 => 230, 0x301 => 230, 0x302 => 230, 0x303 => 230, 0x304 => 230, 0x305 => 230, 0x306 => 230, 0x307 => 230, 0x308 => 230, 0x309 => 230, 0x30A => 230, 0x30B => 230, 0x30C => 230, 0x30D => 230, 0x30E => 230, 0x30F => 230, 0x310 => 230, 0x311 => 230, 0x312 => 230, 0x313 => 230, 0x314 => 230, 0x33D => 230, 0x33E => 230, 0x33F => 230, 0x340 => 230, 0x341 => 230, 0x342 => 230, 0x343 => 230, 0x344 => 230, 0x346 => 230, 0x34A => 230, 0x34B => 230, 0x34C => 230, 0x350 => 230, 0x351 => 230, 0x352 => 230, 0x357 => 230, 0x363 => 230, 0x364 => 230, 0x365 => 230, 0x366 => 230, 0x367 => 230, 0x368 => 230, 0x369 => 230, 0x36A => 230, 0x36B => 230, 0x36C => 230, 0x36D => 230, 0x36E => 230, 0x36F => 230, 0x483 => 230, 0x484 => 230, 0x485 => 230, 0x486 => 230, 0x592 => 230, 0x593 => 230, 0x594 => 230, 0x595 => 230, 0x597 => 230, 0x598 => 230, 0x599 => 230, 0x59C => 230, 0x59D => 230, 0x59E => 230, 0x59F => 230, 0x5A0 => 230, 0x5A1 => 230, 0x5A8 => 230, 0x5A9 => 230, 0x5AB => 230, 0x5AC => 230, 0x5AF => 230, 0x5C4 => 230, 0x610 => 230, 0x611 => 230, 0x612 => 230, 0x613 => 230, 0x614 => 230, 0x615 => 230, 0x653 => 230, 0x654 => 230, 0x657 => 230, 0x658 => 230, 0x6D6 => 230, 0x6D7 => 230, 0x6D8 => 230, 0x6D9 => 230, 0x6DA => 230, 0x6DB => 230, 0x6DC => 230, 0x6DF => 230, 0x6E0 => 230, 0x6E1 => 230, 0x6E2 => 230, 0x6E4 => 230, 0x6E7 => 230, 0x6E8 => 230, 0x6EB => 230, 0x6EC => 230, 0x730 => 230, 0x732 => 230, 0x733 => 230, 0x735 => 230, 0x736 => 230, 0x73A => 230, 0x73D => 230, 0x73F => 230, 0x740 => 230, 0x741 => 230, 0x743 => 230, 0x745 => 230, 0x747 => 230, 0x749 => 230, 0x74A => 230, 0x951 => 230, 0x953 => 230, 0x954 => 230, 0xF82 => 230, 0xF83 => 230, 0xF86 => 230, 0xF87 => 230, 0x170D => 230, 0x193A => 230, 0x20D0 => 230, 0x20D1 => 230, 0x20D4 => 230, 0x20D5 => 230, 0x20D6 => 230, 0x20D7 => 230, 0x20DB => 230, 0x20DC => 230, 0x20E1 => 230, 0x20E7 => 230, 0x20E9 => 230, 0xFE20 => 230, 0xFE21 => 230, 0xFE22 => 230, 0xFE23 => 230, 0x1D185 => 230, 0x1D186 => 230, 0x1D187 => 230, 0x1D189 => 230, 0x1D188 => 230, 0x1D1AA => 230, 0x1D1AB => 230, 0x1D1AC => 230, 0x1D1AD => 230, 0x315 => 232, 0x31A => 232, 0x302C => 232, 0x35F => 233, 0x362 => 233, 0x35D => 234, 0x35E => 234, 0x360 => 234, 0x361 => 234, 0x345 => 240 ); // }}} // {{{ properties /** * @var string * @access private */ private $_punycode_prefix = 'xn--'; /** * @access private */ private $_invalid_ucs = 0x80000000; /** * @access private */ private $_max_ucs = 0x10FFFF; /** * @var int * @access private */ private $_base = 36; /** * @var int * @access private */ private $_tmin = 1; /** * @var int * @access private */ private $_tmax = 26; /** * @var int * @access private */ private $_skew = 38; /** * @var int * @access private */ private $_damp = 700; /** * @var int * @access private */ private $_initial_bias = 72; /** * @var int * @access private */ private $_initial_n = 0x80; /** * @var int * @access private */ private $_slast; /** * @access private */ private $_sbase = 0xAC00; /** * @access private */ private $_lbase = 0x1100; /** * @access private */ private $_vbase = 0x1161; /** * @access private */ private $_tbase = 0x11a7; /** * @var int * @access private */ private $_lcount = 19; /** * @var int * @access private */ private $_vcount = 21; /** * @var int * @access private */ private $_tcount = 28; /** * vcount * tcount * * @var int * @access private */ private $_ncount = 588; /** * lcount * tcount * vcount * * @var int * @access private */ private $_scount = 11172; /** * Default encoding for encode()'s input and decode()'s output is UTF-8; * Other possible encodings are ucs4_string and ucs4_array * See {@link setParams()} for how to select these * * @var bool * @access private */ private $_api_encoding = 'utf8'; /** * Overlong UTF-8 encodings are forbidden * * @var bool * @access private */ private $_allow_overlong = false; /** * Behave strict or not * * @var bool * @access private */ private $_strict_mode = false; /** * IDNA-version to use * * Values are "2003" and "2008". * Defaults to "2003", since that was the original version and for * compatibility with previous versions of this library. * If you need to encode "new" characters like the German "Eszett", * please switch to 2008 first before encoding. * * @var bool * @access private */ private $_version = '2003'; /** * Cached value indicating whether or not mbstring function overloading is * on for strlen * * This is cached for optimal performance. * * @var boolean * @see Net_IDNA2::_byteLength() */ private static $_mb_string_overload = null; // }}} // {{{ constructor /** * Constructor * * @param array $options Options to initialise the object with * * @access public * @see setParams() */ public function __construct($options = null) { $this->_slast = $this->_sbase + $this->_lcount * $this->_vcount * $this->_tcount; if (is_array($options)) { $this->setParams($options); } // populate mbstring overloading cache if not set if (self::$_mb_string_overload === null) { self::$_mb_string_overload = (extension_loaded('mbstring') && (ini_get('mbstring.func_overload') & 0x02) === 0x02); } } // }}} /** * Sets a new option value. Available options and values: * * [utf8 - Use either UTF-8 or ISO-8859-1 as input (true for UTF-8, false * otherwise); The output is always UTF-8] * [overlong - Unicode does not allow unnecessarily long encodings of chars, * to allow this, set this parameter to true, else to false; * default is false.] * [strict - true: strict mode, good for registration purposes - Causes errors * on failures; false: loose mode, ideal for "wildlife" applications * by silently ignoring errors and returning the original input instead] * * @param mixed $option Parameter to set (string: single parameter; array of Parameter => Value pairs) * @param string $value Value to use (if parameter 1 is a string) * * @return boolean true on success, false otherwise * @access public */ public function setParams($option, $value = false) { if (!is_array($option)) { $option = array($option => $value); } foreach ($option as $k => $v) { switch ($k) { case 'encoding': switch ($v) { case 'utf8': case 'ucs4_string': case 'ucs4_array': $this->_api_encoding = $v; break; default: throw new InvalidArgumentException('Set Parameter: Unknown parameter '.$v.' for option '.$k); } break; case 'overlong': $this->_allow_overlong = ($v) ? true : false; break; case 'strict': $this->_strict_mode = ($v) ? true : false; break; case 'version': if (in_array($v, array('2003', '2008'))) { $this->_version = $v; } else { throw new InvalidArgumentException('Set Parameter: Invalid parameter '.$v.' for option '.$k); } break; default: return false; } } return true; } /** * Encode a given UTF-8 domain name. * * @param string $decoded Domain name (UTF-8 or UCS-4) * @param string $one_time_encoding Desired input encoding, see {@link set_parameter} * If not given will use default-encoding * * @return string Encoded Domain name (ACE string) * @return mixed processed string * @throws Exception * @access public */ public function encode($decoded, $one_time_encoding = false) { // Forcing conversion of input to UCS4 array // If one time encoding is given, use this, else the objects property switch (($one_time_encoding) ? $one_time_encoding : $this->_api_encoding) { case 'utf8': $decoded = $this->_utf8_to_ucs4($decoded); break; case 'ucs4_string': $decoded = $this->_ucs4_string_to_ucs4($decoded); case 'ucs4_array': // No break; before this line. Catch case, but do nothing break; default: throw new InvalidArgumentException('Unsupported input format'); } // No input, no output, what else did you expect? if (empty($decoded)) return ''; // Anchors for iteration $last_begin = 0; // Output string $output = ''; foreach ($decoded as $k => $v) { // Make sure to use just the plain dot switch($v) { case 0x3002: case 0xFF0E: case 0xFF61: $decoded[$k] = 0x2E; // It's right, no break here // The codepoints above have to be converted to dots anyway // Stumbling across an anchoring character case 0x2E: case 0x2F: case 0x3A: case 0x3F: case 0x40: // Neither email addresses nor URLs allowed in strict mode if ($this->_strict_mode) { throw new InvalidArgumentException('Neither email addresses nor URLs are allowed in strict mode.'); } // Skip first char if ($k) { $encoded = ''; $encoded = $this->_encode(array_slice($decoded, $last_begin, (($k)-$last_begin))); if ($encoded) { $output .= $encoded; } else { $output .= $this->_ucs4_to_utf8(array_slice($decoded, $last_begin, (($k)-$last_begin))); } $output .= chr($decoded[$k]); } $last_begin = $k + 1; } } // Catch the rest of the string if ($last_begin) { $inp_len = sizeof($decoded); $encoded = ''; $encoded = $this->_encode(array_slice($decoded, $last_begin, (($inp_len)-$last_begin))); if ($encoded) { $output .= $encoded; } else { $output .= $this->_ucs4_to_utf8(array_slice($decoded, $last_begin, (($inp_len)-$last_begin))); } return $output; } if ($output = $this->_encode($decoded)) { return $output; } return $this->_ucs4_to_utf8($decoded); } /** * Decode a given ACE domain name. * * @param string $input Domain name (ACE string) * @param string $one_time_encoding Desired output encoding, see {@link set_parameter} * * @return string Decoded Domain name (UTF-8 or UCS-4) * @throws Exception * @access public */ public function decode($input, $one_time_encoding = false) { // Optionally set if ($one_time_encoding) { switch ($one_time_encoding) { case 'utf8': case 'ucs4_string': case 'ucs4_array': break; default: throw new InvalidArgumentException('Unknown encoding '.$one_time_encoding); } } // Make sure to drop any newline characters around $input = trim($input); // Negotiate input and try to determine, whether it is a plain string, // an email address or something like a complete URL if (strpos($input, '@')) { // Maybe it is an email address // No no in strict mode if ($this->_strict_mode) { throw new InvalidArgumentException('Only simple domain name parts can be handled in strict mode'); } list($email_pref, $input) = explode('@', $input, 2); $arr = explode('.', $input); foreach ($arr as $k => $v) { $conv = $this->_decode($v); if ($conv) $arr[$k] = $conv; } $return = $email_pref . '@' . join('.', $arr); } elseif (preg_match('![:\./]!', $input)) { // Or a complete domain name (with or without paths / parameters) // No no in strict mode if ($this->_strict_mode) { throw new InvalidArgumentException('Only simple domain name parts can be handled in strict mode'); } $parsed = parse_url($input); if (isset($parsed['host'])) { $arr = explode('.', $parsed['host']); foreach ($arr as $k => $v) { $conv = $this->_decode($v); if ($conv) $arr[$k] = $conv; } $parsed['host'] = join('.', $arr); if (isset($parsed['scheme'])) { $parsed['scheme'] .= (strtolower($parsed['scheme']) == 'mailto') ? ':' : '://'; } $return = $this->_unparse_url($parsed); } else { // parse_url seems to have failed, try without it $arr = explode('.', $input); foreach ($arr as $k => $v) { $conv = $this->_decode($v); if ($conv) $arr[$k] = $conv; } $return = join('.', $arr); } } else { // Otherwise we consider it being a pure domain name string $return = $this->_decode($input); } // The output is UTF-8 by default, other output formats need conversion here // If one time encoding is given, use this, else the objects property switch (($one_time_encoding) ? $one_time_encoding : $this->_api_encoding) { case 'utf8': return $return; break; case 'ucs4_string': return $this->_ucs4_to_ucs4_string($this->_utf8_to_ucs4($return)); break; case 'ucs4_array': return $this->_utf8_to_ucs4($return); break; default: throw new InvalidArgumentException('Unsupported output format'); } } // {{{ private /** * Opposite function to parse_url() * * Inspired by code from comments of php.net-documentation for parse_url() * * @param array $parts_arr parts (strings) as returned by parse_url() * * @return string * @access private */ private function _unparse_url($parts_arr) { if (!empty($parts_arr['scheme'])) { $ret_url = $parts_arr['scheme']; } if (!empty($parts_arr['user'])) { $ret_url .= $parts_arr['user']; if (!empty($parts_arr['pass'])) { $ret_url .= ':' . $parts_arr['pass']; } $ret_url .= '@'; } $ret_url .= $parts_arr['host']; if (!empty($parts_arr['port'])) { $ret_url .= ':' . $parts_arr['port']; } $ret_url .= $parts_arr['path']; if (!empty($parts_arr['query'])) { $ret_url .= '?' . $parts_arr['query']; } if (!empty($parts_arr['fragment'])) { $ret_url .= '#' . $parts_arr['fragment']; } return $ret_url; } /** * The actual encoding algorithm. * * @param string $decoded Decoded string which should be encoded * * @return string Encoded string * @throws Exception * @access private */ private function _encode($decoded) { // We cannot encode a domain name containing the Punycode prefix $extract = self::_byteLength($this->_punycode_prefix); $check_pref = $this->_utf8_to_ucs4($this->_punycode_prefix); $check_deco = array_slice($decoded, 0, $extract); if ($check_pref == $check_deco) { throw new InvalidArgumentException('This is already a punycode string'); } // We will not try to encode strings consisting of basic code points only $encodable = false; foreach ($decoded as $k => $v) { if ($v > 0x7a) { $encodable = true; break; } } if (!$encodable) { if ($this->_strict_mode) { throw new InvalidArgumentException('The given string does not contain encodable chars'); } return false; } // Do NAMEPREP $decoded = $this->_nameprep($decoded); $deco_len = count($decoded); // Empty array if (!$deco_len) { return false; } // How many chars have been consumed $codecount = 0; // Start with the prefix; copy it to output $encoded = $this->_punycode_prefix; $encoded = ''; // Copy all basic code points to output for ($i = 0; $i < $deco_len; ++$i) { $test = $decoded[$i]; // Will match [0-9a-zA-Z-] if ((0x2F < $test && $test < 0x40) || (0x40 < $test && $test < 0x5B) || (0x60 < $test && $test <= 0x7B) || (0x2D == $test) ) { $encoded .= chr($decoded[$i]); $codecount++; } } // All codepoints were basic ones if ($codecount == $deco_len) { return $encoded; } // Start with the prefix; copy it to output $encoded = $this->_punycode_prefix . $encoded; // If we have basic code points in output, add an hyphen to the end if ($codecount) { $encoded .= '-'; } // Now find and encode all non-basic code points $is_first = true; $cur_code = $this->_initial_n; $bias = $this->_initial_bias; $delta = 0; while ($codecount < $deco_len) { // Find the smallest code point >= the current code point and // remember the last ouccrence of it in the input for ($i = 0, $next_code = $this->_max_ucs; $i < $deco_len; $i++) { if ($decoded[$i] >= $cur_code && $decoded[$i] <= $next_code) { $next_code = $decoded[$i]; } } $delta += ($next_code - $cur_code) * ($codecount + 1); $cur_code = $next_code; // Scan input again and encode all characters whose code point is $cur_code for ($i = 0; $i < $deco_len; $i++) { if ($decoded[$i] < $cur_code) { $delta++; } else if ($decoded[$i] == $cur_code) { for ($q = $delta, $k = $this->_base; 1; $k += $this->_base) { $t = ($k <= $bias)? $this->_tmin : (($k >= $bias + $this->_tmax)? $this->_tmax : $k - $bias); if ($q < $t) { break; } $encoded .= $this->_encodeDigit(ceil($t + (($q - $t) % ($this->_base - $t)))); $q = ($q - $t) / ($this->_base - $t); } $encoded .= $this->_encodeDigit($q); $bias = $this->_adapt($delta, $codecount + 1, $is_first); $codecount++; $delta = 0; $is_first = false; } } $delta++; $cur_code++; } return $encoded; } /** * The actual decoding algorithm. * * @param string $encoded Encoded string which should be decoded * * @return string Decoded string * @throws Exception * @access private */ private function _decode($encoded) { // We do need to find the Punycode prefix if (!preg_match('!^' . preg_quote($this->_punycode_prefix, '!') . '!', $encoded)) { return false; } $encode_test = preg_replace('!^' . preg_quote($this->_punycode_prefix, '!') . '!', '', $encoded); // If nothing left after removing the prefix, it is hopeless if (!$encode_test) { return false; } // Find last occurrence of the delimiter $delim_pos = strrpos($encoded, '-'); if ($delim_pos > self::_byteLength($this->_punycode_prefix)) { for ($k = self::_byteLength($this->_punycode_prefix); $k < $delim_pos; ++$k) { $decoded[] = ord($encoded{$k}); } } else { $decoded = array(); } $deco_len = count($decoded); $enco_len = self::_byteLength($encoded); // Wandering through the strings; init $is_first = true; $bias = $this->_initial_bias; $idx = 0; $char = $this->_initial_n; for ($enco_idx = ($delim_pos)? ($delim_pos + 1) : 0; $enco_idx < $enco_len; ++$deco_len) { for ($old_idx = $idx, $w = 1, $k = $this->_base; 1 ; $k += $this->_base) { $digit = $this->_decodeDigit($encoded{$enco_idx++}); $idx += $digit * $w; $t = ($k <= $bias) ? $this->_tmin : (($k >= $bias + $this->_tmax)? $this->_tmax : ($k - $bias)); if ($digit < $t) { break; } $w = (int)($w * ($this->_base - $t)); } $bias = $this->_adapt($idx - $old_idx, $deco_len + 1, $is_first); $is_first = false; $char += (int) ($idx / ($deco_len + 1)); $idx %= ($deco_len + 1); if ($deco_len > 0) { // Make room for the decoded char for ($i = $deco_len; $i > $idx; $i--) { $decoded[$i] = $decoded[($i - 1)]; } } $decoded[$idx++] = $char; } return $this->_ucs4_to_utf8($decoded); } /** * Adapt the bias according to the current code point and position. * * @param int $delta ... * @param int $npoints ... * @param boolean $is_first ... * * @return int * @access private */ private function _adapt($delta, $npoints, $is_first) { $delta = (int) ($is_first ? ($delta / $this->_damp) : ($delta / 2)); $delta += (int) ($delta / $npoints); for ($k = 0; $delta > (($this->_base - $this->_tmin) * $this->_tmax) / 2; $k += $this->_base) { $delta = (int) ($delta / ($this->_base - $this->_tmin)); } return (int) ($k + ($this->_base - $this->_tmin + 1) * $delta / ($delta + $this->_skew)); } /** * Encoding a certain digit. * * @param int $d One digit to encode * * @return char Encoded digit * @access private */ private function _encodeDigit($d) { return chr($d + 22 + 75 * ($d < 26)); } /** * Decode a certain digit. * * @param char $cp One digit (character) to decode * * @return int Decoded digit * @access private */ private function _decodeDigit($cp) { $cp = ord($cp); return ($cp - 48 < 10)? $cp - 22 : (($cp - 65 < 26)? $cp - 65 : (($cp - 97 < 26)? $cp - 97 : $this->_base)); } /** * Do Nameprep according to RFC3491 and RFC3454. * * @param array $input Unicode Characters * * @return string Unicode Characters, Nameprep'd * @throws Exception * @access private */ private function _nameprep($input) { $output = array(); // Walking through the input array, performing the required steps on each of // the input chars and putting the result into the output array // While mapping required chars we apply the canonical ordering foreach ($input as $v) { // Map to nothing == skip that code point if (in_array($v, self::$_np_map_nothing)) { continue; } // Try to find prohibited input if (in_array($v, self::$_np_prohibit) || in_array($v, self::$_general_prohibited)) { throw new Net_IDNA2_Exception_Nameprep('Prohibited input U+' . sprintf('%08X', $v)); } foreach (self::$_np_prohibit_ranges as $range) { if ($range[0] <= $v && $v <= $range[1]) { throw new Net_IDNA2_Exception_Nameprep('Prohibited input U+' . sprintf('%08X', $v)); } } // Hangul syllable decomposition if (0xAC00 <= $v && $v <= 0xD7AF) { foreach ($this->_hangulDecompose($v) as $out) { $output[] = $out; } } else if (($this->_version == '2003') && isset(self::$_np_replacemaps[$v])) { // There's a decomposition mapping for that code point // Decompositions only in version 2003 (original) of IDNA foreach ($this->_applyCannonicalOrdering(self::$_np_replacemaps[$v]) as $out) { $output[] = $out; } } else { $output[] = $v; } } // Combine code points $last_class = 0; $last_starter = 0; $out_len = count($output); for ($i = 0; $i < $out_len; ++$i) { $class = $this->_getCombiningClass($output[$i]); if ((!$last_class || $last_class != $class) && $class) { // Try to match $seq_len = $i - $last_starter; $out = $this->_combine(array_slice($output, $last_starter, $seq_len)); // On match: Replace the last starter with the composed character and remove // the now redundant non-starter(s) if ($out) { $output[$last_starter] = $out; if (count($out) != $seq_len) { for ($j = $i + 1; $j < $out_len; ++$j) { $output[$j - 1] = $output[$j]; } unset($output[$out_len]); } // Rewind the for loop by one, since there can be more possible compositions $i--; $out_len--; $last_class = ($i == $last_starter)? 0 : $this->_getCombiningClass($output[$i - 1]); continue; } } // The current class is 0 if (!$class) { $last_starter = $i; } $last_class = $class; } return $output; } /** * Decomposes a Hangul syllable * (see http://www.unicode.org/unicode/reports/tr15/#Hangul). * * @param integer $char 32bit UCS4 code point * * @return array Either Hangul Syllable decomposed or original 32bit * value as one value array * @access private */ private function _hangulDecompose($char) { $sindex = $char - $this->_sbase; if ($sindex < 0 || $sindex >= $this->_scount) { return array($char); } $result = array(); $T = $this->_tbase + $sindex % $this->_tcount; $result[] = (int)($this->_lbase + $sindex / $this->_ncount); $result[] = (int)($this->_vbase + ($sindex % $this->_ncount) / $this->_tcount); if ($T != $this->_tbase) { $result[] = $T; } return $result; } /** * Ccomposes a Hangul syllable * (see http://www.unicode.org/unicode/reports/tr15/#Hangul). * * @param array $input Decomposed UCS4 sequence * * @return array UCS4 sequence with syllables composed * @access private */ private function _hangulCompose($input) { $inp_len = count($input); if (!$inp_len) { return array(); } $result = array(); $last = $input[0]; $result[] = $last; // copy first char from input to output for ($i = 1; $i < $inp_len; ++$i) { $char = $input[$i]; // Find out, wether two current characters from L and V $lindex = $last - $this->_lbase; if (0 <= $lindex && $lindex < $this->_lcount) { $vindex = $char - $this->_vbase; if (0 <= $vindex && $vindex < $this->_vcount) { // create syllable of form LV $last = ($this->_sbase + ($lindex * $this->_vcount + $vindex) * $this->_tcount); $out_off = count($result) - 1; $result[$out_off] = $last; // reset last // discard char continue; } } // Find out, wether two current characters are LV and T $sindex = $last - $this->_sbase; if (0 <= $sindex && $sindex < $this->_scount && ($sindex % $this->_tcount) == 0) { $tindex = $char - $this->_tbase; if (0 <= $tindex && $tindex <= $this->_tcount) { // create syllable of form LVT $last += $tindex; $out_off = count($result) - 1; $result[$out_off] = $last; // reset last // discard char continue; } } // if neither case was true, just add the character $last = $char; $result[] = $char; } return $result; } /** * Returns the combining class of a certain wide char. * * @param integer $char Wide char to check (32bit integer) * * @return integer Combining class if found, else 0 * @access private */ private function _getCombiningClass($char) { return isset(self::$_np_norm_combcls[$char])? self::$_np_norm_combcls[$char] : 0; } /** * Apllies the canonical ordering of a decomposed UCS4 sequence. * * @param array $input Decomposed UCS4 sequence * * @return array Ordered USC4 sequence * @access private */ private function _applyCannonicalOrdering($input) { $swap = true; $size = count($input); while ($swap) { $swap = false; $last = $this->_getCombiningClass($input[0]); for ($i = 0; $i < $size - 1; ++$i) { $next = $this->_getCombiningClass($input[$i + 1]); if ($next != 0 && $last > $next) { // Move item leftward until it fits for ($j = $i + 1; $j > 0; --$j) { if ($this->_getCombiningClass($input[$j - 1]) <= $next) { break; } $t = $input[$j]; $input[$j] = $input[$j - 1]; $input[$j - 1] = $t; $swap = 1; } // Reentering the loop looking at the old character again $next = $last; } $last = $next; } } return $input; } /** * Do composition of a sequence of starter and non-starter. * * @param array $input UCS4 Decomposed sequence * * @return array Ordered USC4 sequence * @access private */ private function _combine($input) { $inp_len = count($input); // Is it a Hangul syllable? if (1 != $inp_len) { $hangul = $this->_hangulCompose($input); // This place is probably wrong if (count($hangul) != $inp_len) { return $hangul; } } foreach (self::$_np_replacemaps as $np_src => $np_target) { if ($np_target[0] != $input[0]) { continue; } if (count($np_target) != $inp_len) { continue; } $hit = false; foreach ($input as $k2 => $v2) { if ($v2 == $np_target[$k2]) { $hit = true; } else { $hit = false; break; } } if ($hit) { return $np_src; } } return false; } /** * This converts an UTF-8 encoded string to its UCS-4 (array) representation * By talking about UCS-4 we mean arrays of 32bit integers representing * each of the "chars". This is due to PHP not being able to handle strings with * bit depth different from 8. This applies to the reverse method _ucs4_to_utf8(), too. * The following UTF-8 encodings are supported: * * bytes bits representation * 1 7 0xxxxxxx * 2 11 110xxxxx 10xxxxxx * 3 16 1110xxxx 10xxxxxx 10xxxxxx * 4 21 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx * 5 26 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx * 6 31 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx * * Each x represents a bit that can be used to store character data. * * @param string $input utf8-encoded string * * @return array ucs4-encoded array * @throws Exception * @access private */ private function _utf8_to_ucs4($input) { $output = array(); $out_len = 0; $inp_len = self::_byteLength($input, '8bit'); $mode = 'next'; $test = 'none'; for ($k = 0; $k < $inp_len; ++$k) { $v = ord($input{$k}); // Extract byte from input string if ($v < 128) { // We found an ASCII char - put into string as is $output[$out_len] = $v; ++$out_len; if ('add' == $mode) { throw new UnexpectedValueException('Conversion from UTF-8 to UCS-4 failed: malformed input at byte '.$k); } continue; } if ('next' == $mode) { // Try to find the next start byte; determine the width of the Unicode char $start_byte = $v; $mode = 'add'; $test = 'range'; if ($v >> 5 == 6) { // &110xxxxx 10xxxxx $next_byte = 0; // Tells, how many times subsequent bitmasks must rotate 6bits to the left $v = ($v - 192) << 6; } elseif ($v >> 4 == 14) { // &1110xxxx 10xxxxxx 10xxxxxx $next_byte = 1; $v = ($v - 224) << 12; } elseif ($v >> 3 == 30) { // &11110xxx 10xxxxxx 10xxxxxx 10xxxxxx $next_byte = 2; $v = ($v - 240) << 18; } elseif ($v >> 2 == 62) { // &111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx $next_byte = 3; $v = ($v - 248) << 24; } elseif ($v >> 1 == 126) { // &1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx $next_byte = 4; $v = ($v - 252) << 30; } else { throw new UnexpectedValueException('This might be UTF-8, but I don\'t understand it at byte '.$k); } if ('add' == $mode) { $output[$out_len] = (int) $v; ++$out_len; continue; } } if ('add' == $mode) { if (!$this->_allow_overlong && $test == 'range') { $test = 'none'; if (($v < 0xA0 && $start_byte == 0xE0) || ($v < 0x90 && $start_byte == 0xF0) || ($v > 0x8F && $start_byte == 0xF4)) { throw new OutOfRangeException('Bogus UTF-8 character detected (out of legal range) at byte '.$k); } } if ($v >> 6 == 2) { // Bit mask must be 10xxxxxx $v = ($v - 128) << ($next_byte * 6); $output[($out_len - 1)] += $v; --$next_byte; } else { throw new UnexpectedValueException('Conversion from UTF-8 to UCS-4 failed: malformed input at byte '.$k); } if ($next_byte < 0) { $mode = 'next'; } } } // for return $output; } /** * Convert UCS-4 array into UTF-8 string * * @param array $input ucs4-encoded array * * @return string utf8-encoded string * @throws Exception * @access private */ private function _ucs4_to_utf8($input) { $output = ''; foreach ($input as $v) { // $v = ord($v); if ($v < 128) { // 7bit are transferred literally $output .= chr($v); } else if ($v < 1 << 11) { // 2 bytes $output .= chr(192 + ($v >> 6)) . chr(128 + ($v & 63)); } else if ($v < 1 << 16) { // 3 bytes $output .= chr(224 + ($v >> 12)) . chr(128 + (($v >> 6) & 63)) . chr(128 + ($v & 63)); } else if ($v < 1 << 21) { // 4 bytes $output .= chr(240 + ($v >> 18)) . chr(128 + (($v >> 12) & 63)) . chr(128 + (($v >> 6) & 63)) . chr(128 + ($v & 63)); } else if ($v < 1 << 26) { // 5 bytes $output .= chr(248 + ($v >> 24)) . chr(128 + (($v >> 18) & 63)) . chr(128 + (($v >> 12) & 63)) . chr(128 + (($v >> 6) & 63)) . chr(128 + ($v & 63)); } else if ($v < 1 << 31) { // 6 bytes $output .= chr(252 + ($v >> 30)) . chr(128 + (($v >> 24) & 63)) . chr(128 + (($v >> 18) & 63)) . chr(128 + (($v >> 12) & 63)) . chr(128 + (($v >> 6) & 63)) . chr(128 + ($v & 63)); } else { throw new UnexpectedValueException('Conversion from UCS-4 to UTF-8 failed: malformed input'); } } return $output; } /** * Convert UCS-4 array into UCS-4 string * * @param array $input ucs4-encoded array * * @return string ucs4-encoded string * @throws Exception * @access private */ private function _ucs4_to_ucs4_string($input) { $output = ''; // Take array values and split output to 4 bytes per value // The bit mask is 255, which reads &11111111 foreach ($input as $v) { $output .= ($v & (255 << 24) >> 24) . ($v & (255 << 16) >> 16) . ($v & (255 << 8) >> 8) . ($v & 255); } return $output; } /** * Convert UCS-4 string into UCS-4 array * * @param string $input ucs4-encoded string * * @return array ucs4-encoded array * @throws InvalidArgumentException * @access private */ private function _ucs4_string_to_ucs4($input) { $output = array(); $inp_len = self::_byteLength($input); // Input length must be dividable by 4 if ($inp_len % 4) { throw new InvalidArgumentException('Input UCS4 string is broken'); } // Empty input - return empty output if (!$inp_len) { return $output; } for ($i = 0, $out_len = -1; $i < $inp_len; ++$i) { // Increment output position every 4 input bytes if (!$i % 4) { $out_len++; $output[$out_len] = 0; } $output[$out_len] += ord($input{$i}) << (8 * (3 - ($i % 4) ) ); } return $output; } /** * Echo hex representation of UCS4 sequence. * * @param array $input UCS4 sequence * @param boolean $include_bit Include bitmask in output * * @return void * @static * @access private */ private static function _showHex($input, $include_bit = false) { foreach ($input as $k => $v) { echo '[', $k, '] => ', sprintf('%X', $v); if ($include_bit) { echo ' (', Net_IDNA2::_showBitmask($v), ')'; } echo "\n"; } } /** * Gives you a bit representation of given Byte (8 bits), Word (16 bits) or DWord (32 bits) * Output width is automagically determined * * @param int $octet ... * * @return string Bitmask-representation * @static * @access private */ private static function _showBitmask($octet) { if ($octet >= (1 << 16)) { $w = 31; } else if ($octet >= (1 << 8)) { $w = 15; } else { $w = 7; } $return = ''; for ($i = $w; $i > -1; $i--) { $return .= ($octet & (1 << $i))? '1' : '0'; } return $return; } /** * Gets the length of a string in bytes even if mbstring function * overloading is turned on * * @param string $string the string for which to get the length. * * @return integer the length of the string in bytes. * * @see Net_IDNA2::$_mb_string_overload */ private static function _byteLength($string) { if (self::$_mb_string_overload) { return mb_strlen($string, '8bit'); } return strlen((binary)$string); } // }}}} // {{{ factory /** * Attempts to return a concrete IDNA instance for either php4 or php5. * * @param array $params Set of paramaters * * @return Net_IDNA2 * @access public */ public static function getInstance($params = array()) { return new Net_IDNA2($params); } // }}} // {{{ singleton /** * Attempts to return a concrete IDNA instance for either php4 or php5, * only creating a new instance if no IDNA instance with the same * parameters currently exists. * * @param array $params Set of parameters * * @return object Net_IDNA2 * @access public */ public static function singleton($params = array()) { static $instances; if (!isset($instances)) { $instances = array(); } $signature = serialize($params); if (!isset($instances[$signature])) { $instances[$signature] = Net_IDNA2::getInstance($params); } return $instances[$signature]; } // }}} } ?> PKu]NFUFUNet/Socket.phpnu[ * @author Chuck Hagenbuch * @copyright 1997-2017 The PHP Group * @license http://opensource.org/licenses/bsd-license.php BSD-2-Clause * @link http://pear.php.net/packages/Net_Socket */ require_once 'PEAR.php'; define('NET_SOCKET_READ', 1); define('NET_SOCKET_WRITE', 2); define('NET_SOCKET_ERROR', 4); /** * Generalized Socket class. * * @category Net * @package Net_Socket * @author Stig Bakken * @author Chuck Hagenbuch * @copyright 1997-2017 The PHP Group * @license http://opensource.org/licenses/bsd-license.php BSD-2-Clause * @link http://pear.php.net/packages/Net_Socket */ class Net_Socket extends PEAR { /** * Socket file pointer. * @var resource $fp */ public $fp = null; /** * Whether the socket is blocking. Defaults to true. * @var boolean $blocking */ public $blocking = true; /** * Whether the socket is persistent. Defaults to false. * @var boolean $persistent */ public $persistent = false; /** * The IP address to connect to. * @var string $addr */ public $addr = ''; /** * The port number to connect to. * @var integer $port */ public $port = 0; /** * Number of seconds to wait on socket operations before assuming * there's no more data. Defaults to no timeout. * @var integer|float $timeout */ public $timeout = null; /** * Number of bytes to read at a time in readLine() and * readAll(). Defaults to 2048. * @var integer $lineLength */ public $lineLength = 2048; /** * The string to use as a newline terminator. Usually "\r\n" or "\n". * @var string $newline */ public $newline = "\r\n"; /** * Connect to the specified port. If called when the socket is * already connected, it disconnects and connects again. * * @param string $addr IP address or host name (may be with protocol prefix). * @param integer $port TCP port number. * @param boolean $persistent (optional) Whether the connection is * persistent (kept open between requests * by the web server). * @param integer $timeout (optional) Connection socket timeout. * @param array $options See options for stream_context_create. * * @access public * * @return boolean|PEAR_Error True on success or a PEAR_Error on failure. */ public function connect( $addr, $port = 0, $persistent = null, $timeout = null, $options = null ) { if (is_resource($this->fp)) { @fclose($this->fp); $this->fp = null; } if (!$addr) { return $this->raiseError('$addr cannot be empty'); } else { if (strspn($addr, ':.0123456789') === strlen($addr)) { $this->addr = strpos($addr, ':') !== false ? '[' . $addr . ']' : $addr; } else { $this->addr = $addr; } } $this->port = $port % 65536; if ($persistent !== null) { $this->persistent = $persistent; } $openfunc = $this->persistent ? 'pfsockopen' : 'fsockopen'; $errno = 0; $errstr = ''; if (function_exists('error_clear_last')) { error_clear_last(); } else { $old_track_errors = @ini_set('track_errors', 1); } if ($timeout <= 0) { $timeout = @ini_get('default_socket_timeout'); } if ($options && function_exists('stream_context_create')) { $context = stream_context_create($options); // Since PHP 5 fsockopen doesn't allow context specification if (function_exists('stream_socket_client')) { $flags = STREAM_CLIENT_CONNECT; if ($this->persistent) { $flags = STREAM_CLIENT_PERSISTENT; } $addr = $this->addr . ':' . $this->port; $fp = @stream_socket_client($addr, $errno, $errstr, $timeout, $flags, $context); } else { $fp = @$openfunc($this->addr, $this->port, $errno, $errstr, $timeout, $context); } } else { $fp = @$openfunc($this->addr, $this->port, $errno, $errstr, $timeout); } if (!$fp) { if ($errno === 0 && !strlen($errstr)) { $errstr = ''; if (isset($old_track_errors)) { $errstr = $php_errormsg ?: ''; @ini_set('track_errors', $old_track_errors); } else { $lastError = error_get_last(); if (isset($lastError['message'])) { $errstr = $lastError['message']; } } } return $this->raiseError($errstr, $errno); } if (isset($old_track_errors)) { @ini_set('track_errors', $old_track_errors); } $this->fp = $fp; $this->setTimeout(); return $this->setBlocking($this->blocking); } /** * Disconnects from the peer, closes the socket. * * @access public * @return mixed true on success or a PEAR_Error instance otherwise */ public function disconnect() { if (!is_resource($this->fp)) { return $this->raiseError('not connected'); } @fclose($this->fp); $this->fp = null; return true; } /** * Set the newline character/sequence to use. * * @param string $newline Newline character(s) * @return boolean True */ public function setNewline($newline) { $this->newline = $newline; return true; } /** * Find out if the socket is in blocking mode. * * @access public * @return boolean The current blocking mode. */ public function isBlocking() { return $this->blocking; } /** * Sets whether the socket connection should be blocking or * not. A read call to a non-blocking socket will return immediately * if there is no data available, whereas it will block until there * is data for blocking sockets. * * @param boolean $mode True for blocking sockets, false for nonblocking. * * @access public * @return mixed true on success or a PEAR_Error instance otherwise */ public function setBlocking($mode) { if (!is_resource($this->fp)) { return $this->raiseError('not connected'); } $this->blocking = $mode; stream_set_blocking($this->fp, (int)$this->blocking); return true; } /** * Sets the timeout value on socket descriptor, * expressed in the sum of seconds and microseconds * * @param integer $seconds Seconds. * @param integer $microseconds Microseconds, optional. * * @access public * @return mixed True on success or false on failure or * a PEAR_Error instance when not connected */ public function setTimeout($seconds = null, $microseconds = null) { if (!is_resource($this->fp)) { return $this->raiseError('not connected'); } if ($seconds === null && $microseconds === null) { $seconds = (int)$this->timeout; $microseconds = (int)(($this->timeout - $seconds) * 1000000); } else { $this->timeout = $seconds + $microseconds / 1000000; } if ($this->timeout > 0) { return stream_set_timeout($this->fp, (int)$seconds, (int)$microseconds); } else { return false; } } /** * Sets the file buffering size on the stream. * See php's stream_set_write_buffer for more information. * * @param integer $size Write buffer size. * * @access public * @return mixed on success or an PEAR_Error object otherwise */ public function setWriteBuffer($size) { if (!is_resource($this->fp)) { return $this->raiseError('not connected'); } $returned = stream_set_write_buffer($this->fp, $size); if ($returned === 0) { return true; } return $this->raiseError('Cannot set write buffer.'); } /** * Returns information about an existing socket resource. * Currently returns four entries in the result array: * *

* timed_out (bool) - The socket timed out waiting for data
* blocked (bool) - The socket was blocked
* eof (bool) - Indicates EOF event
* unread_bytes (int) - Number of bytes left in the socket buffer
*

* * @access public * @return mixed Array containing information about existing socket * resource or a PEAR_Error instance otherwise */ public function getStatus() { if (!is_resource($this->fp)) { return $this->raiseError('not connected'); } return stream_get_meta_data($this->fp); } /** * Get a specified line of data * * @param int $size Reading ends when size - 1 bytes have been read, * or a newline or an EOF (whichever comes first). * If no size is specified, it will keep reading from * the stream until it reaches the end of the line. * * @access public * @return mixed $size bytes of data from the socket, or a PEAR_Error if * not connected. If an error occurs, FALSE is returned. */ public function gets($size = null) { if (!is_resource($this->fp)) { return $this->raiseError('not connected'); } if (null === $size) { return @fgets($this->fp); } else { return @fgets($this->fp, $size); } } /** * Read a specified amount of data. This is guaranteed to return, * and has the added benefit of getting everything in one fread() * chunk; if you know the size of the data you're getting * beforehand, this is definitely the way to go. * * @param integer $size The number of bytes to read from the socket. * * @access public * @return string $size bytes of data from the socket, or a PEAR_Error if * not connected. */ public function read($size) { if (!is_resource($this->fp)) { return $this->raiseError('not connected'); } return @fread($this->fp, $size); } /** * Write a specified amount of data. * * @param string $data Data to write. * @param integer $blocksize Amount of data to write at once. * NULL means all at once. * * @access public * @return mixed If the socket is not connected, returns an instance of * PEAR_Error. * If the write succeeds, returns the number of bytes written. * If the write fails, returns false. * If the socket times out, returns an instance of PEAR_Error. */ public function write($data, $blocksize = null) { if (!is_resource($this->fp)) { return $this->raiseError('not connected'); } if (null === $blocksize && !OS_WINDOWS) { $written = @fwrite($this->fp, $data); // Check for timeout or lost connection if ($written === false) { $meta_data = $this->getStatus(); if (!is_array($meta_data)) { return $meta_data; // PEAR_Error } if (!empty($meta_data['timed_out'])) { return $this->raiseError('timed out'); } } return $written; } else { if (null === $blocksize) { $blocksize = 1024; } $pos = 0; $size = strlen($data); while ($pos < $size) { $written = @fwrite($this->fp, substr($data, $pos, $blocksize)); // Check for timeout or lost connection if ($written === false) { $meta_data = $this->getStatus(); if (!is_array($meta_data)) { return $meta_data; // PEAR_Error } if (!empty($meta_data['timed_out'])) { return $this->raiseError('timed out'); } return $written; } $pos += $written; } return $pos; } } /** * Write a line of data to the socket, followed by a trailing newline. * * @param string $data Data to write * * @access public * @return mixed fwrite() result, or PEAR_Error when not connected */ public function writeLine($data) { if (!is_resource($this->fp)) { return $this->raiseError('not connected'); } return fwrite($this->fp, $data . $this->newline); } /** * Tests for end-of-file on a socket descriptor. * * Also returns true if the socket is disconnected. * * @access public * @return bool */ public function eof() { return (!is_resource($this->fp) || feof($this->fp)); } /** * Reads a byte of data * * @access public * @return integer 1 byte of data from the socket, or a PEAR_Error if * not connected. */ public function readByte() { if (!is_resource($this->fp)) { return $this->raiseError('not connected'); } return ord(@fread($this->fp, 1)); } /** * Reads a word of data * * @access public * @return integer 1 word of data from the socket, or a PEAR_Error if * not connected. */ public function readWord() { if (!is_resource($this->fp)) { return $this->raiseError('not connected'); } $buf = @fread($this->fp, 2); return (ord($buf[0]) + (ord($buf[1]) << 8)); } /** * Reads an int of data * * @access public * @return integer 1 int of data from the socket, or a PEAR_Error if * not connected. */ public function readInt() { if (!is_resource($this->fp)) { return $this->raiseError('not connected'); } $buf = @fread($this->fp, 4); return (ord($buf[0]) + (ord($buf[1]) << 8) + (ord($buf[2]) << 16) + (ord($buf[3]) << 24)); } /** * Reads a zero-terminated string of data * * @access public * @return string, or a PEAR_Error if * not connected. */ public function readString() { if (!is_resource($this->fp)) { return $this->raiseError('not connected'); } $string = ''; while (($char = @fread($this->fp, 1)) !== "\x00") { $string .= $char; } return $string; } /** * Reads an IP Address and returns it in a dot formatted string * * @access public * @return string Dot formatted string, or a PEAR_Error if * not connected. */ public function readIPAddress() { if (!is_resource($this->fp)) { return $this->raiseError('not connected'); } $buf = @fread($this->fp, 4); return sprintf('%d.%d.%d.%d', ord($buf[0]), ord($buf[1]), ord($buf[2]), ord($buf[3])); } /** * Read until either the end of the socket or a newline, whichever * comes first. Strips the trailing newline from the returned data. * * @access public * @return string All available data up to a newline, without that * newline, or until the end of the socket, or a PEAR_Error if * not connected. */ public function readLine() { if (!is_resource($this->fp)) { return $this->raiseError('not connected'); } $line = ''; $timeout = time() + $this->timeout; while (!feof($this->fp) && (!$this->timeout || time() < $timeout)) { $line .= @fgets($this->fp, $this->lineLength); if (substr($line, -1) == "\n") { return rtrim($line, $this->newline); } } return $line; } /** * Read until the socket closes, or until there is no more data in * the inner PHP buffer. If the inner buffer is empty, in blocking * mode we wait for at least 1 byte of data. Therefore, in * blocking mode, if there is no data at all to be read, this * function will never exit (unless the socket is closed on the * remote end). * * @access public * * @return string All data until the socket closes, or a PEAR_Error if * not connected. */ public function readAll() { if (!is_resource($this->fp)) { return $this->raiseError('not connected'); } $data = ''; $timeout = time() + $this->timeout; while (!feof($this->fp) && (!$this->timeout || time() < $timeout)) { $data .= @fread($this->fp, $this->lineLength); } return $data; } /** * Runs the equivalent of the select() system call on the socket * with a timeout specified by tv_sec and tv_usec. * * @param integer $state Which of read/write/error to check for. * @param integer $tv_sec Number of seconds for timeout. * @param integer $tv_usec Number of microseconds for timeout. * * @access public * @return False if select fails, integer describing which of read/write/error * are ready, or PEAR_Error if not connected. */ public function select($state, $tv_sec, $tv_usec = 0) { if (!is_resource($this->fp)) { return $this->raiseError('not connected'); } $read = null; $write = null; $except = null; if ($state & NET_SOCKET_READ) { $read[] = $this->fp; } if ($state & NET_SOCKET_WRITE) { $write[] = $this->fp; } if ($state & NET_SOCKET_ERROR) { $except[] = $this->fp; } if (false === ($sr = stream_select($read, $write, $except, $tv_sec, $tv_usec)) ) { return false; } $result = 0; if (count($read)) { $result |= NET_SOCKET_READ; } if (count($write)) { $result |= NET_SOCKET_WRITE; } if (count($except)) { $result |= NET_SOCKET_ERROR; } return $result; } /** * Turns encryption on/off on a connected socket. * * @param bool $enabled Set this parameter to true to enable encryption * and false to disable encryption. * @param integer $type Type of encryption. See stream_socket_enable_crypto() * for values. * * @see http://se.php.net/manual/en/function.stream-socket-enable-crypto.php * @access public * @return false on error, true on success and 0 if there isn't enough data * and the user should try again (non-blocking sockets only). * A PEAR_Error object is returned if the socket is not * connected */ public function enableCrypto($enabled, $type) { if (version_compare(phpversion(), '5.1.0', '>=')) { if (!is_resource($this->fp)) { return $this->raiseError('not connected'); } return @stream_socket_enable_crypto($this->fp, $enabled, $type); } else { $msg = 'Net_Socket::enableCrypto() requires php version >= 5.1.0'; return $this->raiseError($msg); } } } PKu]ZZ Net/Sieve.phpnu[ * @author Damian Fernandez Sosa * @author Anish Mistry * @author Jan Schneider * @copyright 2002-2003 Richard Heyes * @copyright 2006-2008 Anish Mistry * @license http://www.opensource.org/licenses/bsd-license.php BSD * @link http://pear.php.net/package/Net_Sieve */ require_once 'PEAR.php'; require_once 'Net/Socket.php'; /** * Disconnected state * * @const NET_SIEVE_STATE_DISCONNECTED */ define('NET_SIEVE_STATE_DISCONNECTED', 1); /** * Authorisation state * * @const NET_SIEVE_STATE_AUTHORISATION */ define('NET_SIEVE_STATE_AUTHORISATION', 2); /** * Transaction state * * @const NET_SIEVE_STATE_TRANSACTION */ define('NET_SIEVE_STATE_TRANSACTION', 3); /** * A class for talking to the timsieved server which comes with Cyrus IMAP. * * @category Networking * @package Net_Sieve * @author Richard Heyes * @author Damian Fernandez Sosa * @author Anish Mistry * @author Jan Schneider * @author Neil Munday * @copyright 2002-2003 Richard Heyes * @copyright 2006-2008 Anish Mistry * @license http://www.opensource.org/licenses/bsd-license.php BSD * @version Release: 1.4.5 * @link http://pear.php.net/package/Net_Sieve * @link http://tools.ietf.org/html/rfc5228 RFC 5228 (Sieve: An Email * Filtering Language) * @link http://tools.ietf.org/html/rfc5804 RFC 5804 A Protocol for * Remotely Managing Sieve Scripts */ class Net_Sieve { /** * The authentication methods this class supports. * * Can be overwritten if having problems with certain methods. * * @var array */ var $supportedAuthMethods = array( 'DIGEST-MD5', 'CRAM-MD5', 'EXTERNAL', 'PLAIN' , 'LOGIN', 'GSSAPI', 'XOAUTH2' ); /** * SASL authentication methods that require Auth_SASL. * * @var array */ var $supportedSASLAuthMethods = array('DIGEST-MD5', 'CRAM-MD5'); /** * The socket handle. * * @var resource */ var $_sock; /** * Parameters and connection information. * * @var array */ var $_data; /** * Current state of the connection. * * One of the NET_SIEVE_STATE_* constants. * * @var integer */ var $_state; /** * PEAR object to avoid strict warnings. * * @var PEAR_Error */ var $_pear; /** * Constructor error. * * @var PEAR_Error */ var $_error; /** * Whether to enable debugging. * * @var boolean */ var $_debug = false; /** * Debug output handler. * * This has to be a valid callback. * * @var string|array */ var $_debug_handler = null; /** * Whether to pick up an already established connection. * * @var boolean */ var $_bypassAuth = false; /** * Whether to use TLS if available. * * @var boolean */ var $_useTLS = true; /** * Additional options for stream_context_create(). * * @var array */ var $_options = null; /** * Maximum number of referral loops * * @var array */ var $_maxReferralCount = 15; /** * Kerberos service principal to use for GSSAPI authentication. * * @var string */ var $_gssapiPrincipal = null; /** * Kerberos service cname to use for GSSAPI authentication. * * @var string */ var $_gssapiCN = null; /** * Constructor. * * Sets up the object, connects to the server and logs in. Stores any * generated error in $this->_error, which can be retrieved using the * getError() method. * * @param string $user Login username. * @param string $pass Login password. * @param string $host Hostname of server. * @param string $port Port of server. * @param string $logintype Type of login to perform (see * $supportedAuthMethods). * @param string $euser Effective user. If authenticating as an * administrator, login as this user. * @param boolean $debug Whether to enable debugging (@see setDebug()). * @param string $bypassAuth Skip the authentication phase. Useful if the * socket is already open. * @param boolean $useTLS Use TLS if available. * @param array $options Additional options for * stream_context_create(). * @param mixed $handler A callback handler for the debug output. * @param string $principal Kerberos service principal to use * with GSSAPI authentication. * @param string $cname Kerberos service cname to use * with GSSAPI authentication. */ function __construct($user = null, $pass = null, $host = 'localhost', $port = 2000, $logintype = '', $euser = '', $debug = false, $bypassAuth = false, $useTLS = true, $options = null, $handler = null, $principal = null, $cname = null ) { $this->_pear = new PEAR(); $this->_state = NET_SIEVE_STATE_DISCONNECTED; $this->_data['user'] = $user; $this->_data['pass'] = $pass; $this->_data['host'] = $host; $this->_data['port'] = $port; $this->_data['logintype'] = $logintype; $this->_data['euser'] = $euser; $this->_sock = new Net_Socket(); $this->_bypassAuth = $bypassAuth; $this->_useTLS = $useTLS; $this->_options = (array) $options; $this->_gssapiPrincipal = $principal; $this->_gssapiCN = $cname; $this->setDebug($debug, $handler); /* Try to include the Auth_SASL package. If the package is not * available, we disable the authentication methods that depend upon * it. */ if ((@include_once 'Auth/SASL.php') === false) { $this->_debug('Auth_SASL not present'); $this->supportedAuthMethods = array_diff( $this->supportedAuthMethods, $this->supportedSASLAuthMethods ); } if (strlen($user) && strlen($pass)) { $this->_error = $this->_handleConnectAndLogin(); } } /** * Returns any error that may have been generated in the constructor. * * @return boolean|PEAR_Error False if no error, PEAR_Error otherwise. */ function getError() { return is_a($this->_error, 'PEAR_Error') ? $this->_error : false; } /** * Sets the debug state and handler function. * * @param boolean $debug Whether to enable debugging. * @param string $handler A custom debug handler. Must be a valid callback. * * @return void */ function setDebug($debug = true, $handler = null) { $this->_debug = $debug; $this->_debug_handler = $handler; } /** * Sets the Kerberos service principal for use with GSSAPI * authentication. * * @param string $principal The Kerberos service principal * * @return void */ function setServicePrincipal($principal) { $this->_gssapiPrincipal = $principal; } /** * Sets the Kerberos service CName for use with GSSAPI * authentication. * * @param string $cname The Kerberos service principal * * @return void */ function setServiceCN($cname) { $this->_gssapiCN = $cname; } /** * Connects to the server and logs in. * * @return boolean True on success, PEAR_Error on failure. */ function _handleConnectAndLogin() { $res = $this->connect($this->_data['host'], $this->_data['port'], $this->_options, $this->_useTLS); if (is_a($res, 'PEAR_Error')) { return $res; } if ($this->_bypassAuth === false) { $res = $this->login($this->_data['user'], $this->_data['pass'], $this->_data['logintype'], $this->_data['euser'], $this->_bypassAuth); if (is_a($res, 'PEAR_Error')) { return $res; } } return true; } /** * Handles connecting to the server and checks the response validity. * * @param string $host Hostname of server. * @param string $port Port of server. * @param array $options List of options to pass to * stream_context_create(). * @param boolean $useTLS Use TLS if available. * * @return boolean True on success, PEAR_Error otherwise. */ function connect($host, $port, $options = null, $useTLS = true) { $this->_data['host'] = $host; $this->_data['port'] = $port; $this->_useTLS = $useTLS; if (is_array($options)) { $this->_options = array_merge($this->_options, $options); } if (NET_SIEVE_STATE_DISCONNECTED != $this->_state) { return $this->_pear->raiseError('Not currently in DISCONNECTED state', 1); } $res = $this->_sock->connect($host, $port, false, 5, $options); if (is_a($res, 'PEAR_Error')) { return $res; } if ($this->_bypassAuth) { $this->_state = NET_SIEVE_STATE_TRANSACTION; // Reset capabilities $this->_parseCapability(''); } else { $this->_state = NET_SIEVE_STATE_AUTHORISATION; $res = $this->_doCmd(); if (is_a($res, 'PEAR_Error')) { return $res; } // Reset capabilities (use unattended capabilities) $this->_parseCapability($res); } // Explicitly ask for the capabilities if needed if (empty($this->_capability['implementation'])) { $res = $this->_cmdCapability(); if (is_a($res, 'PEAR_Error')) { return $this->_pear->raiseError( 'Failed to connect, server said: ' . $res->getMessage(), 2 ); } } // Check if we can enable TLS via STARTTLS. if ($useTLS && !empty($this->_capability['starttls']) && function_exists('stream_socket_enable_crypto') ) { $res = $this->_startTLS(); if (is_a($res, 'PEAR_Error')) { return $res; } } return true; } /** * Disconnect from the Sieve server. * * @param boolean $sendLogoutCMD Whether to send LOGOUT command before * disconnecting. * * @return boolean True on success, PEAR_Error otherwise. */ function disconnect($sendLogoutCMD = true) { return $this->_cmdLogout($sendLogoutCMD); } /** * Logs into server. * * @param string $user Login username. * @param string $pass Login password. * @param string $logintype Type of login method to use. * @param string $euser Effective UID (perform on behalf of $euser). * @param boolean $bypassAuth Do not perform authentication. * * @return boolean True on success, PEAR_Error otherwise. */ function login($user, $pass, $logintype = null, $euser = '', $bypassAuth = false) { $this->_data['user'] = $user; $this->_data['pass'] = $pass; $this->_data['logintype'] = $logintype; $this->_data['euser'] = $euser; $this->_bypassAuth = $bypassAuth; if (NET_SIEVE_STATE_AUTHORISATION != $this->_state) { return $this->_pear->raiseError('Not currently in AUTHORISATION state', 1); } if (!$bypassAuth ) { $res = $this->_cmdAuthenticate($user, $pass, $logintype, $euser); if (is_a($res, 'PEAR_Error')) { return $res; } } $this->_state = NET_SIEVE_STATE_TRANSACTION; return true; } /** * Returns an indexed array of scripts currently on the server. * * @param string $active Will be set to the name of the active script * * @return array Indexed array of scriptnames, PEAR_Error on failure */ function listScripts(&$active = null) { if (is_array($scripts = $this->_cmdListScripts())) { if (isset($scripts[1])) { $active = $scripts[1]; } return $scripts[0]; } return $scripts; } /** * Returns the active script. * * @return string The active scriptname. */ function getActive() { if (is_array($scripts = $this->_cmdListScripts())) { return $scripts[1]; } } /** * Sets the active script. * * @param string $scriptname The name of the script to be set as active. * * @return boolean True on success, PEAR_Error on failure. */ function setActive($scriptname) { return $this->_cmdSetActive($scriptname); } /** * Retrieves a script. * * @param string $scriptname The name of the script to be retrieved. * * @return string The script on success, PEAR_Error on failure. */ function getScript($scriptname) { return $this->_cmdGetScript($scriptname); } /** * Adds a script to the server. * * @param string $scriptname Name of the script. * @param string $script The script content. * @param boolean $makeactive Whether to make this the active script. * * @return boolean True on success, PEAR_Error on failure. */ function installScript($scriptname, $script, $makeactive = false) { $res = $this->_cmdPutScript($scriptname, $script); if (is_a($res, 'PEAR_Error')) { return $res; } if ($makeactive) { return $this->_cmdSetActive($scriptname); } return true; } /** * Removes a script from the server. * * @param string $scriptname Name of the script. * * @return boolean True on success, PEAR_Error on failure. */ function removeScript($scriptname) { return $this->_cmdDeleteScript($scriptname); } /** * Checks if the server has space to store the script by the server. * * @param string $scriptname The name of the script to mark as active. * @param integer $size The size of the script. * * @return boolean|PEAR_Error True if there is space, PEAR_Error otherwise. * * @todo Rename to hasSpace() */ function haveSpace($scriptname, $size) { if (NET_SIEVE_STATE_TRANSACTION != $this->_state) { return $this->_pear->raiseError('Not currently in TRANSACTION state', 1); } $res = $this->_doCmd(sprintf('HAVESPACE %s %d', $this->_escape($scriptname), $size)); if (is_a($res, 'PEAR_Error')) { return $res; } return true; } /** * Returns the list of extensions the server supports. * * @return array List of extensions or PEAR_Error on failure. */ function getExtensions() { if (NET_SIEVE_STATE_DISCONNECTED == $this->_state) { return $this->_pear->raiseError('Not currently connected', 7); } return $this->_capability['extensions']; } /** * Returns whether the server supports an extension. * * @param string $extension The extension to check. * * @return boolean Whether the extension is supported or PEAR_Error on * failure. */ function hasExtension($extension) { if (NET_SIEVE_STATE_DISCONNECTED == $this->_state) { return $this->_pear->raiseError('Not currently connected', 7); } $extension = trim($this->_toUpper($extension)); if (is_array($this->_capability['extensions'])) { foreach ($this->_capability['extensions'] as $ext) { if ($ext == $extension) { return true; } } } return false; } /** * Returns the list of authentication methods the server supports. * * @return array List of authentication methods or PEAR_Error on failure. */ function getAuthMechs() { if (NET_SIEVE_STATE_DISCONNECTED == $this->_state) { return $this->_pear->raiseError('Not currently connected', 7); } return $this->_capability['sasl']; } /** * Returns whether the server supports an authentication method. * * @param string $method The method to check. * * @return boolean Whether the method is supported or PEAR_Error on * failure. */ function hasAuthMech($method) { if (NET_SIEVE_STATE_DISCONNECTED == $this->_state) { return $this->_pear->raiseError('Not currently connected', 7); } $method = trim($this->_toUpper($method)); if (is_array($this->_capability['sasl'])) { foreach ($this->_capability['sasl'] as $sasl) { if ($sasl == $method) { return true; } } } return false; } /** * Handles the authentication using any known method. * * @param string $uid The userid to authenticate as. * @param string $pwd The password to authenticate with. * @param string $userMethod The method to use. If empty, the class chooses * the best (strongest) available method. * @param string $euser The effective uid to authenticate as. * * @return void */ function _cmdAuthenticate($uid, $pwd, $userMethod = null, $euser = '') { $method = $this->_getBestAuthMethod($userMethod); if (is_a($method, 'PEAR_Error')) { return $method; } switch ($method) { case 'DIGEST-MD5': return $this->_authDigestMD5($uid, $pwd, $euser); case 'CRAM-MD5': $result = $this->_authCRAMMD5($uid, $pwd, $euser); break; case 'LOGIN': $result = $this->_authLOGIN($uid, $pwd, $euser); break; case 'PLAIN': $result = $this->_authPLAIN($uid, $pwd, $euser); break; case 'EXTERNAL': $result = $this->_authEXTERNAL($uid, $pwd, $euser); break; case 'GSSAPI': $result = $this->_authGSSAPI($pwd); break; case 'XOAUTH2': $result = $this->_authXOAUTH2($uid, $pwd, $euser); break; default : $result = $this->_pear->raiseError( $method . ' is not a supported authentication method' ); break; } $res = $this->_doCmd(); if (is_a($res, 'PEAR_Error')) { return $res; } if ($this->_pear->isError($res = $this->_cmdCapability())) { return $this->_pear->raiseError( 'Failed to connect, server said: ' . $res->getMessage(), 2 ); } return $result; } /** * Authenticates the user using the PLAIN method. * * @param string $user The userid to authenticate as. * @param string $pass The password to authenticate with. * @param string $euser The effective uid to authenticate as. * * @return void */ function _authPLAIN($user, $pass, $euser) { return $this->_sendCmd( sprintf( 'AUTHENTICATE "PLAIN" "%s"', base64_encode($euser . chr(0) . $user . chr(0) . $pass) ) ); } /** * Authenticates the user using the GSSAPI method. * * @note the PHP krb5 extension is required and the service principal and cname * must have been set. * @see setServicePrincipal() * * @return void */ function _authGSSAPI() { if (!extension_loaded('krb5')) { return $this->_pear->raiseError('The krb5 extension is required for GSSAPI authentication', 2); } if (!$this->_gssapiPrincipal) { return $this->_pear->raiseError('No Kerberos service principal set', 2); } if (!$this->_gssapiCN) { return $this->_pear->raiseError('No Kerberos service CName set', 2); } putenv('KRB5CCNAME=' . $this->_gssapiCN); try { $ccache = new KRB5CCache(); $ccache->open($this->_gssapiCN); $gssapicontext = new GSSAPIContext(); $gssapicontext->acquireCredentials($ccache); $token = ''; $success = $gssapicontext->initSecContext($this->_gssapiPrincipal, null, null, null, $token); $token = base64_encode($token); } catch (Exception $e) { return $this->_pear->raiseError('GSSAPI authentication failed: ' . $e->getMessage()); } $this->_sendCmd("AUTHENTICATE \"GSSAPI\" {" . strlen($token) . "+}"); $response = $this->_doCmd($token, true); try { $challenge = base64_decode(substr($response, 1, -1)); $gssapicontext->unwrap($challenge, $challenge); $gssapicontext->wrap($challenge, $challenge, true); } catch (Exception $e) { return $this->_pear->raiseError('GSSAPI authentication failed: ' . $e->getMessage()); } $response = base64_encode($challenge); $this->_sendCmd("{" . strlen($response) . "+}"); return $this->_sendCmd($response); } /** * Authenticates the user using the LOGIN method. * * @param string $user The userid to authenticate as. * @param string $pass The password to authenticate with. * @param string $euser The effective uid to authenticate as. Not used. * * @return void */ function _authLOGIN($user, $pass, $euser) { $result = $this->_sendCmd('AUTHENTICATE "LOGIN"'); if (is_a($result, 'PEAR_Error')) { return $result; } $result = $this->_doCmd('"' . base64_encode($user) . '"', true); if (is_a($result, 'PEAR_Error')) { return $result; } return $this->_doCmd('"' . base64_encode($pass) . '"', true); } /** * Authenticates the user using the CRAM-MD5 method. * * @param string $user The userid to authenticate as. * @param string $pass The password to authenticate with. * @param string $euser The effective uid to authenticate as. Not used. * * @return void */ function _authCRAMMD5($user, $pass, $euser) { $challenge = $this->_doCmd('AUTHENTICATE "CRAM-MD5"', true); if (is_a($challenge, 'PEAR_Error')) { return $challenge; } $auth_sasl = new Auth_SASL; $cram = $auth_sasl->factory('crammd5'); $challenge = base64_decode(trim($challenge)); $response = $cram->getResponse($user, $pass, $challenge); if (is_a($response, 'PEAR_Error')) { return $response; } return $this->_sendStringResponse(base64_encode($response)); } /** * Authenticates the user using the DIGEST-MD5 method. * * @param string $user The userid to authenticate as. * @param string $pass The password to authenticate with. * @param string $euser The effective uid to authenticate as. * * @return void */ function _authDigestMD5($user, $pass, $euser) { $challenge = $this->_doCmd('AUTHENTICATE "DIGEST-MD5"', true); if (is_a($challenge, 'PEAR_Error')) { return $challenge; } $auth_sasl = new Auth_SASL; $digest = $auth_sasl->factory('digestmd5'); $challenge = base64_decode(trim($challenge)); // @todo Really 'localhost'? $response = $digest->getResponse($user, $pass, $challenge, 'localhost', 'sieve', $euser); if (is_a($response, 'PEAR_Error')) { return $response; } $result = $this->_sendStringResponse(base64_encode($response)); if (is_a($result, 'PEAR_Error')) { return $result; } $result = $this->_doCmd('', true); if (is_a($result, 'PEAR_Error')) { return $result; } if ($this->_toUpper(substr($result, 0, 2)) == 'OK') { return; } /* We don't use the protocol's third step because SIEVE doesn't allow * subsequent authentication, so we just silently ignore it. */ $result = $this->_sendStringResponse(''); if (is_a($result, 'PEAR_Error')) { return $result; } return $this->_doCmd(); } /** * Authenticates the user using the EXTERNAL method. * * @param string $user The userid to authenticate as. * @param string $pass The password to authenticate with. * @param string $euser The effective uid to authenticate as. * * @return void * * @since 1.1.7 */ function _authEXTERNAL($user, $pass, $euser) { $cmd = sprintf( 'AUTHENTICATE "EXTERNAL" "%s"', base64_encode(strlen($euser) ? $euser : $user) ); return $this->_sendCmd($cmd); } /** * Authenticates the user using the XOAUTH2 method. * * @param string $user The userid to authenticate as. * @param string $token The token to authenticate with. * @param string $euser The effective uid to authenticate as. * * @return void */ function _authXOAUTH2($user, $token, $euser) { // default to $user if $euser is not set if (! $euser) { $euser = $user; } $auth = base64_encode("user=$euser\001auth=$token\001\001"); return $this->_sendCmd("AUTHENTICATE \"XOAUTH2\" \"$auth\""); } /** * Removes a script from the server. * * @param string $scriptname Name of the script to delete. * * @return boolean True on success, PEAR_Error otherwise. */ function _cmdDeleteScript($scriptname) { if (NET_SIEVE_STATE_TRANSACTION != $this->_state) { return $this->_pear->raiseError('Not currently in AUTHORISATION state', 1); } $res = $this->_doCmd(sprintf('DELETESCRIPT %s', $this->_escape($scriptname))); if (is_a($res, 'PEAR_Error')) { return $res; } return true; } /** * Retrieves the contents of the named script. * * @param string $scriptname Name of the script to retrieve. * * @return string The script if successful, PEAR_Error otherwise. */ function _cmdGetScript($scriptname) { if (NET_SIEVE_STATE_TRANSACTION != $this->_state) { return $this->_pear->raiseError('Not currently in AUTHORISATION state', 1); } $res = $this->_doCmd(sprintf('GETSCRIPT %s', $this->_escape($scriptname))); if (is_a($res, 'PEAR_Error')) { return $res; } return preg_replace('/^{[0-9]+}\r\n/', '', $res); } /** * Sets the active script, i.e. the one that gets run on new mail by the * server. * * @param string $scriptname The name of the script to mark as active. * * @return boolean True on success, PEAR_Error otherwise. */ function _cmdSetActive($scriptname) { if (NET_SIEVE_STATE_TRANSACTION != $this->_state) { return $this->_pear->raiseError('Not currently in AUTHORISATION state', 1); } $res = $this->_doCmd(sprintf('SETACTIVE %s', $this->_escape($scriptname))); if (is_a($res, 'PEAR_Error')) { return $res; } return true; } /** * Returns the list of scripts on the server. * * @return array An array with the list of scripts in the first element * and the active script in the second element on success, * PEAR_Error otherwise. */ function _cmdListScripts() { if (NET_SIEVE_STATE_TRANSACTION != $this->_state) { return $this->_pear->raiseError('Not currently in AUTHORISATION state', 1); } $res = $this->_doCmd('LISTSCRIPTS'); if (is_a($res, 'PEAR_Error')) { return $res; } $scripts = array(); $activescript = null; $res = explode("\r\n", $res); foreach ($res as $value) { if (preg_match('/^"(.*)"( ACTIVE)?$/i', $value, $matches)) { $script_name = stripslashes($matches[1]); $scripts[] = $script_name; if (!empty($matches[2])) { $activescript = $script_name; } } } return array($scripts, $activescript); } /** * Adds a script to the server. * * @param string $scriptname Name of the new script. * @param string $scriptdata The new script. * * @return boolean True on success, PEAR_Error otherwise. */ function _cmdPutScript($scriptname, $scriptdata) { if (NET_SIEVE_STATE_TRANSACTION != $this->_state) { return $this->_pear->raiseError('Not currently in AUTHORISATION state', 1); } $stringLength = $this->_getLineLength($scriptdata); $command = sprintf( "PUTSCRIPT %s {%d+}\r\n%s", $this->_escape($scriptname), $stringLength, $scriptdata ); $res = $this->_doCmd($command); if (is_a($res, 'PEAR_Error')) { return $res; } return true; } /** * Logs out of the server and terminates the connection. * * @param boolean $sendLogoutCMD Whether to send LOGOUT command before * disconnecting. * * @return boolean True on success, PEAR_Error otherwise. */ function _cmdLogout($sendLogoutCMD = true) { if (NET_SIEVE_STATE_DISCONNECTED == $this->_state) { return $this->_pear->raiseError('Not currently connected', 1); } if ($sendLogoutCMD) { $res = $this->_doCmd('LOGOUT'); if (is_a($res, 'PEAR_Error')) { return $res; } } $this->_sock->disconnect(); $this->_state = NET_SIEVE_STATE_DISCONNECTED; return true; } /** * Sends the CAPABILITY command * * @return boolean True on success, PEAR_Error otherwise. */ function _cmdCapability() { if (NET_SIEVE_STATE_DISCONNECTED == $this->_state) { return $this->_pear->raiseError('Not currently connected', 1); } $res = $this->_doCmd('CAPABILITY'); if (is_a($res, 'PEAR_Error')) { return $res; } $this->_parseCapability($res); return true; } /** * Parses the response from the CAPABILITY command and stores the result * in $_capability. * * @param string $data The response from the capability command. * * @return void */ function _parseCapability($data) { // Clear the cached capabilities. $this->_capability = array('sasl' => array(), 'extensions' => array()); $data = preg_split('/\r?\n/', $this->_toUpper($data), -1, PREG_SPLIT_NO_EMPTY); for ($i = 0; $i < count($data); $i++) { if (!preg_match('/^"([A-Z]+)"( "(.*)")?$/', $data[$i], $matches)) { continue; } switch ($matches[1]) { case 'IMPLEMENTATION': $this->_capability['implementation'] = $matches[3]; break; case 'SASL': if (!empty($matches[3])) { $this->_capability['sasl'] = preg_split('/\s+/', $matches[3]); } break; case 'SIEVE': if (!empty($matches[3])) { $this->_capability['extensions'] = preg_split('/\s+/', $matches[3]); } break; case 'STARTTLS': $this->_capability['starttls'] = true; break; } } } /** * Sends a command to the server * * @param string $cmd The command to send. * * @return void */ function _sendCmd($cmd) { $status = $this->_sock->getStatus(); if (is_a($status, 'PEAR_Error') || $status['eof']) { return $this->_pear->raiseError('Failed to write to socket: connection lost'); } $error = $this->_sock->write($cmd . "\r\n"); if (is_a($error, 'PEAR_Error')) { return $this->_pear->raiseError( 'Failed to write to socket: ' . $error->getMessage() ); } $this->_debug("C: $cmd"); } /** * Sends a string response to the server. * * @param string $str The string to send. * * @return void */ function _sendStringResponse($str) { return $this->_sendCmd('{' . $this->_getLineLength($str) . "+}\r\n" . $str); } /** * Receives a single line from the server. * * @return string The server response line. */ function _recvLn() { $lastline = $this->_sock->gets(8192); if (is_a($lastline, 'PEAR_Error')) { return $this->_pear->raiseError( 'Failed to read from socket: ' . $lastline->getMessage() ); } $lastline = rtrim($lastline); $this->_debug("S: $lastline"); if ($lastline === '') { return $this->_pear->raiseError('Failed to read from socket'); } return $lastline; } /** * Receives a number of bytes from the server. * * @param integer $length Number of bytes to read. * * @return string The server response. */ function _recvBytes($length) { $response = ''; $response_length = 0; while ($response_length < $length) { $response .= $this->_sock->read($length - $response_length); $response_length = $this->_getLineLength($response); } $this->_debug('S: ' . rtrim($response)); return $response; } /** * Send a command and retrieves a response from the server. * * @param string $cmd The command to send. * @param boolean $auth Whether this is an authentication command. * * @return string|PEAR_Error Reponse string if an OK response, PEAR_Error * if a NO response. */ function _doCmd($cmd = '', $auth = false) { $referralCount = 0; while ($referralCount < $this->_maxReferralCount) { if (strlen($cmd)) { $error = $this->_sendCmd($cmd); if (is_a($error, 'PEAR_Error')) { return $error; } } $response = ''; while (true) { $line = $this->_recvLn(); if (is_a($line, 'PEAR_Error')) { return $line; } if (preg_match('/^(OK|NO)/i', $line, $tag)) { // Check for string literal message. if (preg_match('/{([0-9]+)}$/', $line, $matches)) { $line = substr($line, 0, -(strlen($matches[1]) + 2)) . str_replace( "\r\n", ' ', $this->_recvBytes($matches[1] + 2) ); } if ('OK' == $this->_toUpper($tag[1])) { $response .= $line; return rtrim($response); } return $this->_pear->raiseError(trim($response . substr($line, 2)), 3); } if (preg_match('/^BYE/i', $line)) { $error = $this->disconnect(false); if (is_a($error, 'PEAR_Error')) { return $this->_pear->raiseError( 'Cannot handle BYE, the error was: ' . $error->getMessage(), 4 ); } // Check for referral, then follow it. Otherwise, carp an // error. if (preg_match('/^bye \(referral "(sieve:\/\/)?([^"]+)/i', $line, $matches)) { // Replace the old host with the referral host // preserving any protocol prefix. $this->_data['host'] = preg_replace( '/\w+(?!(\w|\:\/\/)).*/', $matches[2], $this->_data['host'] ); $error = $this->_handleConnectAndLogin(); if (is_a($error, 'PEAR_Error')) { return $this->_pear->raiseError( 'Cannot follow referral to ' . $this->_data['host'] . ', the error was: ' . $error->getMessage(), 5 ); } break; } return $this->_pear->raiseError(trim($response . $line), 6); } if (preg_match('/^{([0-9]+)}/', $line, $matches)) { // Matches literal string responses. $line = $this->_recvBytes($matches[1] + 2); if (!$auth) { // Receive the pending OK only if we aren't // authenticating since string responses during // authentication don't need an OK. $this->_recvLn(); } return $line; } if ($auth) { // String responses during authentication don't need an // OK. $response .= $line; return rtrim($response); } $response .= $line . "\r\n"; $referralCount++; } } return $this->_pear->raiseError('Max referral count (' . $referralCount . ') reached. Cyrus murder loop error?', 7); } /** * Returns the name of the best authentication method that the server * has advertised. * * @param string $userMethod Only consider this method as available. * * @return string The name of the best supported authentication method or * a PEAR_Error object on failure. */ function _getBestAuthMethod($userMethod = null) { if (!isset($this->_capability['sasl'])) { return $this->_pear->raiseError('This server doesn\'t support any authentication methods. SASL problem?'); } if (!$this->_capability['sasl']) { return $this->_pear->raiseError('This server doesn\'t support any authentication methods.'); } if ($userMethod) { if (in_array($userMethod, $this->_capability['sasl'])) { return $userMethod; } $msg = 'No supported authentication method found. The server supports these methods: %s, but we want to use: %s'; return $this->_pear->raiseError( sprintf($msg, implode(', ', $this->_capability['sasl']), $userMethod) ); } foreach ($this->supportedAuthMethods as $method) { if (in_array($method, $this->_capability['sasl'])) { return $method; } } $msg = 'No supported authentication method found. The server supports these methods: %s, but we only support: %s'; return $this->_pear->raiseError( sprintf($msg, implode(', ', $this->_capability['sasl']), implode(', ', $this->supportedAuthMethods)) ); } /** * Starts a TLS connection. * * @return boolean True on success, PEAR_Error on failure. */ function _startTLS() { $res = $this->_doCmd('STARTTLS'); if (is_a($res, 'PEAR_Error')) { return $res; } if (isset($this->_options['ssl']['crypto_method'])) { $crypto_method = $this->_options['ssl']['crypto_method']; } else { // There is no flag to enable all TLS methods. Net_SMTP // handles enabling TLS similarly. $crypto_method = STREAM_CRYPTO_METHOD_TLS_CLIENT | @STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT | @STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT; } if (!stream_socket_enable_crypto($this->_sock->fp, true, $crypto_method)) { return $this->_pear->raiseError('Failed to establish TLS connection', 2); } $this->_debug('STARTTLS negotiation successful'); // The server should be sending a CAPABILITY response after // negotiating TLS. Read it, and ignore if it doesn't. // Unfortunately old Cyrus versions are broken and don't send a // CAPABILITY response, thus we would wait here forever. Parse the // Cyrus version and work around this broken behavior. if (!preg_match('/^CYRUS TIMSIEVED V([0-9.]+)/', $this->_capability['implementation'], $matches) || version_compare($matches[1], '2.3.10', '>=') ) { $res = $this->_doCmd(); } // Reset capabilities (use unattended capabilities) $this->_parseCapability(is_string($res) ? $res : ''); // Query the server capabilities again now that we are under encryption. if (empty($this->_capability['implementation'])) { $res = $this->_cmdCapability(); if (is_a($res, 'PEAR_Error')) { return $this->_pear->raiseError( 'Failed to connect, server said: ' . $res->getMessage(), 2 ); } } return true; } /** * Returns the length of a string. * * @param string $string A string. * * @return integer The length of the string. */ function _getLineLength($string) { if (extension_loaded('mbstring')) { return mb_strlen($string, '8bit'); } else { return strlen($string); } } /** * Locale independant strtoupper() implementation. * * @param string $string The string to convert to lowercase. * * @return string The lowercased string, based on ASCII encoding. */ function _toUpper($string) { $language = setlocale(LC_CTYPE, 0); setlocale(LC_CTYPE, 'C'); $string = strtoupper($string); setlocale(LC_CTYPE, $language); return $string; } /** * Converts strings into RFC's quoted-string or literal-c2s form. * * @param string $string The string to convert. * * @return string Result string. */ function _escape($string) { // Some implementations don't allow UTF-8 characters in quoted-string, // use literal-c2s. if (preg_match('/[^\x01-\x09\x0B-\x0C\x0E-\x7F]/', $string)) { return sprintf("{%d+}\r\n%s", $this->_getLineLength($string), $string); } return '"' . addcslashes($string, '\\"') . '"'; } /** * Write debug text to the current debug output handler. * * @param string $message Debug message text. * * @return void */ function _debug($message) { if ($this->_debug) { if ($this->_debug_handler) { call_user_func_array($this->_debug_handler, array(&$this, $message)); } else { echo "$message\n"; } } } } PKu]D:: pearcmd.phpnu[ * @author Tomas V.V.Cox * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR */ @ob_end_clean(); if (!defined('PEAR_RUNTYPE')) { // this is defined in peclcmd.php as 'pecl' define('PEAR_RUNTYPE', 'pear'); } define('PEAR_IGNORE_BACKTRACE', 1); /** * @nodep Gtk */ //the space is needed for windows include paths with trailing backslash // http://pear.php.net/bugs/bug.php?id=19482 if ('/opt/alt/php56/usr/share/pear ' != '@'.'include_path'.'@ ') { ini_set('include_path', trim('/opt/alt/php56/usr/share/pear '). PATH_SEPARATOR . get_include_path()); $raw = false; } else { // this is a raw, uninstalled pear, either a cvs checkout, or php distro ini_set('include_path', dirname(__DIR__) . PATH_SEPARATOR . get_include_path()); $raw = true; } @ini_set('allow_url_fopen', true); @set_time_limit(0); ob_implicit_flush(true); @ini_set('track_errors', true); @ini_set('html_errors', false); $_PEAR_PHPDIR = '#$%^&*'; set_error_handler('error_handler'); $pear_package_version = "1.10.16"; require_once 'PEAR.php'; require_once 'PEAR/Frontend.php'; require_once 'PEAR/Config.php'; require_once 'PEAR/Command.php'; require_once 'Console/Getopt.php'; PEAR_Command::setFrontendType('CLI'); $all_commands = PEAR_Command::getCommands(); $argv = Console_Getopt::readPHPArgv(); // fix CGI sapi oddity - the -- in pear.bat/pear is not removed if (php_sapi_name() != 'cli' && isset($argv[1]) && $argv[1] == '--') { unset($argv[1]); $argv = array_values($argv); } $progname = PEAR_RUNTYPE; array_shift($argv); $options = Console_Getopt::getopt2($argv, "c:C:d:D:Gh?sSqu:vV"); if (PEAR::isError($options)) { usage($options); } $opts = $options[0]; $fetype = 'CLI'; if ($progname == 'gpear' || $progname == 'pear-gtk') { $fetype = 'Gtk2'; } else { foreach ($opts as $opt) { if ($opt[0] == 'G') { $fetype = 'Gtk2'; } } } $pear_user_config = ''; $pear_system_config = ''; $store_user_config = false; $store_system_config = false; $verbose = 1; foreach ($opts as $opt) { switch ($opt[0]) { case 'c': $pear_user_config = $opt[1]; break; case 'C': $pear_system_config = $opt[1]; break; } } PEAR_Command::setFrontendType($fetype); $ui = &PEAR_Command::getFrontendObject(); $config = &PEAR_Config::singleton($pear_user_config, $pear_system_config); if (PEAR::isError($config)) { $_file = ''; if ($pear_user_config !== false) { $_file .= $pear_user_config; } if ($pear_system_config !== false) { $_file .= '/' . $pear_system_config; } if ($_file == '/') { $_file = 'The default config file'; } $config->getMessage(); $ui->outputData("ERROR: $_file is not a valid config file or is corrupted."); // We stop, we have no idea where we are :) exit(1); } // this is used in the error handler to retrieve a relative path $_PEAR_PHPDIR = $config->get('php_dir'); $ui->setConfig($config); PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array($ui, "displayFatalError")); $verbose = $config->get("verbose"); $cmdopts = array(); if ($raw) { if (!$config->isDefinedLayer('user') && !$config->isDefinedLayer('system')) { $found = false; foreach ($opts as $opt) { if ($opt[0] == 'd' || $opt[0] == 'D') { // the user knows what they are doing, and are setting config values $found = true; } } if (!$found) { // no prior runs, try to install PEAR $parent = dirname(__FILE__); if (strpos($parent, 'scripts')) { $grandparent = dirname($parent); $packagexml = $grandparent . DIRECTORY_SEPARATOR . 'package2.xml'; $pearbase = $grandparent; } else { $packagexml = $parent . DIRECTORY_SEPARATOR . 'package2.xml'; $pearbase = $parent; } if (file_exists($packagexml)) { $options[1] = array( 'install', $packagexml ); $config->set('php_dir', $pearbase . DIRECTORY_SEPARATOR . 'php'); $config->set('data_dir', $pearbase . DIRECTORY_SEPARATOR . 'data'); $config->set('doc_dir', $pearbase . DIRECTORY_SEPARATOR . 'docs'); $config->set('test_dir', $pearbase . DIRECTORY_SEPARATOR . 'tests'); $config->set( 'ext_dir', $pearbase . DIRECTORY_SEPARATOR . 'extensions' ); $config->set('bin_dir', $pearbase); $config->mergeConfigFile($pearbase . 'pear.ini', false); $config->store(); $config->set('auto_discover', 1); } } } } foreach ($opts as $opt) { $param = !empty($opt[1]) ? $opt[1] : true; switch ($opt[0]) { case 'd': if ($param === true) { die( 'Invalid usage of "-d" option, expected -d config_value=value, ' . 'received "-d"' . "\n" ); } $possible = explode('=', $param); if (count($possible) != 2) { die( 'Invalid usage of "-d" option, expected ' . '-d config_value=value, received "' . $param . '"' . "\n" ); } list($key, $value) = explode('=', $param); $config->set($key, $value, 'user'); break; case 'D': if ($param === true) { die( 'Invalid usage of "-d" option, expected ' . '-d config_value=value, received "-d"' . "\n" ); } $possible = explode('=', $param); if (count($possible) != 2) { die( 'Invalid usage of "-d" option, expected ' . '-d config_value=value, received "' . $param . '"' . "\n" ); } list($key, $value) = explode('=', $param); $config->set($key, $value, 'system'); break; case 's': $store_user_config = true; break; case 'S': $store_system_config = true; break; case 'u': $config->remove($param, 'user'); break; case 'v': $config->set('verbose', $config->get('verbose') + 1); break; case 'q': $config->set('verbose', $config->get('verbose') - 1); break; case 'V': usage(null, 'version'); case 'c': case 'C': break; default: // all non pear params goes to the command $cmdopts[$opt[0]] = $param; break; } } if ($store_system_config) { $config->store('system'); } if ($store_user_config) { $config->store('user'); } $command = (isset($options[1][0])) ? $options[1][0] : null; if (empty($command) && ($store_user_config || $store_system_config)) { exit; } if ($fetype == 'Gtk2') { if (!$config->validConfiguration()) { PEAR::raiseError( "CRITICAL ERROR: no existing valid configuration files found in " . "files '$pear_user_config' or '$pear_system_config', " . "please copy an existing configuration file to one of these " . "locations, or use the -c and -s options to create one" ); } Gtk::main(); } else { do { if ($command == 'help') { usage(null, isset($options[1][1]) ? $options[1][1] : null); } if (!$config->validConfiguration()) { PEAR::raiseError( "CRITICAL ERROR: no existing valid configuration files found " . "in files '$pear_user_config' or '$pear_system_config', " . "please copy an existing configuration file to one of " . "these locations, or use the -c and -s options to create one" ); } PEAR::pushErrorHandling(PEAR_ERROR_RETURN); $cmd = PEAR_Command::factory($command, $config); PEAR::popErrorHandling(); if (PEAR::isError($cmd)) { usage(null, isset($options[1][0]) ? $options[1][0] : null); } $short_args = $long_args = null; PEAR_Command::getGetoptArgs($command, $short_args, $long_args); array_shift($options[1]); $tmp = Console_Getopt::getopt2($options[1], $short_args, $long_args); if (PEAR::isError($tmp)) { break; } list($tmpopt, $params) = $tmp; $opts = array(); foreach ($tmpopt as $foo => $tmp2) { list($opt, $value) = $tmp2; if ($value === null) { $value = true; // options without args } if (strlen($opt) == 1) { $cmdoptions = $cmd->getOptions($command); foreach ($cmdoptions as $o => $d) { if (isset($d['shortopt']) && $d['shortopt'] == $opt) { $opts[$o] = $value; } } } else { if (substr($opt, 0, 2) == '--') { $opts[substr($opt, 2)] = $value; } } } $ok = $cmd->run($command, $opts, $params); if ($ok === false) { PEAR::raiseError("unknown command `$command'"); } if (PEAR::isError($ok)) { PEAR::setErrorHandling( PEAR_ERROR_CALLBACK, array($ui, "displayFatalError") ); PEAR::raiseError($ok); } } while (false); } // {{{ usage() /** * Display usage information * * @param mixed $error Optional error message * @param mixed $helpsubject Optional subject/command to display help for * * @return void */ function usage($error = null, $helpsubject = null) { global $progname, $all_commands; $stdout = fopen('php://stdout', 'w'); if (PEAR::isError($error)) { fputs($stdout, $error->getMessage() . "\n"); } elseif ($error !== null) { fputs($stdout, "$error\n"); } if ($helpsubject != null) { $put = cmdHelp($helpsubject); } else { $put = "Commands:\n"; $maxlen = max(array_map("strlen", $all_commands)); $formatstr = "%-{$maxlen}s %s\n"; ksort($all_commands); foreach ($all_commands as $cmd => $class) { $put .= sprintf($formatstr, $cmd, PEAR_Command::getDescription($cmd)); } $put .= "Usage: $progname [options] command [command-options] \n". "Type \"$progname help options\" to list all options.\n". "Type \"$progname help shortcuts\" to list all command shortcuts.\n". "Type \"$progname help version\" or ". "\"$progname version\" to list version information.\n". "Type \"$progname help \" to get the help ". "for the specified command."; } fputs($stdout, "$put\n"); fclose($stdout); if ($error === null) { exit(0); } exit(1); } /** * Return help string for specified command * * @param string $command Command to return help for * * @return void */ function cmdHelp($command) { global $progname, $all_commands, $config; if ($command == "options") { return "Options:\n". " -v increase verbosity level (default 1)\n". " -q be quiet, decrease verbosity level\n". " -c file find user configuration in `file'\n". " -C file find system configuration in `file'\n". " -d foo=bar set user config variable `foo' to `bar'\n". " -D foo=bar set system config variable `foo' to `bar'\n". " -G start in graphical (Gtk) mode\n". " -s store user configuration\n". " -S store system configuration\n". " -u foo unset `foo' in the user configuration\n". " -h, -? display help/usage (this message)\n". " -V version information\n"; } elseif ($command == "shortcuts") { $sc = PEAR_Command::getShortcuts(); $ret = "Shortcuts:\n"; foreach ($sc as $s => $c) { $ret .= sprintf(" %-8s %s\n", $s, $c); } return $ret; } elseif ($command == "version") { return "PEAR Version: ".$GLOBALS['pear_package_version']. "\nPHP Version: ".phpversion(). "\nZend Engine Version: ".zend_version(). "\nRunning on: ".php_uname(); } elseif ($help = PEAR_Command::getHelp($command)) { if (is_string($help)) { return "$progname $command [options] $help\n"; } if ($help[1] === null) { return "$progname $command $help[0]"; } return "$progname $command [options] $help[0]\n$help[1]"; } return "Command '$command' is not valid, try '$progname help'"; } // }}} /** * error_handler * * @param mixed $errno Error number * @param mixed $errmsg Message * @param mixed $file Filename * @param mixed $line Line number * * @access public * @return boolean */ function error_handler($errno, $errmsg, $file, $line) { if ((!defined('PHP_VERSION_ID') || PHP_VERSION_ID < 80400) && ($errno & E_STRICT)) { return; // E_STRICT } if ($errno & E_DEPRECATED) { return; // E_DEPRECATED } if (!(error_reporting() & $errno) && isset($GLOBALS['config']) && $GLOBALS['config']->get('verbose') < 4 ) { return false; // @silenced error, show all if debug is high enough } $errortype = array ( E_DEPRECATED => 'Deprecated Warning', E_ERROR => "Error", E_WARNING => "Warning", E_PARSE => "Parsing Error", E_NOTICE => "Notice", E_CORE_ERROR => "Core Error", E_CORE_WARNING => "Core Warning", E_COMPILE_ERROR => "Compile Error", E_COMPILE_WARNING => "Compile Warning", E_USER_ERROR => "User Error", E_USER_WARNING => "User Warning", E_USER_NOTICE => "User Notice" ); if (!defined('PHP_VERSION_ID') || PHP_VERSION_ID < 80400) { $errortype[E_STRICT] = 'Strict Warning'; } $prefix = $errortype[$errno]; global $_PEAR_PHPDIR; if (stristr($file, $_PEAR_PHPDIR)) { $file = substr($file, strlen($_PEAR_PHPDIR) + 1); } else { $file = basename($file); } print "\n$prefix: $errmsg in $file on line $line\n"; return false; } /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * indent-tabs-mode: nil * mode: php * End: */ // vim600:syn=php PKu]ioKXML/RPC/Dump.phpnu[ * @license http://www.php.net/license/3_01.txt PHP License * @version SVN: $Id: Dump.php 300962 2010-07-03 02:24:24Z danielc $ * @link http://pear.php.net/package/XML_RPC */ /** * Pull in the XML_RPC class */ require_once 'XML/RPC.php'; /** * Generates the dump of the XML_RPC_Value and echoes it * * @param object $value the XML_RPC_Value object to dump * * @return void */ function XML_RPC_Dump($value) { $dumper = new XML_RPC_Dump(); echo $dumper->generateDump($value); } /** * Class which generates a dump of a XML_RPC_Value object * * @category Web Services * @package XML_RPC * @author Christian Weiske * @license http://www.php.net/license/3_01.txt PHP License * @version Release: @package_version@ * @link http://pear.php.net/package/XML_RPC */ class XML_RPC_Dump { /** * The indentation array cache * @var array */ var $arIndent = array(); /** * The spaces used for indenting the XML * @var string */ var $strBaseIndent = ' '; /** * Returns the dump in XML format without printing it out * * @param object $value the XML_RPC_Value object to dump * @param int $nLevel the level of indentation * * @return string the dump */ function generateDump($value, $nLevel = 0) { if (!is_object($value) || strtolower(get_class($value)) != 'xml_rpc_value') { require_once 'PEAR.php'; PEAR::raiseError('Tried to dump non-XML_RPC_Value variable' . "\r\n", 0, PEAR_ERROR_PRINT); if (is_object($value)) { $strType = get_class($value); } else { $strType = gettype($value); } return $this->getIndent($nLevel) . 'NOT A XML_RPC_Value: ' . $strType . "\r\n"; } switch ($value->kindOf()) { case 'struct': $ret = $this->genStruct($value, $nLevel); break; case 'array': $ret = $this->genArray($value, $nLevel); break; case 'scalar': $ret = $this->genScalar($value->scalarval(), $nLevel); break; default: require_once 'PEAR.php'; PEAR::raiseError('Illegal type "' . $value->kindOf() . '" in XML_RPC_Value' . "\r\n", 0, PEAR_ERROR_PRINT); } return $ret; } /** * Returns the scalar value dump * * @param object $value the scalar XML_RPC_Value object to dump * @param int $nLevel the level of indentation * * @return string Dumped version of the scalar value */ function genScalar($value, $nLevel) { if (gettype($value) == 'object') { $strClass = ' ' . get_class($value); } else { $strClass = ''; } return $this->getIndent($nLevel) . gettype($value) . $strClass . ' ' . $value . "\r\n"; } /** * Returns the dump of a struct * * @param object $value the struct XML_RPC_Value object to dump * @param int $nLevel the level of indentation * * @return string Dumped version of the scalar value */ function genStruct($value, $nLevel) { $value->structreset(); $strOutput = $this->getIndent($nLevel) . 'struct' . "\r\n"; while (list($key, $keyval) = $value->structeach()) { $strOutput .= $this->getIndent($nLevel + 1) . $key . "\r\n"; $strOutput .= $this->generateDump($keyval, $nLevel + 2); } return $strOutput; } /** * Returns the dump of an array * * @param object $value the array XML_RPC_Value object to dump * @param int $nLevel the level of indentation * * @return string Dumped version of the scalar value */ function genArray($value, $nLevel) { $nSize = $value->arraysize(); $strOutput = $this->getIndent($nLevel) . 'array' . "\r\n"; for($nA = 0; $nA < $nSize; $nA++) { $strOutput .= $this->getIndent($nLevel + 1) . $nA . "\r\n"; $strOutput .= $this->generateDump($value->arraymem($nA), $nLevel + 2); } return $strOutput; } /** * Returns the indent for a specific level and caches it for faster use * * @param int $nLevel the level * * @return string the indented string */ function getIndent($nLevel) { if (!isset($this->arIndent[$nLevel])) { $this->arIndent[$nLevel] = str_repeat($this->strBaseIndent, $nLevel); } return $this->arIndent[$nLevel]; } } /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * c-hanging-comment-ender-p: nil * End: */ ?> PKu]GJWWXML/RPC/Server.phpnu[ * @author Stig Bakken * @author Martin Jansen * @author Daniel Convissor * @copyright 1999-2001 Edd Dumbill, 2001-2010 The PHP Group * @license http://www.php.net/license/3_01.txt PHP License * @version SVN: $Id: Server.php 315558 2011-08-26 14:42:51Z danielc $ * @link http://pear.php.net/package/XML_RPC */ /** * Pull in the XML_RPC class */ require_once 'XML/RPC.php'; /** * signature for system.listMethods: return = array, * parameters = a string or nothing * @global array $GLOBALS['XML_RPC_Server_listMethods_sig'] */ $GLOBALS['XML_RPC_Server_listMethods_sig'] = array( array($GLOBALS['XML_RPC_Array'], $GLOBALS['XML_RPC_String'] ), array($GLOBALS['XML_RPC_Array']) ); /** * docstring for system.listMethods * @global string $GLOBALS['XML_RPC_Server_listMethods_doc'] */ $GLOBALS['XML_RPC_Server_listMethods_doc'] = 'This method lists all the' . ' methods that the XML-RPC server knows how to dispatch'; /** * signature for system.methodSignature: return = array, * parameters = string * @global array $GLOBALS['XML_RPC_Server_methodSignature_sig'] */ $GLOBALS['XML_RPC_Server_methodSignature_sig'] = array( array($GLOBALS['XML_RPC_Array'], $GLOBALS['XML_RPC_String'] ) ); /** * docstring for system.methodSignature * @global string $GLOBALS['XML_RPC_Server_methodSignature_doc'] */ $GLOBALS['XML_RPC_Server_methodSignature_doc'] = 'Returns an array of known' . ' signatures (an array of arrays) for the method name passed. If' . ' no signatures are known, returns a none-array (test for type !=' . ' array to detect missing signature)'; /** * signature for system.methodHelp: return = string, * parameters = string * @global array $GLOBALS['XML_RPC_Server_methodHelp_sig'] */ $GLOBALS['XML_RPC_Server_methodHelp_sig'] = array( array($GLOBALS['XML_RPC_String'], $GLOBALS['XML_RPC_String'] ) ); /** * docstring for methodHelp * @global string $GLOBALS['XML_RPC_Server_methodHelp_doc'] */ $GLOBALS['XML_RPC_Server_methodHelp_doc'] = 'Returns help text if defined' . ' for the method passed, otherwise returns an empty string'; /** * dispatch map for the automatically declared XML-RPC methods. * @global array $GLOBALS['XML_RPC_Server_dmap'] */ $GLOBALS['XML_RPC_Server_dmap'] = array( 'system.listMethods' => array( 'function' => 'XML_RPC_Server_listMethods', 'signature' => $GLOBALS['XML_RPC_Server_listMethods_sig'], 'docstring' => $GLOBALS['XML_RPC_Server_listMethods_doc'] ), 'system.methodHelp' => array( 'function' => 'XML_RPC_Server_methodHelp', 'signature' => $GLOBALS['XML_RPC_Server_methodHelp_sig'], 'docstring' => $GLOBALS['XML_RPC_Server_methodHelp_doc'] ), 'system.methodSignature' => array( 'function' => 'XML_RPC_Server_methodSignature', 'signature' => $GLOBALS['XML_RPC_Server_methodSignature_sig'], 'docstring' => $GLOBALS['XML_RPC_Server_methodSignature_doc'] ) ); /** * @global string $GLOBALS['XML_RPC_Server_debuginfo'] */ $GLOBALS['XML_RPC_Server_debuginfo'] = ''; /** * Lists all the methods that the XML-RPC server knows how to dispatch * * @return object a new XML_RPC_Response object */ function XML_RPC_Server_listMethods($server, $m) { global $XML_RPC_err, $XML_RPC_str, $XML_RPC_Server_dmap; $v = new XML_RPC_Value(); $outAr = array(); foreach ($server->dmap as $key => $val) { $outAr[] = new XML_RPC_Value($key, 'string'); } foreach ($XML_RPC_Server_dmap as $key => $val) { $outAr[] = new XML_RPC_Value($key, 'string'); } $v->addArray($outAr); return new XML_RPC_Response($v); } /** * Returns an array of known signatures (an array of arrays) * for the given method * * If no signatures are known, returns a none-array * (test for type != array to detect missing signature) * * @return object a new XML_RPC_Response object */ function XML_RPC_Server_methodSignature($server, $m) { global $XML_RPC_err, $XML_RPC_str, $XML_RPC_Server_dmap; $methName = $m->getParam(0); $methName = $methName->scalarval(); if (strpos($methName, 'system.') === 0) { $dmap = $XML_RPC_Server_dmap; $sysCall = 1; } else { $dmap = $server->dmap; $sysCall = 0; } // print "\n"; if (isset($dmap[$methName])) { if ($dmap[$methName]['signature']) { $sigs = array(); $thesigs = $dmap[$methName]['signature']; for ($i = 0; $i < sizeof($thesigs); $i++) { $cursig = array(); $inSig = $thesigs[$i]; for ($j = 0; $j < sizeof($inSig); $j++) { $cursig[] = new XML_RPC_Value($inSig[$j], 'string'); } $sigs[] = new XML_RPC_Value($cursig, 'array'); } $r = new XML_RPC_Response(new XML_RPC_Value($sigs, 'array')); } else { $r = new XML_RPC_Response(new XML_RPC_Value('undef', 'string')); } } else { $r = new XML_RPC_Response(0, $XML_RPC_err['introspect_unknown'], $XML_RPC_str['introspect_unknown']); } return $r; } /** * Returns help text if defined for the method passed, otherwise returns * an empty string * * @return object a new XML_RPC_Response object */ function XML_RPC_Server_methodHelp($server, $m) { global $XML_RPC_err, $XML_RPC_str, $XML_RPC_Server_dmap; $methName = $m->getParam(0); $methName = $methName->scalarval(); if (strpos($methName, 'system.') === 0) { $dmap = $XML_RPC_Server_dmap; $sysCall = 1; } else { $dmap = $server->dmap; $sysCall = 0; } if (isset($dmap[$methName])) { if ($dmap[$methName]['docstring']) { $r = new XML_RPC_Response(new XML_RPC_Value($dmap[$methName]['docstring']), 'string'); } else { $r = new XML_RPC_Response(new XML_RPC_Value('', 'string')); } } else { $r = new XML_RPC_Response(0, $XML_RPC_err['introspect_unknown'], $XML_RPC_str['introspect_unknown']); } return $r; } /** * @return void */ function XML_RPC_Server_debugmsg($m) { global $XML_RPC_Server_debuginfo; $XML_RPC_Server_debuginfo = $XML_RPC_Server_debuginfo . $m . "\n"; } /** * A server for receiving and replying to XML RPC requests * * * $server = new XML_RPC_Server( * array( * 'isan8' => * array( * 'function' => 'is_8', * 'signature' => * array( * array('boolean', 'int'), * array('boolean', 'int', 'boolean'), * array('boolean', 'string'), * array('boolean', 'string', 'boolean'), * ), * 'docstring' => 'Is the value an 8?' * ), * ), * 1, * 0 * ); * * * @category Web Services * @package XML_RPC * @author Edd Dumbill * @author Stig Bakken * @author Martin Jansen * @author Daniel Convissor * @copyright 1999-2001 Edd Dumbill, 2001-2010 The PHP Group * @license http://www.php.net/license/3_01.txt PHP License * @version Release: @package_version@ * @link http://pear.php.net/package/XML_RPC */ class XML_RPC_Server { /** * Should the payload's content be passed through mb_convert_encoding()? * * @see XML_RPC_Server::setConvertPayloadEncoding() * @since Property available since Release 1.5.1 * @var boolean */ var $convert_payload_encoding = false; /** * The dispatch map, listing the methods this server provides. * @var array */ var $dmap = array(); /** * The present response's encoding * @var string * @see XML_RPC_Message::getEncoding() */ var $encoding = ''; /** * Debug mode (0 = off, 1 = on) * @var integer */ var $debug = 0; /** * The response's HTTP headers * @var string */ var $server_headers = ''; /** * The response's XML payload * @var string */ var $server_payload = ''; /** * Constructor for the XML_RPC_Server class * * @param array $dispMap the dispatch map. An associative array * explaining each function. The keys of the main * array are the procedure names used by the * clients. The value is another associative array * that contains up to three elements: * + The 'function' element's value is the name * of the function or method that gets called. * To define a class' method: 'class::method'. * + The 'signature' element (optional) is an * array describing the return values and * parameters * + The 'docstring' element (optional) is a * string describing what the method does * @param int $serviceNow should the HTTP response be sent now? * (1 = yes, 0 = no) * @param int $debug should debug output be displayed? * (1 = yes, 0 = no) * * @return void */ function XML_RPC_Server($dispMap, $serviceNow = 1, $debug = 0) { global $HTTP_RAW_POST_DATA; if ($debug) { $this->debug = 1; } else { $this->debug = 0; } $this->dmap = $dispMap; if ($serviceNow) { $this->service(); } else { $this->createServerPayload(); $this->createServerHeaders(); } } /** * @return string the debug information if debug debug mode is on */ function serializeDebug() { global $XML_RPC_Server_debuginfo, $HTTP_RAW_POST_DATA; if ($this->debug) { XML_RPC_Server_debugmsg('vvv POST DATA RECEIVED BY SERVER vvv' . "\n" . $HTTP_RAW_POST_DATA . "\n" . '^^^ END POST DATA ^^^'); } if ($XML_RPC_Server_debuginfo != '') { return "\n"; } else { return ''; } } /** * Sets whether the payload's content gets passed through * mb_convert_encoding() * * Returns PEAR_ERROR object if mb_convert_encoding() isn't available. * * @param int $in where 1 = on, 0 = off * * @return void * * @see XML_RPC_Message::getEncoding() * @since Method available since Release 1.5.1 */ function setConvertPayloadEncoding($in) { if ($in && !function_exists('mb_convert_encoding')) { return $this->raiseError('mb_convert_encoding() is not available', XML_RPC_ERROR_PROGRAMMING); } $this->convert_payload_encoding = $in; } /** * Sends the response * * The encoding and content-type are determined by * XML_RPC_Message::getEncoding() * * @return void * * @uses XML_RPC_Server::createServerPayload(), * XML_RPC_Server::createServerHeaders() */ function service() { if (!$this->server_payload) { $this->createServerPayload(); } if (!$this->server_headers) { $this->createServerHeaders(); } /* * $server_headers needs to remain a string for compatibility with * old scripts using this package, but PHP 4.4.2 no longer allows * line breaks in header() calls. So, we split each header into * an individual call. The initial replace handles the off chance * that someone composed a single header with multiple lines, which * the RFCs allow. */ $this->server_headers = preg_replace("@[\r\n]+[ \t]+@", ' ', trim($this->server_headers)); $headers = preg_split("@[\r\n]+@", $this->server_headers); foreach ($headers as $header) { header($header); } print $this->server_payload; } /** * Generates the payload and puts it in the $server_payload property * * If XML_RPC_Server::setConvertPayloadEncoding() was set to true, * the payload gets passed through mb_convert_encoding() * to ensure the payload matches the encoding set in the * XML declaration. The encoding type can be manually set via * XML_RPC_Message::setSendEncoding(). * * @return void * * @uses XML_RPC_Server::parseRequest(), XML_RPC_Server::$encoding, * XML_RPC_Response::serialize(), XML_RPC_Server::serializeDebug() * @see XML_RPC_Server::setConvertPayloadEncoding() */ function createServerPayload() { $r = $this->parseRequest(); $this->server_payload = 'encoding . '"?>' . "\n" . $this->serializeDebug() . $r->serialize(); if ($this->convert_payload_encoding) { $this->server_payload = mb_convert_encoding($this->server_payload, $this->encoding); } } /** * Determines the HTTP headers and puts them in the $server_headers * property * * @return boolean TRUE if okay, FALSE if $server_payload isn't set. * * @uses XML_RPC_Server::createServerPayload(), * XML_RPC_Server::$server_headers */ function createServerHeaders() { if (!$this->server_payload) { return false; } $this->server_headers = 'Content-Length: ' . strlen($this->server_payload) . "\r\n" . 'Content-Type: text/xml;' . ' charset=' . $this->encoding; return true; } /** * @return array */ function verifySignature($in, $sig) { for ($i = 0; $i < sizeof($sig); $i++) { // check each possible signature in turn $cursig = $sig[$i]; if (sizeof($cursig) == $in->getNumParams() + 1) { $itsOK = 1; for ($n = 0; $n < $in->getNumParams(); $n++) { $p = $in->getParam($n); // print "\n"; if ($p->kindOf() == 'scalar') { $pt = $p->scalartyp(); } else { $pt = $p->kindOf(); } // $n+1 as first type of sig is return type if ($pt != $cursig[$n+1]) { $itsOK = 0; $pno = $n+1; $wanted = $cursig[$n+1]; $got = $pt; break; } } if ($itsOK) { return array(1); } } } if (isset($wanted)) { return array(0, "Wanted ${wanted}, got ${got} at param ${pno}"); } else { $allowed = array(); foreach ($sig as $val) { end($val); $allowed[] = key($val); } $allowed = array_unique($allowed); $last = count($allowed) - 1; if ($last > 0) { $allowed[$last] = 'or ' . $allowed[$last]; } return array(0, 'Signature permits ' . implode(', ', $allowed) . ' parameters but the request had ' . $in->getNumParams()); } } /** * @return object a new XML_RPC_Response object * * @uses XML_RPC_Message::getEncoding(), XML_RPC_Server::$encoding */ function parseRequest($data = '') { global $XML_RPC_xh, $HTTP_RAW_POST_DATA, $XML_RPC_err, $XML_RPC_str, $XML_RPC_errxml, $XML_RPC_defencoding, $XML_RPC_Server_dmap; if ($data == '') { $data = $HTTP_RAW_POST_DATA; } $this->encoding = XML_RPC_Message::getEncoding($data); $parser_resource = xml_parser_create($this->encoding); $parser = (int) $parser_resource; $XML_RPC_xh[$parser] = array(); $XML_RPC_xh[$parser]['cm'] = 0; $XML_RPC_xh[$parser]['isf'] = 0; $XML_RPC_xh[$parser]['params'] = array(); $XML_RPC_xh[$parser]['method'] = ''; $XML_RPC_xh[$parser]['stack'] = array(); $XML_RPC_xh[$parser]['valuestack'] = array(); $plist = ''; // decompose incoming XML into request structure xml_parser_set_option($parser_resource, XML_OPTION_CASE_FOLDING, true); xml_set_element_handler($parser_resource, 'XML_RPC_se', 'XML_RPC_ee'); xml_set_character_data_handler($parser_resource, 'XML_RPC_cd'); if (!xml_parse($parser_resource, $data, 1)) { // return XML error as a faultCode $r = new XML_RPC_Response(0, $XML_RPC_errxml+xml_get_error_code($parser_resource), sprintf('XML error: %s at line %d', xml_error_string(xml_get_error_code($parser_resource)), xml_get_current_line_number($parser_resource))); xml_parser_free($parser_resource); } elseif ($XML_RPC_xh[$parser]['isf']>1) { $r = new XML_RPC_Response(0, $XML_RPC_err['invalid_request'], $XML_RPC_str['invalid_request'] . ': ' . $XML_RPC_xh[$parser]['isf_reason']); xml_parser_free($parser_resource); } else { xml_parser_free($parser_resource); $m = new XML_RPC_Message($XML_RPC_xh[$parser]['method']); // now add parameters in for ($i = 0; $i < sizeof($XML_RPC_xh[$parser]['params']); $i++) { // print '\n"; $plist .= "$i - " . var_export($XML_RPC_xh[$parser]['params'][$i], true) . " \n"; $m->addParam($XML_RPC_xh[$parser]['params'][$i]); } if ($this->debug) { XML_RPC_Server_debugmsg($plist); } // now to deal with the method $methName = $XML_RPC_xh[$parser]['method']; if (strpos($methName, 'system.') === 0) { $dmap = $XML_RPC_Server_dmap; $sysCall = 1; } else { $dmap = $this->dmap; $sysCall = 0; } if (isset($dmap[$methName]['function']) && is_string($dmap[$methName]['function']) && strpos($dmap[$methName]['function'], '::') !== false) { $dmap[$methName]['function'] = explode('::', $dmap[$methName]['function']); } if (isset($dmap[$methName]['function']) && is_callable($dmap[$methName]['function'])) { // dispatch if exists if (isset($dmap[$methName]['signature'])) { $sr = $this->verifySignature($m, $dmap[$methName]['signature'] ); } if (!isset($dmap[$methName]['signature']) || $sr[0]) { // if no signature or correct signature if ($sysCall) { $r = call_user_func($dmap[$methName]['function'], $this, $m); } else { $r = call_user_func($dmap[$methName]['function'], $m); } if (!is_object($r) || !is_a($r, 'XML_RPC_Response')) { $r = new XML_RPC_Response(0, $XML_RPC_err['not_response_object'], $XML_RPC_str['not_response_object']); } } else { $r = new XML_RPC_Response(0, $XML_RPC_err['incorrect_params'], $XML_RPC_str['incorrect_params'] . ': ' . $sr[1]); } } else { // else prepare error response $r = new XML_RPC_Response(0, $XML_RPC_err['unknown_method'], $XML_RPC_str['unknown_method']); } } return $r; } /** * Echos back the input packet as a string value * * @return void * * Useful for debugging. */ function echoInput() { global $HTTP_RAW_POST_DATA; $r = new XML_RPC_Response(0); $r->xv = new XML_RPC_Value("'Aha said I: '" . $HTTP_RAW_POST_DATA, 'string'); print $r->serialize(); } } /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * c-hanging-comment-ender-p: nil * End: */ ?> PKu]c}} XML/Util.phpnu[ * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 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. * * The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS 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 COPYRIGHT OWNER OR * 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. * * @category XML * @package XML_Util * @author Stephan Schmidt * @copyright 2003-2008 Stephan Schmidt * @license http://opensource.org/licenses/bsd-license New BSD License * @version CVS: $Id$ * @link http://pear.php.net/package/XML_Util */ /** * Error code for invalid chars in XML name */ define('XML_UTIL_ERROR_INVALID_CHARS', 51); /** * Error code for invalid chars in XML name */ define('XML_UTIL_ERROR_INVALID_START', 52); /** * Error code for non-scalar tag content */ define('XML_UTIL_ERROR_NON_SCALAR_CONTENT', 60); /** * Error code for missing tag name */ define('XML_UTIL_ERROR_NO_TAG_NAME', 61); /** * Replace XML entities */ define('XML_UTIL_REPLACE_ENTITIES', 1); /** * Embedd content in a CData Section */ define('XML_UTIL_CDATA_SECTION', 5); /** * Do not replace entitites */ define('XML_UTIL_ENTITIES_NONE', 0); /** * Replace all XML entitites * This setting will replace <, >, ", ' and & */ define('XML_UTIL_ENTITIES_XML', 1); /** * Replace only required XML entitites * This setting will replace <, " and & */ define('XML_UTIL_ENTITIES_XML_REQUIRED', 2); /** * Replace HTML entitites * @link http://www.php.net/htmlentities */ define('XML_UTIL_ENTITIES_HTML', 3); /** * Do not collapse any empty tags. */ define('XML_UTIL_COLLAPSE_NONE', 0); /** * Collapse all empty tags. */ define('XML_UTIL_COLLAPSE_ALL', 1); /** * Collapse only empty XHTML tags that have no end tag. */ define('XML_UTIL_COLLAPSE_XHTML_ONLY', 2); /** * Utility class for working with XML documents * * @category XML * @package XML_Util * @author Stephan Schmidt * @copyright 2003-2008 Stephan Schmidt * @license http://opensource.org/licenses/bsd-license New BSD License * @version Release: 1.4.5 * @link http://pear.php.net/package/XML_Util */ class XML_Util { /** * Return API version * * @return string $version API version */ public static function apiVersion() { return '1.4'; } /** * Replace XML entities * * With the optional second parameter, you may select, which * entities should be replaced. * * * require_once 'XML/Util.php'; * * // replace XML entites: * $string = XML_Util::replaceEntities('This string contains < & >.'); * * * With the optional third parameter, you may pass the character encoding * * require_once 'XML/Util.php'; * * // replace XML entites in UTF-8: * $string = XML_Util::replaceEntities( * 'This string contains < & > as well as ä, ö, ß, à and ê', * XML_UTIL_ENTITIES_HTML, * 'UTF-8' * ); * * * @param string $string string where XML special chars * should be replaced * @param int $replaceEntities setting for entities in attribute values * (one of XML_UTIL_ENTITIES_XML, * XML_UTIL_ENTITIES_XML_REQUIRED, * XML_UTIL_ENTITIES_HTML) * @param string $encoding encoding value (if any)... * must be a valid encoding as determined * by the htmlentities() function * * @return string string with replaced chars * @see reverseEntities() */ public static function replaceEntities( $string, $replaceEntities = XML_UTIL_ENTITIES_XML, $encoding = 'ISO-8859-1' ) { switch ($replaceEntities) { case XML_UTIL_ENTITIES_XML: return strtr( $string, array( '&' => '&', '>' => '>', '<' => '<', '"' => '"', '\'' => ''' ) ); break; case XML_UTIL_ENTITIES_XML_REQUIRED: return strtr( $string, array( '&' => '&', '<' => '<', '"' => '"' ) ); break; case XML_UTIL_ENTITIES_HTML: return htmlentities($string, ENT_COMPAT, $encoding); break; } return $string; } /** * Reverse XML entities * * With the optional second parameter, you may select, which * entities should be reversed. * * * require_once 'XML/Util.php'; * * // reverse XML entites: * $string = XML_Util::reverseEntities('This string contains < & >.'); * * * With the optional third parameter, you may pass the character encoding * * require_once 'XML/Util.php'; * * // reverse XML entites in UTF-8: * $string = XML_Util::reverseEntities( * 'This string contains < & > as well as' * . ' ä, ö, ß, à and ê', * XML_UTIL_ENTITIES_HTML, * 'UTF-8' * ); * * * @param string $string string where XML special chars * should be replaced * @param int $replaceEntities setting for entities in attribute values * (one of XML_UTIL_ENTITIES_XML, * XML_UTIL_ENTITIES_XML_REQUIRED, * XML_UTIL_ENTITIES_HTML) * @param string $encoding encoding value (if any)... * must be a valid encoding as determined * by the html_entity_decode() function * * @return string string with replaced chars * @see replaceEntities() */ public static function reverseEntities( $string, $replaceEntities = XML_UTIL_ENTITIES_XML, $encoding = 'ISO-8859-1' ) { switch ($replaceEntities) { case XML_UTIL_ENTITIES_XML: return strtr( $string, array( '&' => '&', '>' => '>', '<' => '<', '"' => '"', ''' => '\'' ) ); break; case XML_UTIL_ENTITIES_XML_REQUIRED: return strtr( $string, array( '&' => '&', '<' => '<', '"' => '"' ) ); break; case XML_UTIL_ENTITIES_HTML: return html_entity_decode($string, ENT_COMPAT, $encoding); break; } return $string; } /** * Build an xml declaration * * * require_once 'XML/Util.php'; * * // get an XML declaration: * $xmlDecl = XML_Util::getXMLDeclaration('1.0', 'UTF-8', true); * * * @param string $version xml version * @param string $encoding character encoding * @param bool $standalone document is standalone (or not) * * @return string xml declaration * @uses attributesToString() to serialize the attributes of the * XML declaration */ public static function getXMLDeclaration( $version = '1.0', $encoding = null, $standalone = null ) { $attributes = array( 'version' => $version, ); // add encoding if ($encoding !== null) { $attributes['encoding'] = $encoding; } // add standalone, if specified if ($standalone !== null) { $attributes['standalone'] = $standalone ? 'yes' : 'no'; } return sprintf( '', XML_Util::attributesToString($attributes, false) ); } /** * Build a document type declaration * * * require_once 'XML/Util.php'; * * // get a doctype declaration: * $xmlDecl = XML_Util::getDocTypeDeclaration('rootTag','myDocType.dtd'); * * * @param string $root name of the root tag * @param string $uri uri of the doctype definition * (or array with uri and public id) * @param string $internalDtd internal dtd entries * * @return string doctype declaration * @since 0.2 */ public static function getDocTypeDeclaration( $root, $uri = null, $internalDtd = null ) { if (is_array($uri)) { $ref = sprintf(' PUBLIC "%s" "%s"', $uri['id'], $uri['uri']); } elseif (!empty($uri)) { $ref = sprintf(' SYSTEM "%s"', $uri); } else { $ref = ''; } if (empty($internalDtd)) { return sprintf('', $root, $ref); } else { return sprintf("", $root, $ref, $internalDtd); } } /** * Create string representation of an attribute list * * * require_once 'XML/Util.php'; * * // build an attribute string * $att = array( * 'foo' => 'bar', * 'argh' => 'tomato' * ); * * $attList = XML_Util::attributesToString($att); * * * @param array $attributes attribute array * @param bool|array $sort sort attribute list alphabetically, * may also be an assoc array containing * the keys 'sort', 'multiline', 'indent', * 'linebreak' and 'entities' * @param bool $multiline use linebreaks, if more than * one attribute is given * @param string $indent string used for indentation of * multiline attributes * @param string $linebreak string used for linebreaks of * multiline attributes * @param int $entities setting for entities in attribute values * (one of XML_UTIL_ENTITIES_NONE, * XML_UTIL_ENTITIES_XML, * XML_UTIL_ENTITIES_XML_REQUIRED, * XML_UTIL_ENTITIES_HTML) * * @return string string representation of the attributes * @uses replaceEntities() to replace XML entities in attribute values * @todo allow sort also to be an options array */ public static function attributesToString( $attributes, $sort = true, $multiline = false, $indent = ' ', $linebreak = "\n", $entities = XML_UTIL_ENTITIES_XML ) { /* * second parameter may be an array */ if (is_array($sort)) { if (isset($sort['multiline'])) { $multiline = $sort['multiline']; } if (isset($sort['indent'])) { $indent = $sort['indent']; } if (isset($sort['linebreak'])) { $multiline = $sort['linebreak']; } if (isset($sort['entities'])) { $entities = $sort['entities']; } if (isset($sort['sort'])) { $sort = $sort['sort']; } else { $sort = true; } } $string = ''; if (is_array($attributes) && !empty($attributes)) { if ($sort) { ksort($attributes); } if (!$multiline || count($attributes) == 1) { foreach ($attributes as $key => $value) { if ($entities != XML_UTIL_ENTITIES_NONE) { if ($entities === XML_UTIL_CDATA_SECTION) { $entities = XML_UTIL_ENTITIES_XML; } $value = XML_Util::replaceEntities($value, $entities); } $string .= ' ' . $key . '="' . $value . '"'; } } else { $first = true; foreach ($attributes as $key => $value) { if ($entities != XML_UTIL_ENTITIES_NONE) { $value = XML_Util::replaceEntities($value, $entities); } if ($first) { $string .= ' ' . $key . '="' . $value . '"'; $first = false; } else { $string .= $linebreak . $indent . $key . '="' . $value . '"'; } } } } return $string; } /** * Collapses empty tags. * * @param string $xml XML * @param int $mode Whether to collapse all empty tags (XML_UTIL_COLLAPSE_ALL) * or only XHTML (XML_UTIL_COLLAPSE_XHTML_ONLY) ones. * * @return string XML */ public static function collapseEmptyTags($xml, $mode = XML_UTIL_COLLAPSE_ALL) { if (preg_match('~<([^>])+/>~s', $xml, $matches)) { // it's already an empty tag return $xml; } switch ($mode) { case XML_UTIL_COLLAPSE_ALL: $preg1 = '~<' . '(?:' . '(https?://[^:\s]+:\w+)' . // ]*)' . // attributes ($4) '>' . '<\/(\1|\2|\3)>' . // 1, 2, or 3 again ($5) '~s' ; $preg2 = '<' . '${1}${2}${3}' . // tag (only one should have been populated) '${4}' . // attributes ' />' ; return (preg_replace($preg1, $preg2, $xml)?:$xml); break; case XML_UTIL_COLLAPSE_XHTML_ONLY: return ( preg_replace( '/<(area|base(?:font)?|br|col|frame|hr|img|input|isindex|link|meta|' . 'param)([^>]*)><\/\\1>/s', '<\\1\\2 />', $xml ) ?: $xml ); break; case XML_UTIL_COLLAPSE_NONE: // fall thru default: return $xml; } } /** * Create a tag * * This method will call XML_Util::createTagFromArray(), which * is more flexible. * * * require_once 'XML/Util.php'; * * // create an XML tag: * $tag = XML_Util::createTag('myNs:myTag', * array('foo' => 'bar'), * 'This is inside the tag', * 'http://www.w3c.org/myNs#'); * * * @param string $qname qualified tagname (including namespace) * @param array $attributes array containg attributes * @param mixed $content the content * @param string $namespaceUri URI of the namespace * @param int $replaceEntities whether to replace XML special chars in * content, embedd it in a CData section * or none of both * @param bool $multiline whether to create a multiline tag where * each attribute gets written to a single line * @param string $indent string used to indent attributes * (_auto indents attributes so they start * at the same column) * @param string $linebreak string used for linebreaks * @param bool $sortAttributes Whether to sort the attributes or not * @param int $collapseTagMode How to handle a content-less, and thus collapseable, tag * * @return string XML tag * @see createTagFromArray() * @uses createTagFromArray() to create the tag */ public static function createTag( $qname, $attributes = array(), $content = null, $namespaceUri = null, $replaceEntities = XML_UTIL_REPLACE_ENTITIES, $multiline = false, $indent = '_auto', $linebreak = "\n", $sortAttributes = true, $collapseTagMode = XML_UTIL_COLLAPSE_ALL ) { $tag = array( 'qname' => $qname, 'attributes' => $attributes ); // add tag content if ($content !== null) { $tag['content'] = $content; } // add namespace Uri if ($namespaceUri !== null) { $tag['namespaceUri'] = $namespaceUri; } return XML_Util::createTagFromArray( $tag, $replaceEntities, $multiline, $indent, $linebreak, $sortAttributes, $collapseTagMode ); } /** * Create a tag from an array. * This method awaits an array in the following format *
     * array(
     *     // qualified name of the tag
     *     'qname' => $qname
     *
     *     // namespace prefix (optional, if qname is specified or no namespace)
     *     'namespace' => $namespace
     *
     *     // local part of the tagname (optional, if qname is specified)
     *     'localpart' => $localpart,
     *
     *     // array containing all attributes (optional)
     *     'attributes' => array(),
     *
     *     // tag content (optional)
     *     'content' => $content,
     *
     *     // namespaceUri for the given namespace (optional)
     *     'namespaceUri' => $namespaceUri
     * )
     * 
* * * require_once 'XML/Util.php'; * * $tag = array( * 'qname' => 'foo:bar', * 'namespaceUri' => 'http://foo.com', * 'attributes' => array('key' => 'value', 'argh' => 'fruit&vegetable'), * 'content' => 'I\'m inside the tag', * ); * // creating a tag with qualified name and namespaceUri * $string = XML_Util::createTagFromArray($tag); * * * @param array $tag tag definition * @param int $replaceEntities whether to replace XML special chars in * content, embedd it in a CData section * or none of both * @param bool $multiline whether to create a multiline tag where each * attribute gets written to a single line * @param string $indent string used to indent attributes * (_auto indents attributes so they start * at the same column) * @param string $linebreak string used for linebreaks * @param bool $sortAttributes Whether to sort the attributes or not * @param int $collapseTagMode How to handle a content-less, and thus collapseable, tag * * @return string XML tag * * @see createTag() * @uses attributesToString() to serialize the attributes of the tag * @uses splitQualifiedName() to get local part and namespace of a qualified name * @uses createCDataSection() * @uses collapseEmptyTags() * @uses raiseError() */ public static function createTagFromArray( $tag, $replaceEntities = XML_UTIL_REPLACE_ENTITIES, $multiline = false, $indent = '_auto', $linebreak = "\n", $sortAttributes = true, $collapseTagMode = XML_UTIL_COLLAPSE_ALL ) { if (isset($tag['content']) && !is_scalar($tag['content'])) { return XML_Util::raiseError( 'Supplied non-scalar value as tag content', XML_UTIL_ERROR_NON_SCALAR_CONTENT ); } if (!isset($tag['qname']) && !isset($tag['localPart'])) { return XML_Util::raiseError( 'You must either supply a qualified name ' . '(qname) or local tag name (localPart).', XML_UTIL_ERROR_NO_TAG_NAME ); } // if no attributes hav been set, use empty attributes if (!isset($tag['attributes']) || !is_array($tag['attributes'])) { $tag['attributes'] = array(); } if (isset($tag['namespaces'])) { foreach ($tag['namespaces'] as $ns => $uri) { $tag['attributes']['xmlns:' . $ns] = $uri; } } if (!isset($tag['qname'])) { // qualified name is not given // check for namespace if (isset($tag['namespace']) && !empty($tag['namespace'])) { $tag['qname'] = $tag['namespace'] . ':' . $tag['localPart']; } else { $tag['qname'] = $tag['localPart']; } } elseif (isset($tag['namespaceUri']) && !isset($tag['namespace'])) { // namespace URI is set, but no namespace $parts = XML_Util::splitQualifiedName($tag['qname']); $tag['localPart'] = $parts['localPart']; if (isset($parts['namespace'])) { $tag['namespace'] = $parts['namespace']; } } if (isset($tag['namespaceUri']) && !empty($tag['namespaceUri'])) { // is a namespace given if (isset($tag['namespace']) && !empty($tag['namespace'])) { $tag['attributes']['xmlns:' . $tag['namespace']] = $tag['namespaceUri']; } else { // define this Uri as the default namespace $tag['attributes']['xmlns'] = $tag['namespaceUri']; } } if (!array_key_exists('content', $tag)) { $tag['content'] = ''; } // check for multiline attributes if ($multiline === true) { if ($indent === '_auto') { $indent = str_repeat(' ', (strlen($tag['qname'])+2)); } } // create attribute list $attList = XML_Util::attributesToString( $tag['attributes'], $sortAttributes, $multiline, $indent, $linebreak ); switch ($replaceEntities) { case XML_UTIL_ENTITIES_NONE: break; case XML_UTIL_CDATA_SECTION: $tag['content'] = XML_Util::createCDataSection($tag['content']); break; default: $tag['content'] = XML_Util::replaceEntities( $tag['content'], $replaceEntities ); break; } $tag = sprintf( '<%s%s>%s', $tag['qname'], $attList, $tag['content'], $tag['qname'] ); return self::collapseEmptyTags($tag, $collapseTagMode); } /** * Create a start element * * * require_once 'XML/Util.php'; * * // create an XML start element: * $tag = XML_Util::createStartElement('myNs:myTag', * array('foo' => 'bar') ,'http://www.w3c.org/myNs#'); * * * @param string $qname qualified tagname (including namespace) * @param array $attributes array containg attributes * @param string $namespaceUri URI of the namespace * @param bool $multiline whether to create a multiline tag where each * attribute gets written to a single line * @param string $indent string used to indent attributes (_auto indents * attributes so they start at the same column) * @param string $linebreak string used for linebreaks * @param bool $sortAttributes Whether to sort the attributes or not * * @return string XML start element * @see createEndElement(), createTag() */ public static function createStartElement( $qname, $attributes = array(), $namespaceUri = null, $multiline = false, $indent = '_auto', $linebreak = "\n", $sortAttributes = true ) { // if no attributes hav been set, use empty attributes if (!isset($attributes) || !is_array($attributes)) { $attributes = array(); } if ($namespaceUri != null) { $parts = XML_Util::splitQualifiedName($qname); } // check for multiline attributes if ($multiline === true) { if ($indent === '_auto') { $indent = str_repeat(' ', (strlen($qname)+2)); } } if ($namespaceUri != null) { // is a namespace given if (isset($parts['namespace']) && !empty($parts['namespace'])) { $attributes['xmlns:' . $parts['namespace']] = $namespaceUri; } else { // define this Uri as the default namespace $attributes['xmlns'] = $namespaceUri; } } // create attribute list $attList = XML_Util::attributesToString( $attributes, $sortAttributes, $multiline, $indent, $linebreak ); $element = sprintf('<%s%s>', $qname, $attList); return $element; } /** * Create an end element * * * require_once 'XML/Util.php'; * * // create an XML start element: * $tag = XML_Util::createEndElement('myNs:myTag'); * * * @param string $qname qualified tagname (including namespace) * * @return string XML end element * @see createStartElement(), createTag() */ public static function createEndElement($qname) { $element = sprintf('', $qname); return $element; } /** * Create an XML comment * * * require_once 'XML/Util.php'; * * // create an XML start element: * $tag = XML_Util::createComment('I am a comment'); * * * @param string $content content of the comment * * @return string XML comment */ public static function createComment($content) { $comment = sprintf('', $content); return $comment; } /** * Create a CData section * * * require_once 'XML/Util.php'; * * // create a CData section * $tag = XML_Util::createCDataSection('I am content.'); * * * @param string $data data of the CData section * * @return string CData section with content */ public static function createCDataSection($data) { return sprintf( '', preg_replace('/\]\]>/', ']]]]>', strval($data)) ); } /** * Split qualified name and return namespace and local part * * * require_once 'XML/Util.php'; * * // split qualified tag * $parts = XML_Util::splitQualifiedName('xslt:stylesheet'); * * the returned array will contain two elements: *
     * array(
     *     'namespace' => 'xslt',
     *     'localPart' => 'stylesheet'
     * );
     * 
* * @param string $qname qualified tag name * @param string $defaultNs default namespace (optional) * * @return array array containing namespace and local part */ public static function splitQualifiedName($qname, $defaultNs = null) { if (strstr($qname, ':')) { $tmp = explode(':', $qname); return array( 'namespace' => $tmp[0], 'localPart' => $tmp[1] ); } return array( 'namespace' => $defaultNs, 'localPart' => $qname ); } /** * Check, whether string is valid XML name * *

XML names are used for tagname, attribute names and various * other, lesser known entities.

*

An XML name may only consist of alphanumeric characters, * dashes, undescores and periods, and has to start with a letter * or an underscore.

* * * require_once 'XML/Util.php'; * * // verify tag name * $result = XML_Util::isValidName('invalidTag?'); * if (is_a($result, 'PEAR_Error')) { * print 'Invalid XML name: ' . $result->getMessage(); * } * * * @param string $string string that should be checked * * @return mixed true, if string is a valid XML name, PEAR error otherwise * * @todo support for other charsets * @todo PEAR CS - unable to avoid 85-char limit on second preg_match */ public static function isValidName($string) { // check for invalid chars if (!is_string($string) || !strlen($string) || !preg_match('/^[[:alpha:]_]\\z/', $string[0])) { return XML_Util::raiseError( 'XML names may only start with letter or underscore', XML_UTIL_ERROR_INVALID_START ); } // check for invalid chars $match = preg_match( '/^([[:alpha:]_]([[:alnum:]\-\.]*)?:)?' . '[[:alpha:]_]([[:alnum:]\_\-\.]+)?\\z/', $string ); if (!$match) { return XML_Util::raiseError( 'XML names may only contain alphanumeric ' . 'chars, period, hyphen, colon and underscores', XML_UTIL_ERROR_INVALID_CHARS ); } // XML name is valid return true; } /** * Replacement for XML_Util::raiseError * * Avoids the necessity to always require * PEAR.php * * @param string $msg error message * @param int $code error code * * @return PEAR_Error * @todo PEAR CS - should this use include_once instead? */ public static function raiseError($msg, $code) { include_once 'PEAR.php'; return PEAR::raiseError($msg, $code); } } ?> PKu]/= XML/RPC.phpnu[ * @author Stig Bakken * @author Martin Jansen * @author Daniel Convissor * @copyright 1999-2001 Edd Dumbill, 2001-2010 The PHP Group * @license http://www.php.net/license/3_01.txt PHP License * @version SVN: $Id: RPC.php 315594 2011-08-27 01:03:57Z danielc $ * @link http://pear.php.net/package/XML_RPC */ if (!function_exists('xml_parser_create')) { include_once 'PEAR.php'; PEAR::loadExtension('xml'); } /**#@+ * Error constants */ /** * Parameter values don't match parameter types */ define('XML_RPC_ERROR_INVALID_TYPE', 101); /** * Parameter declared to be numeric but the values are not */ define('XML_RPC_ERROR_NON_NUMERIC_FOUND', 102); /** * Communication error */ define('XML_RPC_ERROR_CONNECTION_FAILED', 103); /** * The array or struct has already been started */ define('XML_RPC_ERROR_ALREADY_INITIALIZED', 104); /** * Incorrect parameters submitted */ define('XML_RPC_ERROR_INCORRECT_PARAMS', 105); /** * Programming error by developer */ define('XML_RPC_ERROR_PROGRAMMING', 106); /**#@-*/ /** * Data types * @global string $GLOBALS['XML_RPC_I4'] */ $GLOBALS['XML_RPC_I4'] = 'i4'; /** * Data types * @global string $GLOBALS['XML_RPC_Int'] */ $GLOBALS['XML_RPC_Int'] = 'int'; /** * Data types * @global string $GLOBALS['XML_RPC_Boolean'] */ $GLOBALS['XML_RPC_Boolean'] = 'boolean'; /** * Data types * @global string $GLOBALS['XML_RPC_Double'] */ $GLOBALS['XML_RPC_Double'] = 'double'; /** * Data types * @global string $GLOBALS['XML_RPC_String'] */ $GLOBALS['XML_RPC_String'] = 'string'; /** * Data types * @global string $GLOBALS['XML_RPC_DateTime'] */ $GLOBALS['XML_RPC_DateTime'] = 'dateTime.iso8601'; /** * Data types * @global string $GLOBALS['XML_RPC_Base64'] */ $GLOBALS['XML_RPC_Base64'] = 'base64'; /** * Data types * @global string $GLOBALS['XML_RPC_Array'] */ $GLOBALS['XML_RPC_Array'] = 'array'; /** * Data types * @global string $GLOBALS['XML_RPC_Struct'] */ $GLOBALS['XML_RPC_Struct'] = 'struct'; /** * Data type meta-types * @global array $GLOBALS['XML_RPC_Types'] */ $GLOBALS['XML_RPC_Types'] = array( $GLOBALS['XML_RPC_I4'] => 1, $GLOBALS['XML_RPC_Int'] => 1, $GLOBALS['XML_RPC_Boolean'] => 1, $GLOBALS['XML_RPC_String'] => 1, $GLOBALS['XML_RPC_Double'] => 1, $GLOBALS['XML_RPC_DateTime'] => 1, $GLOBALS['XML_RPC_Base64'] => 1, $GLOBALS['XML_RPC_Array'] => 2, $GLOBALS['XML_RPC_Struct'] => 3, ); /** * Error message numbers * @global array $GLOBALS['XML_RPC_err'] */ $GLOBALS['XML_RPC_err'] = array( 'unknown_method' => 1, 'invalid_return' => 2, 'incorrect_params' => 3, 'introspect_unknown' => 4, 'http_error' => 5, 'not_response_object' => 6, 'invalid_request' => 7, ); /** * Error message strings * @global array $GLOBALS['XML_RPC_str'] */ $GLOBALS['XML_RPC_str'] = array( 'unknown_method' => 'Unknown method', 'invalid_return' => 'Invalid return payload: enable debugging to examine incoming payload', 'incorrect_params' => 'Incorrect parameters passed to method', 'introspect_unknown' => 'Can\'t introspect: method unknown', 'http_error' => 'Didn\'t receive 200 OK from remote server.', 'not_response_object' => 'The requested method didn\'t return an XML_RPC_Response object.', 'invalid_request' => 'Invalid request payload', ); /** * Default XML encoding (ISO-8859-1, UTF-8 or US-ASCII) * @global string $GLOBALS['XML_RPC_defencoding'] */ $GLOBALS['XML_RPC_defencoding'] = 'UTF-8'; /** * User error codes start at 800 * @global int $GLOBALS['XML_RPC_erruser'] */ $GLOBALS['XML_RPC_erruser'] = 800; /** * XML parse error codes start at 100 * @global int $GLOBALS['XML_RPC_errxml'] */ $GLOBALS['XML_RPC_errxml'] = 100; /** * Compose backslashes for escaping regexp * @global string $GLOBALS['XML_RPC_backslash'] */ $GLOBALS['XML_RPC_backslash'] = chr(92) . chr(92); /** * Should we automatically base64 encode strings that contain characters * which can cause PHP's SAX-based XML parser to break? * @global boolean $GLOBALS['XML_RPC_auto_base64'] */ $GLOBALS['XML_RPC_auto_base64'] = false; /** * Valid parents of XML elements * @global array $GLOBALS['XML_RPC_valid_parents'] */ $GLOBALS['XML_RPC_valid_parents'] = array( 'BOOLEAN' => array('VALUE'), 'I4' => array('VALUE'), 'INT' => array('VALUE'), 'STRING' => array('VALUE'), 'DOUBLE' => array('VALUE'), 'DATETIME.ISO8601' => array('VALUE'), 'BASE64' => array('VALUE'), 'ARRAY' => array('VALUE'), 'STRUCT' => array('VALUE'), 'PARAM' => array('PARAMS'), 'METHODNAME' => array('METHODCALL'), 'PARAMS' => array('METHODCALL', 'METHODRESPONSE'), 'MEMBER' => array('STRUCT'), 'NAME' => array('MEMBER'), 'DATA' => array('ARRAY'), 'FAULT' => array('METHODRESPONSE'), 'VALUE' => array('MEMBER', 'DATA', 'PARAM', 'FAULT'), ); /** * Stores state during parsing * * quick explanation of components: * + ac = accumulates values * + qt = decides if quotes are needed for evaluation * + cm = denotes struct or array (comma needed) * + isf = indicates a fault * + lv = indicates "looking for a value": implements the logic * to allow values with no types to be strings * + params = stores parameters in method calls * + method = stores method name * * @global array $GLOBALS['XML_RPC_xh'] */ $GLOBALS['XML_RPC_xh'] = array(); /** * Start element handler for the XML parser * * @return void */ function XML_RPC_se($parser_resource, $name, $attrs) { global $XML_RPC_xh, $XML_RPC_valid_parents; $parser = (int) $parser_resource; // if invalid xmlrpc already detected, skip all processing if ($XML_RPC_xh[$parser]['isf'] >= 2) { return; } // check for correct element nesting // top level element can only be of 2 types if (count($XML_RPC_xh[$parser]['stack']) == 0) { if ($name != 'METHODRESPONSE' && $name != 'METHODCALL') { $XML_RPC_xh[$parser]['isf'] = 2; $XML_RPC_xh[$parser]['isf_reason'] = 'missing top level xmlrpc element'; return; } } else { // not top level element: see if parent is OK if (!in_array($XML_RPC_xh[$parser]['stack'][0], $XML_RPC_valid_parents[$name])) { $name = preg_replace('@[^a-zA-Z0-9._-]@', '', $name); $XML_RPC_xh[$parser]['isf'] = 2; $XML_RPC_xh[$parser]['isf_reason'] = "xmlrpc element $name cannot be child of {$XML_RPC_xh[$parser]['stack'][0]}"; return; } } switch ($name) { case 'STRUCT': $XML_RPC_xh[$parser]['cm']++; // turn quoting off $XML_RPC_xh[$parser]['qt'] = 0; $cur_val = array(); $cur_val['value'] = array(); $cur_val['members'] = 1; array_unshift($XML_RPC_xh[$parser]['valuestack'], $cur_val); break; case 'ARRAY': $XML_RPC_xh[$parser]['cm']++; // turn quoting off $XML_RPC_xh[$parser]['qt'] = 0; $cur_val = array(); $cur_val['value'] = array(); $cur_val['members'] = 0; array_unshift($XML_RPC_xh[$parser]['valuestack'], $cur_val); break; case 'NAME': $XML_RPC_xh[$parser]['ac'] = ''; break; case 'FAULT': $XML_RPC_xh[$parser]['isf'] = 1; break; case 'PARAM': $XML_RPC_xh[$parser]['valuestack'] = array(); break; case 'VALUE': $XML_RPC_xh[$parser]['lv'] = 1; $XML_RPC_xh[$parser]['vt'] = $GLOBALS['XML_RPC_String']; $XML_RPC_xh[$parser]['ac'] = ''; $XML_RPC_xh[$parser]['qt'] = 0; // look for a value: if this is still 1 by the // time we reach the first data segment then the type is string // by implication and we need to add in a quote break; case 'I4': case 'INT': case 'STRING': case 'BOOLEAN': case 'DOUBLE': case 'DATETIME.ISO8601': case 'BASE64': $XML_RPC_xh[$parser]['ac'] = ''; // reset the accumulator if ($name == 'DATETIME.ISO8601' || $name == 'STRING') { $XML_RPC_xh[$parser]['qt'] = 1; if ($name == 'DATETIME.ISO8601') { $XML_RPC_xh[$parser]['vt'] = $GLOBALS['XML_RPC_DateTime']; } } elseif ($name == 'BASE64') { $XML_RPC_xh[$parser]['qt'] = 2; } else { // No quoting is required here -- but // at the end of the element we must check // for data format errors. $XML_RPC_xh[$parser]['qt'] = 0; } break; case 'MEMBER': $XML_RPC_xh[$parser]['ac'] = ''; break; case 'DATA': case 'METHODCALL': case 'METHODNAME': case 'METHODRESPONSE': case 'PARAMS': // valid elements that add little to processing break; } // Save current element to stack array_unshift($XML_RPC_xh[$parser]['stack'], $name); if ($name != 'VALUE') { $XML_RPC_xh[$parser]['lv'] = 0; } } /** * End element handler for the XML parser * * @return void */ function XML_RPC_ee($parser_resource, $name) { global $XML_RPC_xh; $parser = (int) $parser_resource; if ($XML_RPC_xh[$parser]['isf'] >= 2) { return; } // push this element from stack // NB: if XML validates, correct opening/closing is guaranteed and // we do not have to check for $name == $curr_elem. // we also checked for proper nesting at start of elements... $curr_elem = array_shift($XML_RPC_xh[$parser]['stack']); switch ($name) { case 'STRUCT': case 'ARRAY': $cur_val = array_shift($XML_RPC_xh[$parser]['valuestack']); $XML_RPC_xh[$parser]['value'] = $cur_val['value']; $XML_RPC_xh[$parser]['vt'] = strtolower($name); $XML_RPC_xh[$parser]['cm']--; break; case 'NAME': $XML_RPC_xh[$parser]['valuestack'][0]['name'] = $XML_RPC_xh[$parser]['ac']; break; case 'BOOLEAN': // special case here: we translate boolean 1 or 0 into PHP // constants true or false if ($XML_RPC_xh[$parser]['ac'] == '1') { $XML_RPC_xh[$parser]['ac'] = 'true'; } else { $XML_RPC_xh[$parser]['ac'] = 'false'; } $XML_RPC_xh[$parser]['vt'] = strtolower($name); // Drop through intentionally. case 'I4': case 'INT': case 'STRING': case 'DOUBLE': case 'DATETIME.ISO8601': case 'BASE64': if ($XML_RPC_xh[$parser]['qt'] == 1) { // we use double quotes rather than single so backslashification works OK $XML_RPC_xh[$parser]['value'] = $XML_RPC_xh[$parser]['ac']; } elseif ($XML_RPC_xh[$parser]['qt'] == 2) { $XML_RPC_xh[$parser]['value'] = base64_decode($XML_RPC_xh[$parser]['ac']); } elseif ($name == 'BOOLEAN') { $XML_RPC_xh[$parser]['value'] = $XML_RPC_xh[$parser]['ac']; } else { // we have an I4, INT or a DOUBLE // we must check that only 0123456789-. are characters here if (!preg_match("@^[+-]?[0123456789 \t\.]+$@", $XML_RPC_xh[$parser]['ac'])) { XML_RPC_Base::raiseError('Non-numeric value received in INT or DOUBLE', XML_RPC_ERROR_NON_NUMERIC_FOUND); $XML_RPC_xh[$parser]['value'] = XML_RPC_ERROR_NON_NUMERIC_FOUND; } else { // it's ok, add it on $XML_RPC_xh[$parser]['value'] = $XML_RPC_xh[$parser]['ac']; } } $XML_RPC_xh[$parser]['ac'] = ''; $XML_RPC_xh[$parser]['qt'] = 0; $XML_RPC_xh[$parser]['lv'] = 3; // indicate we've found a value break; case 'VALUE': if ($XML_RPC_xh[$parser]['vt'] == $GLOBALS['XML_RPC_String']) { if (strlen($XML_RPC_xh[$parser]['ac']) > 0) { $XML_RPC_xh[$parser]['value'] = $XML_RPC_xh[$parser]['ac']; } elseif ($XML_RPC_xh[$parser]['lv'] == 1) { // The element was empty. $XML_RPC_xh[$parser]['value'] = ''; } } $temp = new XML_RPC_Value($XML_RPC_xh[$parser]['value'], $XML_RPC_xh[$parser]['vt']); $cur_val = array_shift($XML_RPC_xh[$parser]['valuestack']); if (is_array($cur_val)) { if ($cur_val['members']==0) { $cur_val['value'][] = $temp; } else { $XML_RPC_xh[$parser]['value'] = $temp; } array_unshift($XML_RPC_xh[$parser]['valuestack'], $cur_val); } else { $XML_RPC_xh[$parser]['value'] = $temp; } break; case 'MEMBER': $XML_RPC_xh[$parser]['ac'] = ''; $XML_RPC_xh[$parser]['qt'] = 0; $cur_val = array_shift($XML_RPC_xh[$parser]['valuestack']); if (is_array($cur_val)) { if ($cur_val['members']==1) { $cur_val['value'][$cur_val['name']] = $XML_RPC_xh[$parser]['value']; } array_unshift($XML_RPC_xh[$parser]['valuestack'], $cur_val); } break; case 'DATA': $XML_RPC_xh[$parser]['ac'] = ''; $XML_RPC_xh[$parser]['qt'] = 0; break; case 'PARAM': $XML_RPC_xh[$parser]['params'][] = $XML_RPC_xh[$parser]['value']; break; case 'METHODNAME': case 'RPCMETHODNAME': $XML_RPC_xh[$parser]['method'] = preg_replace("@^[\n\r\t ]+@", '', $XML_RPC_xh[$parser]['ac']); break; } // if it's a valid type name, set the type if (isset($GLOBALS['XML_RPC_Types'][strtolower($name)])) { $XML_RPC_xh[$parser]['vt'] = strtolower($name); } } /** * Character data handler for the XML parser * * @return void */ function XML_RPC_cd($parser_resource, $data) { global $XML_RPC_xh, $XML_RPC_backslash; $parser = (int) $parser_resource; if ($XML_RPC_xh[$parser]['lv'] != 3) { // "lookforvalue==3" means that we've found an entire value // and should discard any further character data if ($XML_RPC_xh[$parser]['lv'] == 1) { // if we've found text and we're just in a then // turn quoting on, as this will be a string $XML_RPC_xh[$parser]['qt'] = 1; // and say we've found a value $XML_RPC_xh[$parser]['lv'] = 2; } // replace characters that eval would // do special things with if (!isset($XML_RPC_xh[$parser]['ac'])) { $XML_RPC_xh[$parser]['ac'] = ''; } $XML_RPC_xh[$parser]['ac'] .= $data; } } /** * The common methods and properties for all of the XML_RPC classes * * @category Web Services * @package XML_RPC * @author Edd Dumbill * @author Stig Bakken * @author Martin Jansen * @author Daniel Convissor * @copyright 1999-2001 Edd Dumbill, 2001-2010 The PHP Group * @license http://www.php.net/license/3_01.txt PHP License * @version Release: @package_version@ * @link http://pear.php.net/package/XML_RPC */ class XML_RPC_Base { /** * PEAR Error handling * * @return object PEAR_Error object */ function raiseError($msg, $code) { include_once 'PEAR.php'; if (is_object(@$this)) { return PEAR::raiseError(get_class($this) . ': ' . $msg, $code); } else { return PEAR::raiseError('XML_RPC: ' . $msg, $code); } } /** * Tell whether something is a PEAR_Error object * * @param mixed $value the item to check * * @return bool whether $value is a PEAR_Error object or not * * @access public */ function isError($value) { return is_object($value) && is_a($value, 'PEAR_Error'); } } /** * The methods and properties for submitting XML RPC requests * * @category Web Services * @package XML_RPC * @author Edd Dumbill * @author Stig Bakken * @author Martin Jansen * @author Daniel Convissor * @copyright 1999-2001 Edd Dumbill, 2001-2010 The PHP Group * @license http://www.php.net/license/3_01.txt PHP License * @version Release: @package_version@ * @link http://pear.php.net/package/XML_RPC */ class XML_RPC_Client extends XML_RPC_Base { /** * The path and name of the RPC server script you want the request to go to * @var string */ var $path = ''; /** * The name of the remote server to connect to * @var string */ var $server = ''; /** * The protocol to use in contacting the remote server * @var string */ var $protocol = 'http://'; /** * The port for connecting to the remote server * * The default is 80 for http:// connections * and 443 for https:// and ssl:// connections. * * @var integer */ var $port = 80; /** * A user name for accessing the RPC server * @var string * @see XML_RPC_Client::setCredentials() */ var $username = ''; /** * A password for accessing the RPC server * @var string * @see XML_RPC_Client::setCredentials() */ var $password = ''; /** * The name of the proxy server to use, if any * @var string */ var $proxy = ''; /** * The protocol to use in contacting the proxy server, if any * @var string */ var $proxy_protocol = 'http://'; /** * The port for connecting to the proxy server * * The default is 8080 for http:// connections * and 443 for https:// and ssl:// connections. * * @var integer */ var $proxy_port = 8080; /** * A user name for accessing the proxy server * @var string */ var $proxy_user = ''; /** * A password for accessing the proxy server * @var string */ var $proxy_pass = ''; /** * The error number, if any * @var integer */ var $errno = 0; /** * The error message, if any * @var string */ var $errstr = ''; /** * The current debug mode (1 = on, 0 = off) * @var integer */ var $debug = 0; /** * The HTTP headers for the current request. * @var string */ var $headers = ''; /** * Sets the object's properties * * @param string $path the path and name of the RPC server script * you want the request to go to * @param string $server the URL of the remote server to connect to. * If this parameter doesn't specify a * protocol and $port is 443, ssl:// is * assumed. * @param integer $port a port for connecting to the remote server. * Defaults to 80 for http:// connections and * 443 for https:// and ssl:// connections. * @param string $proxy the URL of the proxy server to use, if any. * If this parameter doesn't specify a * protocol and $port is 443, ssl:// is * assumed. * @param integer $proxy_port a port for connecting to the remote server. * Defaults to 8080 for http:// connections and * 443 for https:// and ssl:// connections. * @param string $proxy_user a user name for accessing the proxy server * @param string $proxy_pass a password for accessing the proxy server * * @return void */ function XML_RPC_Client($path, $server, $port = 0, $proxy = '', $proxy_port = 0, $proxy_user = '', $proxy_pass = '') { $this->path = $path; $this->proxy_user = $proxy_user; $this->proxy_pass = $proxy_pass; preg_match('@^(http://|https://|ssl://)?(.*)$@', $server, $match); if ($match[1] == '') { if ($port == 443) { $this->server = $match[2]; $this->protocol = 'ssl://'; $this->port = 443; } else { $this->server = $match[2]; if ($port) { $this->port = $port; } } } elseif ($match[1] == 'http://') { $this->server = $match[2]; if ($port) { $this->port = $port; } } else { $this->server = $match[2]; $this->protocol = 'ssl://'; if ($port) { $this->port = $port; } else { $this->port = 443; } } if ($proxy) { preg_match('@^(http://|https://|ssl://)?(.*)$@', $proxy, $match); if ($match[1] == '') { if ($proxy_port == 443) { $this->proxy = $match[2]; $this->proxy_protocol = 'ssl://'; $this->proxy_port = 443; } else { $this->proxy = $match[2]; if ($proxy_port) { $this->proxy_port = $proxy_port; } } } elseif ($match[1] == 'http://') { $this->proxy = $match[2]; if ($proxy_port) { $this->proxy_port = $proxy_port; } } else { $this->proxy = $match[2]; $this->proxy_protocol = 'ssl://'; if ($proxy_port) { $this->proxy_port = $proxy_port; } else { $this->proxy_port = 443; } } } } /** * Change the current debug mode * * @param int $in where 1 = on, 0 = off * * @return void */ function setDebug($in) { if ($in) { $this->debug = 1; } else { $this->debug = 0; } } /** * Sets whether strings that contain characters which may cause PHP's * SAX-based XML parser to break should be automatically base64 encoded * * This is is a workaround for systems that don't have PHP's mbstring * extension available. * * @param int $in where 1 = on, 0 = off * * @return void */ function setAutoBase64($in) { if ($in) { $GLOBALS['XML_RPC_auto_base64'] = true; } else { $GLOBALS['XML_RPC_auto_base64'] = false; } } /** * Set username and password properties for connecting to the RPC server * * @param string $u the user name * @param string $p the password * * @return void * * @see XML_RPC_Client::$username, XML_RPC_Client::$password */ function setCredentials($u, $p) { $this->username = $u; $this->password = $p; } /** * Transmit the RPC request via HTTP 1.0 protocol * * @param object $msg the XML_RPC_Message object * @param int $timeout how many seconds to wait for the request * * @return object an XML_RPC_Response object. 0 is returned if any * problems happen. * * @see XML_RPC_Message, XML_RPC_Client::XML_RPC_Client(), * XML_RPC_Client::setCredentials() */ function send($msg, $timeout = 0) { if (!is_object($msg) || !is_a($msg, 'XML_RPC_Message')) { $this->errstr = 'send()\'s $msg parameter must be an' . ' XML_RPC_Message object.'; $this->raiseError($this->errstr, XML_RPC_ERROR_PROGRAMMING); return 0; } $msg->debug = $this->debug; return $this->sendPayloadHTTP10($msg, $this->server, $this->port, $timeout, $this->username, $this->password); } /** * Transmit the RPC request via HTTP 1.0 protocol * * Requests should be sent using XML_RPC_Client send() rather than * calling this method directly. * * @param object $msg the XML_RPC_Message object * @param string $server the server to send the request to * @param int $port the server port send the request to * @param int $timeout how many seconds to wait for the request * before giving up * @param string $username a user name for accessing the RPC server * @param string $password a password for accessing the RPC server * * @return object an XML_RPC_Response object. 0 is returned if any * problems happen. * * @access protected * @see XML_RPC_Client::send() */ function sendPayloadHTTP10($msg, $server, $port, $timeout = 0, $username = '', $password = '') { // Pre-emptive BC hacks for fools calling sendPayloadHTTP10() directly if ($username != $this->username) { $this->setCredentials($username, $password); } // Only create the payload if it was not created previously if (empty($msg->payload)) { $msg->createPayload(); } $this->createHeaders($msg); $op = $this->headers . "\r\n\r\n"; $op .= $msg->payload; if ($this->debug) { print "\n
---SENT---\n";
            print $op;
            print "\n---END---
\n"; } /* * If we're using a proxy open a socket to the proxy server * instead to the xml-rpc server */ if ($this->proxy) { if ($this->proxy_protocol == 'http://') { $protocol = ''; } else { $protocol = $this->proxy_protocol; } if ($timeout > 0) { $fp = @fsockopen($protocol . $this->proxy, $this->proxy_port, $this->errno, $this->errstr, $timeout); } else { $fp = @fsockopen($protocol . $this->proxy, $this->proxy_port, $this->errno, $this->errstr); } } else { if ($this->protocol == 'http://') { $protocol = ''; } else { $protocol = $this->protocol; } if ($timeout > 0) { $fp = @fsockopen($protocol . $server, $port, $this->errno, $this->errstr, $timeout); } else { $fp = @fsockopen($protocol . $server, $port, $this->errno, $this->errstr); } } /* * Just raising the error without returning it is strange, * but keep it here for backwards compatibility. */ if (!$fp && $this->proxy) { $this->raiseError('Connection to proxy server ' . $this->proxy . ':' . $this->proxy_port . ' failed. ' . $this->errstr, XML_RPC_ERROR_CONNECTION_FAILED); return 0; } elseif (!$fp) { $this->raiseError('Connection to RPC server ' . $server . ':' . $port . ' failed. ' . $this->errstr, XML_RPC_ERROR_CONNECTION_FAILED); return 0; } if ($timeout) { /* * Using socket_set_timeout() because stream_set_timeout() * was introduced in 4.3.0, but we need to support 4.2.0. */ socket_set_timeout($fp, $timeout); } if (!fputs($fp, $op, strlen($op))) { $this->errstr = 'Write error'; return 0; } $resp = $msg->parseResponseFile($fp); $meta = socket_get_status($fp); if ($meta['timed_out']) { fclose($fp); $this->errstr = 'RPC server did not send response before timeout.'; $this->raiseError($this->errstr, XML_RPC_ERROR_CONNECTION_FAILED); return 0; } fclose($fp); return $resp; } /** * Determines the HTTP headers and puts it in the $headers property * * @param object $msg the XML_RPC_Message object * * @return boolean TRUE if okay, FALSE if the message payload isn't set. * * @access protected */ function createHeaders($msg) { if (empty($msg->payload)) { return false; } if ($this->proxy) { $this->headers = 'POST ' . $this->protocol . $this->server; if ($this->proxy_port) { $this->headers .= ':' . $this->port; } } else { $this->headers = 'POST '; } $this->headers .= $this->path. " HTTP/1.0\r\n"; $this->headers .= "User-Agent: PEAR XML_RPC\r\n"; $this->headers .= 'Host: ' . $this->server . "\r\n"; if ($this->proxy && $this->proxy_user) { $this->headers .= 'Proxy-Authorization: Basic ' . base64_encode("$this->proxy_user:$this->proxy_pass") . "\r\n"; } // thanks to Grant Rauscher for this if ($this->username) { $this->headers .= 'Authorization: Basic ' . base64_encode("$this->username:$this->password") . "\r\n"; } $this->headers .= "Content-Type: text/xml\r\n"; $this->headers .= 'Content-Length: ' . strlen($msg->payload); return true; } } /** * The methods and properties for interpreting responses to XML RPC requests * * @category Web Services * @package XML_RPC * @author Edd Dumbill * @author Stig Bakken * @author Martin Jansen * @author Daniel Convissor * @copyright 1999-2001 Edd Dumbill, 2001-2010 The PHP Group * @license http://www.php.net/license/3_01.txt PHP License * @version Release: @package_version@ * @link http://pear.php.net/package/XML_RPC */ class XML_RPC_Response extends XML_RPC_Base { var $xv; var $fn; var $fs; var $hdrs; /** * @return void */ function XML_RPC_Response($val, $fcode = 0, $fstr = '') { if ($fcode != 0) { $this->fn = $fcode; $this->fs = htmlspecialchars($fstr); } else { $this->xv = $val; } } /** * @return int the error code */ function faultCode() { if (isset($this->fn)) { return $this->fn; } else { return 0; } } /** * @return string the error string */ function faultString() { return $this->fs; } /** * @return mixed the value */ function value() { return $this->xv; } /** * @return string the error message in XML format */ function serialize() { $rs = "\n"; if ($this->fn) { $rs .= " faultCode " . $this->fn . " faultString " . $this->fs . " "; } else { $rs .= "\n\n" . $this->xv->serialize() . "\n"; } $rs .= "\n"; return $rs; } } /** * The methods and properties for composing XML RPC messages * * @category Web Services * @package XML_RPC * @author Edd Dumbill * @author Stig Bakken * @author Martin Jansen * @author Daniel Convissor * @copyright 1999-2001 Edd Dumbill, 2001-2010 The PHP Group * @license http://www.php.net/license/3_01.txt PHP License * @version Release: @package_version@ * @link http://pear.php.net/package/XML_RPC */ class XML_RPC_Message extends XML_RPC_Base { /** * Should the payload's content be passed through mb_convert_encoding()? * * @see XML_RPC_Message::setConvertPayloadEncoding() * @since Property available since Release 1.5.1 * @var boolean */ var $convert_payload_encoding = false; /** * The current debug mode (1 = on, 0 = off) * @var integer */ var $debug = 0; /** * The encoding to be used for outgoing messages * * Defaults to the value of $GLOBALS['XML_RPC_defencoding'] * * @var string * @see XML_RPC_Message::setSendEncoding(), * $GLOBALS['XML_RPC_defencoding'], XML_RPC_Message::xml_header() */ var $send_encoding = ''; /** * The method presently being evaluated * @var string */ var $methodname = ''; /** * @var array */ var $params = array(); /** * The XML message being generated * @var string */ var $payload = ''; /** * Should extra line breaks be removed from the payload? * @since Property available since Release 1.4.6 * @var boolean */ var $remove_extra_lines = true; /** * The XML response from the remote server * @since Property available since Release 1.4.6 * @var string */ var $response_payload = ''; /** * @return void */ function XML_RPC_Message($meth, $pars = 0) { $this->methodname = $meth; if (is_array($pars) && sizeof($pars) > 0) { for ($i = 0; $i < sizeof($pars); $i++) { $this->addParam($pars[$i]); } } } /** * Produces the XML declaration including the encoding attribute * * The encoding is determined by this class' $send_encoding * property. If the $send_encoding property is not set, use * $GLOBALS['XML_RPC_defencoding']. * * @return string the XML declaration and element * * @see XML_RPC_Message::setSendEncoding(), * XML_RPC_Message::$send_encoding, $GLOBALS['XML_RPC_defencoding'] */ function xml_header() { global $XML_RPC_defencoding; if (!$this->send_encoding) { $this->send_encoding = $XML_RPC_defencoding; } return 'send_encoding . '"?>' . "\n\n"; } /** * @return string the closing tag */ function xml_footer() { return "\n"; } /** * Fills the XML_RPC_Message::$payload property * * Part of the process makes sure all line endings are in DOS format * (CRLF), which is probably required by specifications. * * If XML_RPC_Message::setConvertPayloadEncoding() was set to true, * the payload gets passed through mb_convert_encoding() * to ensure the payload matches the encoding set in the * XML declaration. The encoding type can be manually set via * XML_RPC_Message::setSendEncoding(). * * @return void * * @uses XML_RPC_Message::xml_header(), XML_RPC_Message::xml_footer() * @see XML_RPC_Message::setSendEncoding(), $GLOBALS['XML_RPC_defencoding'], * XML_RPC_Message::setConvertPayloadEncoding() */ function createPayload() { $this->payload = $this->xml_header(); $this->payload .= '' . $this->methodname . "\n"; $this->payload .= "\n"; for ($i = 0; $i < sizeof($this->params); $i++) { $p = $this->params[$i]; $this->payload .= "\n" . $p->serialize() . "\n"; } $this->payload .= "\n"; $this->payload .= $this->xml_footer(); if ($this->remove_extra_lines) { $this->payload = preg_replace("@[\r\n]+@", "\r\n", $this->payload); } else { $this->payload = preg_replace("@\r\n|\n|\r|\n\r@", "\r\n", $this->payload); } if ($this->convert_payload_encoding) { $this->payload = mb_convert_encoding($this->payload, $this->send_encoding); } } /** * @return string the name of the method */ function method($meth = '') { if ($meth != '') { $this->methodname = $meth; } return $this->methodname; } /** * @return string the payload */ function serialize() { $this->createPayload(); return $this->payload; } /** * @return void */ function addParam($par) { $this->params[] = $par; } /** * Obtains an XML_RPC_Value object for the given parameter * * @param int $i the index number of the parameter to obtain * * @return object the XML_RPC_Value object. * If the parameter doesn't exist, an XML_RPC_Response object. * * @since Returns XML_RPC_Response object on error since Release 1.3.0 */ function getParam($i) { global $XML_RPC_err, $XML_RPC_str; if (isset($this->params[$i])) { return $this->params[$i]; } else { $this->raiseError('The submitted request did not contain this parameter', XML_RPC_ERROR_INCORRECT_PARAMS); return new XML_RPC_Response(0, $XML_RPC_err['incorrect_params'], $XML_RPC_str['incorrect_params']); } } /** * @return int the number of parameters */ function getNumParams() { return sizeof($this->params); } /** * Sets whether the payload's content gets passed through * mb_convert_encoding() * * Returns PEAR_ERROR object if mb_convert_encoding() isn't available. * * @param int $in where 1 = on, 0 = off * * @return void * * @see XML_RPC_Message::setSendEncoding() * @since Method available since Release 1.5.1 */ function setConvertPayloadEncoding($in) { if ($in && !function_exists('mb_convert_encoding')) { return $this->raiseError('mb_convert_encoding() is not available', XML_RPC_ERROR_PROGRAMMING); } $this->convert_payload_encoding = $in; } /** * Sets the XML declaration's encoding attribute * * @param string $type the encoding type (ISO-8859-1, UTF-8 or US-ASCII) * * @return void * * @see XML_RPC_Message::setConvertPayloadEncoding(), XML_RPC_Message::xml_header() * @since Method available since Release 1.2.0 */ function setSendEncoding($type) { $this->send_encoding = $type; } /** * Determine the XML's encoding via the encoding attribute * in the XML declaration * * If the encoding parameter is not set or is not ISO-8859-1, UTF-8 * or US-ASCII, $XML_RPC_defencoding will be returned. * * @param string $data the XML that will be parsed * * @return string the encoding to be used * * @link http://php.net/xml_parser_create * @since Method available since Release 1.2.0 */ function getEncoding($data) { global $XML_RPC_defencoding; if (preg_match('@<\?xml[^>]*\s*encoding\s*=\s*[\'"]([^"\']*)[\'"]@', $data, $match)) { $match[1] = trim(strtoupper($match[1])); switch ($match[1]) { case 'ISO-8859-1': case 'UTF-8': case 'US-ASCII': return $match[1]; break; default: return $XML_RPC_defencoding; } } else { return $XML_RPC_defencoding; } } /** * @return object a new XML_RPC_Response object */ function parseResponseFile($fp) { $ipd = ''; while ($data = @fread($fp, 8192)) { $ipd .= $data; } return $this->parseResponse($ipd); } /** * @return object a new XML_RPC_Response object */ function parseResponse($data = '') { global $XML_RPC_xh, $XML_RPC_err, $XML_RPC_str, $XML_RPC_defencoding; $encoding = $this->getEncoding($data); $parser_resource = xml_parser_create($encoding); $parser = (int) $parser_resource; $XML_RPC_xh = array(); $XML_RPC_xh[$parser] = array(); $XML_RPC_xh[$parser]['cm'] = 0; $XML_RPC_xh[$parser]['isf'] = 0; $XML_RPC_xh[$parser]['ac'] = ''; $XML_RPC_xh[$parser]['qt'] = ''; $XML_RPC_xh[$parser]['stack'] = array(); $XML_RPC_xh[$parser]['valuestack'] = array(); xml_parser_set_option($parser_resource, XML_OPTION_CASE_FOLDING, true); xml_set_element_handler($parser_resource, 'XML_RPC_se', 'XML_RPC_ee'); xml_set_character_data_handler($parser_resource, 'XML_RPC_cd'); $hdrfnd = 0; if ($this->debug) { print "\n
---GOT---\n";
            print isset($_SERVER['SERVER_PROTOCOL']) ? htmlspecialchars($data) : $data;
            print "\n---END---
\n"; } // See if response is a 200 or a 100 then a 200, else raise error. // But only do this if we're using the HTTP protocol. if (preg_match('@^HTTP@', $data) && !preg_match('@^HTTP/[0-9\.]+ 200 @', $data) && !preg_match('@^HTTP/[0-9\.]+ 10[0-9]([A-Z ]+)?[\r\n]+HTTP/[0-9\.]+ 200@', $data)) { $errstr = substr($data, 0, strpos($data, "\n") - 1); error_log('HTTP error, got response: ' . $errstr); $r = new XML_RPC_Response(0, $XML_RPC_err['http_error'], $XML_RPC_str['http_error'] . ' (' . $errstr . ')'); xml_parser_free($parser_resource); return $r; } // gotta get rid of headers here if (!$hdrfnd && ($brpos = strpos($data,"\r\n\r\n"))) { $XML_RPC_xh[$parser]['ha'] = substr($data, 0, $brpos); $data = substr($data, $brpos + 4); $hdrfnd = 1; } /* * be tolerant of junk after methodResponse * (e.g. javascript automatically inserted by free hosts) * thanks to Luca Mariano */ $data = substr($data, 0, strpos($data, "") + 17); $this->response_payload = $data; if (!xml_parse($parser_resource, $data, sizeof($data))) { // thanks to Peter Kocks if (xml_get_current_line_number($parser_resource) == 1) { $errstr = 'XML error at line 1, check URL'; } else { $errstr = sprintf('XML error: %s at line %d', xml_error_string(xml_get_error_code($parser_resource)), xml_get_current_line_number($parser_resource)); } error_log($errstr); $r = new XML_RPC_Response(0, $XML_RPC_err['invalid_return'], $XML_RPC_str['invalid_return']); xml_parser_free($parser_resource); return $r; } xml_parser_free($parser_resource); if ($this->debug) { print "\n
---PARSED---\n";
            var_dump($XML_RPC_xh[$parser]['value']);
            print "---END---
\n"; } if ($XML_RPC_xh[$parser]['isf'] > 1) { $r = new XML_RPC_Response(0, $XML_RPC_err['invalid_return'], $XML_RPC_str['invalid_return'].' '.$XML_RPC_xh[$parser]['isf_reason']); } elseif (!is_object($XML_RPC_xh[$parser]['value'])) { // then something odd has happened // and it's time to generate a client side error // indicating something odd went on $r = new XML_RPC_Response(0, $XML_RPC_err['invalid_return'], $XML_RPC_str['invalid_return']); } else { $v = $XML_RPC_xh[$parser]['value']; if ($XML_RPC_xh[$parser]['isf']) { $f = $v->structmem('faultCode'); $fs = $v->structmem('faultString'); $r = new XML_RPC_Response($v, $f->scalarval(), $fs->scalarval()); } else { $r = new XML_RPC_Response($v); } } $r->hdrs = preg_split("@\r?\n@", $XML_RPC_xh[$parser]['ha']); return $r; } } /** * The methods and properties that represent data in XML RPC format * * @category Web Services * @package XML_RPC * @author Edd Dumbill * @author Stig Bakken * @author Martin Jansen * @author Daniel Convissor * @copyright 1999-2001 Edd Dumbill, 2001-2010 The PHP Group * @license http://www.php.net/license/3_01.txt PHP License * @version Release: @package_version@ * @link http://pear.php.net/package/XML_RPC */ class XML_RPC_Value extends XML_RPC_Base { var $me = array(); var $mytype = 0; /** * @return void */ function XML_RPC_Value($val = -1, $type = '') { $this->me = array(); $this->mytype = 0; if ($val != -1 || $type != '') { if ($type == '') { $type = 'string'; } if (!array_key_exists($type, $GLOBALS['XML_RPC_Types'])) { // XXX // need some way to report this error } elseif ($GLOBALS['XML_RPC_Types'][$type] == 1) { $this->addScalar($val, $type); } elseif ($GLOBALS['XML_RPC_Types'][$type] == 2) { $this->addArray($val); } elseif ($GLOBALS['XML_RPC_Types'][$type] == 3) { $this->addStruct($val); } } } /** * @return int returns 1 if successful or 0 if there are problems */ function addScalar($val, $type = 'string') { if ($this->mytype == 1) { $this->raiseError('Scalar can have only one value', XML_RPC_ERROR_INVALID_TYPE); return 0; } $typeof = $GLOBALS['XML_RPC_Types'][$type]; if ($typeof != 1) { $this->raiseError("Not a scalar type (${typeof})", XML_RPC_ERROR_INVALID_TYPE); return 0; } if ($type == $GLOBALS['XML_RPC_Boolean']) { if (strcasecmp($val, 'true') == 0 || $val == 1 || ($val == true && strcasecmp($val, 'false'))) { $val = 1; } else { $val = 0; } } if ($this->mytype == 2) { // we're adding to an array here $ar = $this->me['array']; $ar[] = new XML_RPC_Value($val, $type); $this->me['array'] = $ar; } else { // a scalar, so set the value and remember we're scalar $this->me[$type] = $val; $this->mytype = $typeof; } return 1; } /** * @return int returns 1 if successful or 0 if there are problems */ function addArray($vals) { if ($this->mytype != 0) { $this->raiseError( 'Already initialized as a [' . $this->kindOf() . ']', XML_RPC_ERROR_ALREADY_INITIALIZED); return 0; } $this->mytype = $GLOBALS['XML_RPC_Types']['array']; $this->me['array'] = $vals; return 1; } /** * @return int returns 1 if successful or 0 if there are problems */ function addStruct($vals) { if ($this->mytype != 0) { $this->raiseError( 'Already initialized as a [' . $this->kindOf() . ']', XML_RPC_ERROR_ALREADY_INITIALIZED); return 0; } $this->mytype = $GLOBALS['XML_RPC_Types']['struct']; $this->me['struct'] = $vals; return 1; } /** * @return void */ function dump($ar) { reset($ar); foreach ($ar as $key => $val) { echo "$key => $val
"; if ($key == 'array') { foreach ($val as $key2 => $val2) { echo "-- $key2 => $val2
"; } } } } /** * @return string the data type of the current value */ function kindOf() { switch ($this->mytype) { case 3: return 'struct'; case 2: return 'array'; case 1: return 'scalar'; default: return 'undef'; } } /** * @return string the data in XML format */ function serializedata($typ, $val) { $rs = ''; if (!array_key_exists($typ, $GLOBALS['XML_RPC_Types'])) { // XXX // need some way to report this error return; } switch ($GLOBALS['XML_RPC_Types'][$typ]) { case 3: // struct $rs .= "\n"; reset($val); foreach ($val as $key2 => $val2) { $rs .= "" . htmlspecialchars($key2) . "\n"; $rs .= $this->serializeval($val2); $rs .= "\n"; } $rs .= ''; break; case 2: // array $rs .= "\n\n"; foreach ($val as $value) { $rs .= $this->serializeval($value); } $rs .= "\n"; break; case 1: switch ($typ) { case $GLOBALS['XML_RPC_Base64']: $rs .= "<${typ}>" . base64_encode($val) . ""; break; case $GLOBALS['XML_RPC_Boolean']: $rs .= "<${typ}>" . ($val ? '1' : '0') . ""; break; case $GLOBALS['XML_RPC_String']: $rs .= "<${typ}>" . htmlspecialchars($val). ""; break; default: $rs .= "<${typ}>${val}"; } } return $rs; } /** * @return string the data in XML format */ function serialize() { return $this->serializeval($this); } /** * @return string the data in XML format */ function serializeval($o) { if (!is_object($o) || empty($o->me) || !is_array($o->me)) { return ''; } $ar = $o->me; reset($ar); list($typ, $val) = each($ar); return '' . $this->serializedata($typ, $val) . "\n"; } /** * @return mixed the contents of the element requested */ function structmem($m) { return $this->me['struct'][$m]; } /** * @return void */ function structreset() { reset($this->me['struct']); } /** * @return the key/value pair of the struct's current element */ function structeach() { return each($this->me['struct']); } /** * @return mixed the current value */ function getval() { // UNSTABLE reset($this->me); $b = current($this->me); // contributed by I Sofer, 2001-03-24 // add support for nested arrays to scalarval // i've created a new method here, so as to // preserve back compatibility if (is_array($b)) { foreach ($b as $id => $cont) { $b[$id] = $cont->scalarval(); } } // add support for structures directly encoding php objects if (is_object($b)) { $t = get_object_vars($b); foreach ($t as $id => $cont) { $t[$id] = $cont->scalarval(); } foreach ($t as $id => $cont) { $b->$id = $cont; } } // end contrib return $b; } /** * @return mixed the current element's scalar value. If the value is * not scalar, FALSE is returned. */ function scalarval() { reset($this->me); $v = current($this->me); if (!is_scalar($v)) { $v = false; } return $v; } /** * @return string */ function scalartyp() { reset($this->me); $a = key($this->me); if ($a == $GLOBALS['XML_RPC_I4']) { $a = $GLOBALS['XML_RPC_Int']; } return $a; } /** * @return mixed the struct's current element */ function arraymem($m) { return $this->me['array'][$m]; } /** * @return int the number of elements in the array */ function arraysize() { reset($this->me); list($a, $b) = each($this->me); return sizeof($b); } /** * Determines if the item submitted is an XML_RPC_Value object * * @param mixed $val the variable to be evaluated * * @return bool TRUE if the item is an XML_RPC_Value object * * @static * @since Method available since Release 1.3.0 */ function isValue($val) { return (strtolower(get_class($val)) == 'xml_rpc_value'); } } /** * Return an ISO8601 encoded string * * While timezones ought to be supported, the XML-RPC spec says: * * "Don't assume a timezone. It should be specified by the server in its * documentation what assumptions it makes about timezones." * * This routine always assumes localtime unless $utc is set to 1, in which * case UTC is assumed and an adjustment for locale is made when encoding. * * @return string the formatted date */ function XML_RPC_iso8601_encode($timet, $utc = 0) { if (!$utc) { $t = strftime('%Y%m%dT%H:%M:%S', $timet); } else { if (function_exists('gmstrftime')) { // gmstrftime doesn't exist in some versions // of PHP $t = gmstrftime('%Y%m%dT%H:%M:%S', $timet); } else { $t = strftime('%Y%m%dT%H:%M:%S', $timet - date('Z')); } } return $t; } /** * Convert a datetime string into a Unix timestamp * * While timezones ought to be supported, the XML-RPC spec says: * * "Don't assume a timezone. It should be specified by the server in its * documentation what assumptions it makes about timezones." * * This routine always assumes localtime unless $utc is set to 1, in which * case UTC is assumed and an adjustment for locale is made when encoding. * * @return int the unix timestamp of the date submitted */ function XML_RPC_iso8601_decode($idate, $utc = 0) { $t = 0; if (preg_match('@([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})@', $idate, $regs)) { if ($utc) { $t = gmmktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]); } else { $t = mktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]); } } return $t; } /** * Converts an XML_RPC_Value object into native PHP types * * @param object $XML_RPC_val the XML_RPC_Value object to decode * * @return mixed the PHP values */ function XML_RPC_decode($XML_RPC_val) { $kind = $XML_RPC_val->kindOf(); if ($kind == 'scalar') { return $XML_RPC_val->scalarval(); } elseif ($kind == 'array') { $size = $XML_RPC_val->arraysize(); $arr = array(); for ($i = 0; $i < $size; $i++) { $arr[] = XML_RPC_decode($XML_RPC_val->arraymem($i)); } return $arr; } elseif ($kind == 'struct') { $XML_RPC_val->structreset(); $arr = array(); while (list($key, $value) = $XML_RPC_val->structeach()) { $arr[$key] = XML_RPC_decode($value); } return $arr; } } /** * Converts native PHP types into an XML_RPC_Value object * * @param mixed $php_val the PHP value or variable you want encoded * * @return object the XML_RPC_Value object */ function XML_RPC_encode($php_val) { $type = gettype($php_val); $XML_RPC_val = new XML_RPC_Value; switch ($type) { case 'array': if (empty($php_val)) { $XML_RPC_val->addArray($php_val); break; } $tmp = array_diff(array_keys($php_val), range(0, count($php_val)-1)); if (empty($tmp)) { $arr = array(); foreach ($php_val as $k => $v) { $arr[$k] = XML_RPC_encode($v); } $XML_RPC_val->addArray($arr); break; } // fall though if it's not an enumerated array case 'object': $arr = array(); foreach ($php_val as $k => $v) { $arr[$k] = XML_RPC_encode($v); } $XML_RPC_val->addStruct($arr); break; case 'integer': $XML_RPC_val->addScalar($php_val, $GLOBALS['XML_RPC_Int']); break; case 'double': $XML_RPC_val->addScalar($php_val, $GLOBALS['XML_RPC_Double']); break; case 'string': case 'NULL': if (preg_match('@^[0-9]{8}\T{1}[0-9]{2}\:[0-9]{2}\:[0-9]{2}$@', $php_val)) { $XML_RPC_val->addScalar($php_val, $GLOBALS['XML_RPC_DateTime']); } elseif ($GLOBALS['XML_RPC_auto_base64'] && preg_match("@[^ -~\t\r\n]@", $php_val)) { // Characters other than alpha-numeric, punctuation, SP, TAB, // LF and CR break the XML parser, encode value via Base 64. $XML_RPC_val->addScalar($php_val, $GLOBALS['XML_RPC_Base64']); } else { $XML_RPC_val->addScalar($php_val, $GLOBALS['XML_RPC_String']); } break; case 'boolean': // Add support for encoding/decoding of booleans, since they // are supported in PHP // by $XML_RPC_val->addScalar($php_val, $GLOBALS['XML_RPC_Boolean']); break; case 'unknown type': default: $XML_RPC_val = false; } return $XML_RPC_val; } /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * c-hanging-comment-ender-p: nil * End: */ ?> PKu]P'hB&&Mail.phpnu[ * @copyright 1997-2017 Chuck Hagenbuch * @license http://opensource.org/licenses/BSD-3-Clause New BSD License * @version CVS: $Id$ * @link http://pear.php.net/package/Mail/ */ require_once 'PEAR.php'; /** * PEAR's Mail:: interface. Defines the interface for implementing * mailers under the PEAR hierarchy, and provides supporting functions * useful in multiple mailer backends. * * @version $Revision$ * @package Mail */ class Mail { /** * Line terminator used for separating header lines. * @var string */ public $sep = "\r\n"; /** * Provides an interface for generating Mail:: objects of various * types * * @param string $driver The kind of Mail:: object to instantiate. * @param array $params The parameters to pass to the Mail:: object. * * @return object Mail a instance of the driver class or if fails a PEAR Error */ public static function factory($driver, $params = array()) { $driver = strtolower($driver); @include_once 'Mail/' . $driver . '.php'; $class = 'Mail_' . $driver; if (class_exists($class)) { $mailer = new $class($params); return $mailer; } else { return PEAR::raiseError('Unable to find class for driver ' . $driver); } } /** * Implements Mail::send() function using php's built-in mail() * command. * * @param mixed $recipients Either a comma-seperated list of recipients * (RFC822 compliant), or an array of recipients, * each RFC822 valid. This may contain recipients not * specified in the headers, for Bcc:, resending * messages, etc. * * @param array $headers The array of headers to send with the mail, in an * associative array, where the array key is the * header name (ie, 'Subject'), and the array value * is the header value (ie, 'test'). The header * produced from those values would be 'Subject: * test'. * * @param string $body The full text of the message body, including any * Mime parts, etc. * * @return mixed Returns true on success, or a PEAR_Error * containing a descriptive error message on * failure. * * @deprecated use Mail_mail::send instead */ public function send($recipients, $headers, $body) { if (!is_array($headers)) { return PEAR::raiseError('$headers must be an array'); } $result = $this->_sanitizeHeaders($headers); if (is_a($result, 'PEAR_Error')) { return $result; } // if we're passed an array of recipients, implode it. if (is_array($recipients)) { $recipients = implode(', ', $recipients); } // get the Subject out of the headers array so that we can // pass it as a seperate argument to mail(). $subject = ''; if (isset($headers['Subject'])) { $subject = $headers['Subject']; unset($headers['Subject']); } // flatten the headers out. list(, $text_headers) = Mail::prepareHeaders($headers); return mail($recipients, $subject, $body, $text_headers); } /** * Sanitize an array of mail headers by removing any additional header * strings present in a legitimate header's value. The goal of this * filter is to prevent mail injection attacks. * * @param array $headers The associative array of headers to sanitize. */ protected function _sanitizeHeaders(&$headers) { foreach ($headers as $key => $value) { $headers[$key] = preg_replace('=((||0x0A/%0A|0x0D/%0D|\\n|\\r)\S).*=i', null, $value); } } /** * Take an array of mail headers and return a string containing * text usable in sending a message. * * @param array $headers The array of headers to prepare, in an associative * array, where the array key is the header name (ie, * 'Subject'), and the array value is the header * value (ie, 'test'). The header produced from those * values would be 'Subject: test'. * * @return mixed Returns false if it encounters a bad address, * otherwise returns an array containing two * elements: Any From: address found in the headers, * and the plain text version of the headers. */ protected function prepareHeaders($headers) { $lines = array(); $from = null; foreach ($headers as $key => $value) { if (strcasecmp($key, 'From') === 0) { include_once 'Mail/RFC822.php'; $parser = new Mail_RFC822(); $addresses = $parser->parseAddressList($value, 'localhost', false); if (is_a($addresses, 'PEAR_Error')) { return $addresses; } $from = $addresses[0]->mailbox . '@' . $addresses[0]->host; // Reject envelope From: addresses with spaces. if (strstr($from, ' ')) { return false; } $lines[] = $key . ': ' . $value; } elseif (strcasecmp($key, 'Received') === 0) { $received = array(); if (is_array($value)) { foreach ($value as $line) { $received[] = $key . ': ' . $line; } } else { $received[] = $key . ': ' . $value; } // Put Received: headers at the top. Spam detectors often // flag messages with Received: headers after the Subject: // as spam. $lines = array_merge($received, $lines); } else { // If $value is an array (i.e., a list of addresses), convert // it to a comma-delimited string of its elements (addresses). if (is_array($value)) { $value = implode(', ', $value); } $lines[] = $key . ': ' . $value; } } return array($from, join($this->sep, $lines)); } /** * Take a set of recipients and parse them, returning an array of * bare addresses (forward paths) that can be passed to sendmail * or an smtp server with the rcpt to: command. * * @param mixed Either a comma-seperated list of recipients * (RFC822 compliant), or an array of recipients, * each RFC822 valid. * * @return mixed An array of forward paths (bare addresses) or a PEAR_Error * object if the address list could not be parsed. */ protected function parseRecipients($recipients) { include_once 'Mail/RFC822.php'; // if we're passed an array, assume addresses are valid and // implode them before parsing. if (is_array($recipients)) { $recipients = implode(', ', $recipients); } // Parse recipients, leaving out all personal info. This is // for smtp recipients, etc. All relevant personal information // should already be in the headers. $Mail_RFC822 = new Mail_RFC822(); $addresses = $Mail_RFC822->parseAddressList($recipients, 'localhost', false); // If parseAddressList() returned a PEAR_Error object, just return it. if (is_a($addresses, 'PEAR_Error')) { return $addresses; } $recipients = array(); if (is_array($addresses)) { foreach ($addresses as $ob) { $recipients[] = $ob->mailbox . '@' . $ob->host; } } return $recipients; } } PKu]U  PEAR/Packager.phpnu[ * @author Tomas V. V. Cox * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 0.1 */ /** * base class */ require_once 'PEAR/Common.php'; require_once 'PEAR/PackageFile.php'; require_once 'System.php'; /** * Administration class used to make a PEAR release tarball. * * @category pear * @package PEAR * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 0.1 */ class PEAR_Packager extends PEAR_Common { /** * @var PEAR_Registry */ var $_registry; function package($pkgfile = null, $compress = true, $pkg2 = null) { // {{{ validate supplied package.xml file if (empty($pkgfile)) { $pkgfile = 'package.xml'; } PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); $pkg = new PEAR_PackageFile($this->config, $this->debug); $pf = &$pkg->fromPackageFile($pkgfile, PEAR_VALIDATE_NORMAL); $main = &$pf; PEAR::staticPopErrorHandling(); if (PEAR::isError($pf)) { if (is_array($pf->getUserInfo())) { foreach ($pf->getUserInfo() as $error) { $this->log(0, 'Error: ' . $error['message']); } } $this->log(0, $pf->getMessage()); return $this->raiseError("Cannot package, errors in package file"); } foreach ($pf->getValidationWarnings() as $warning) { $this->log(1, 'Warning: ' . $warning['message']); } // }}} if ($pkg2) { $this->log(0, 'Attempting to process the second package file'); PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); $pf2 = &$pkg->fromPackageFile($pkg2, PEAR_VALIDATE_NORMAL); PEAR::staticPopErrorHandling(); if (PEAR::isError($pf2)) { if (is_array($pf2->getUserInfo())) { foreach ($pf2->getUserInfo() as $error) { $this->log(0, 'Error: ' . $error['message']); } } $this->log(0, $pf2->getMessage()); return $this->raiseError("Cannot package, errors in second package file"); } foreach ($pf2->getValidationWarnings() as $warning) { $this->log(1, 'Warning: ' . $warning['message']); } if ($pf2->getPackagexmlVersion() == '2.0' || $pf2->getPackagexmlVersion() == '2.1' ) { $main = &$pf2; $other = &$pf; } else { $main = &$pf; $other = &$pf2; } if ($main->getPackagexmlVersion() != '2.0' && $main->getPackagexmlVersion() != '2.1') { return PEAR::raiseError('Error: cannot package two package.xml version 1.0, can ' . 'only package together a package.xml 1.0 and package.xml 2.0'); } if ($other->getPackagexmlVersion() != '1.0') { return PEAR::raiseError('Error: cannot package two package.xml version 2.0, can ' . 'only package together a package.xml 1.0 and package.xml 2.0'); } } $main->setLogger($this); if (!$main->validate(PEAR_VALIDATE_PACKAGING)) { foreach ($main->getValidationWarnings() as $warning) { $this->log(0, 'Error: ' . $warning['message']); } return $this->raiseError("Cannot package, errors in package"); } foreach ($main->getValidationWarnings() as $warning) { $this->log(1, 'Warning: ' . $warning['message']); } if ($pkg2) { $other->setLogger($this); $a = false; if (!$other->validate(PEAR_VALIDATE_NORMAL) || $a = !$main->isEquivalent($other)) { foreach ($other->getValidationWarnings() as $warning) { $this->log(0, 'Error: ' . $warning['message']); } foreach ($main->getValidationWarnings() as $warning) { $this->log(0, 'Error: ' . $warning['message']); } if ($a) { return $this->raiseError('The two package.xml files are not equivalent!'); } return $this->raiseError("Cannot package, errors in package"); } foreach ($other->getValidationWarnings() as $warning) { $this->log(1, 'Warning: ' . $warning['message']); } $gen = &$main->getDefaultGenerator(); $tgzfile = $gen->toTgz2($this, $other, $compress); if (PEAR::isError($tgzfile)) { return $tgzfile; } $dest_package = basename($tgzfile); $pkgdir = dirname($pkgfile); // TAR the Package ------------------------------------------- $this->log(1, "Package $dest_package done"); if (file_exists("$pkgdir/CVS/Root")) { $cvsversion = preg_replace('/[^a-z0-9]/i', '_', $pf->getVersion()); $cvstag = "RELEASE_$cvsversion"; $this->log(1, 'Tag the released code with "pear cvstag ' . $main->getPackageFile() . '"'); $this->log(1, "(or set the CVS tag $cvstag by hand)"); } elseif (file_exists("$pkgdir/.svn")) { $svnversion = preg_replace('/[^a-z0-9]/i', '.', $pf->getVersion()); $svntag = $pf->getName() . "-$svnversion"; $this->log(1, 'Tag the released code with "pear svntag ' . $main->getPackageFile() . '"'); $this->log(1, "(or set the SVN tag $svntag by hand)"); } } else { // this branch is executed for single packagefile packaging $gen = &$pf->getDefaultGenerator(); $tgzfile = $gen->toTgz($this, $compress); if (PEAR::isError($tgzfile)) { $this->log(0, $tgzfile->getMessage()); return $this->raiseError("Cannot package, errors in package"); } $dest_package = basename($tgzfile); $pkgdir = dirname($pkgfile); // TAR the Package ------------------------------------------- $this->log(1, "Package $dest_package done"); if (file_exists("$pkgdir/CVS/Root")) { $cvsversion = preg_replace('/[^a-z0-9]/i', '_', $pf->getVersion()); $cvstag = "RELEASE_$cvsversion"; $this->log(1, "Tag the released code with `pear cvstag $pkgfile'"); $this->log(1, "(or set the CVS tag $cvstag by hand)"); } elseif (file_exists("$pkgdir/.svn")) { $svnversion = preg_replace('/[^a-z0-9]/i', '.', $pf->getVersion()); $svntag = $pf->getName() . "-$svnversion"; $this->log(1, "Tag the released code with `pear svntag $pkgfile'"); $this->log(1, "(or set the SVN tag $svntag by hand)"); } } return $dest_package; } }PKu]OWH H PEAR/PackageFile/Parser/v2.phpnu[ * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ /** * base xml parser class */ require_once 'PEAR/XMLParser.php'; require_once 'PEAR/PackageFile/v2.php'; /** * Parser for package.xml version 2.0 * @category pear * @package PEAR * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: @PEAR-VER@ * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ class PEAR_PackageFile_Parser_v2 extends PEAR_XMLParser { var $_config; var $_logger; var $_registry; function setConfig(&$c) { $this->_config = &$c; $this->_registry = &$c->getRegistry(); } function setLogger(&$l) { $this->_logger = &$l; } /** * Unindent given string * * @param string $str The string that has to be unindented. * @return string * @access private */ function _unIndent($str) { // remove leading newlines $str = preg_replace('/^[\r\n]+/', '', $str); // find whitespace at the beginning of the first line $indent_len = strspn($str, " \t"); $indent = substr($str, 0, $indent_len); $data = ''; // remove the same amount of whitespace from following lines foreach (explode("\n", $str) as $line) { if (substr($line, 0, $indent_len) == $indent) { $data .= substr($line, $indent_len) . "\n"; } else { $data .= $line . "\n"; } } return $data; } /** * post-process data * * @param string $data * @param string $element element name */ function postProcess($data, $element) { if ($element == 'notes') { return trim($this->_unIndent($data)); } return trim($data); } /** * @param string * @param string file name of the package.xml * @param string|false name of the archive this package.xml came from, if any * @param string class name to instantiate and return. This must be PEAR_PackageFile_v2 or * a subclass * @return PEAR_PackageFile_v2 */ function parse($data, $file = null, $archive = false, $class = 'PEAR_PackageFile_v2') { if (PEAR::isError($err = parent::parse($data))) { return $err; } $ret = new $class; $ret->encoding = $this->encoding; $ret->setConfig($this->_config); if (isset($this->_logger)) { $ret->setLogger($this->_logger); } $ret->fromArray($this->_unserializedData); $ret->setPackagefile($file, $archive); return $ret; } }PKu]_=@@PEAR/PackageFile/Parser/v1.phpnu[ * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ /** * package.xml abstraction class */ require_once 'PEAR/PackageFile/v1.php'; /** * Parser for package.xml version 1.0 * @category pear * @package PEAR * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: @PEAR-VER@ * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ class PEAR_PackageFile_Parser_v1 { var $_registry; var $_config; var $_logger; /** * BC hack to allow PEAR_Common::infoFromString() to sort of * work with the version 2.0 format - there's no filelist though * @param PEAR_PackageFile_v2 */ function fromV2($packagefile) { $info = $packagefile->getArray(true); $ret = new PEAR_PackageFile_v1; $ret->fromArray($info['old']); } function setConfig(&$c) { $this->_config = &$c; $this->_registry = &$c->getRegistry(); } function setLogger(&$l) { $this->_logger = &$l; } /** * @param string contents of package.xml file, version 1.0 * @return bool success of parsing */ function &parse($data, $file, $archive = false) { if (!extension_loaded('xml')) { return PEAR::raiseError('Cannot create xml parser for parsing package.xml, no xml extension'); } $xp = xml_parser_create(); if (!$xp) { $a = &PEAR::raiseError('Cannot create xml parser for parsing package.xml'); return $a; } xml_set_object($xp, $this); xml_set_element_handler($xp, '_element_start_1_0', '_element_end_1_0'); xml_set_character_data_handler($xp, '_pkginfo_cdata_1_0'); xml_parser_set_option($xp, XML_OPTION_CASE_FOLDING, false); $this->element_stack = array(); $this->_packageInfo = array('provides' => array()); $this->current_element = false; unset($this->dir_install); $this->_packageInfo['filelist'] = array(); $this->filelist =& $this->_packageInfo['filelist']; $this->dir_names = array(); $this->in_changelog = false; $this->d_i = 0; $this->cdata = ''; $this->_isValid = true; if (!xml_parse($xp, $data, 1)) { $code = xml_get_error_code($xp); $line = xml_get_current_line_number($xp); xml_parser_free($xp); $a = PEAR::raiseError(sprintf("XML error: %s at line %d", $str = xml_error_string($code), $line), 2); return $a; } xml_parser_free($xp); $pf = new PEAR_PackageFile_v1; $pf->setConfig($this->_config); if (isset($this->_logger)) { $pf->setLogger($this->_logger); } $pf->setPackagefile($file, $archive); $pf->fromArray($this->_packageInfo); return $pf; } // {{{ _unIndent() /** * Unindent given string * * @param string $str The string that has to be unindented. * @return string * @access private */ function _unIndent($str) { // remove leading newlines $str = preg_replace('/^[\r\n]+/', '', $str); // find whitespace at the beginning of the first line $indent_len = strspn($str, " \t"); $indent = substr($str, 0, $indent_len); $data = ''; // remove the same amount of whitespace from following lines foreach (explode("\n", $str) as $line) { if (substr($line, 0, $indent_len) == $indent) { $data .= substr($line, $indent_len) . "\n"; } elseif (trim(substr($line, 0, $indent_len))) { $data .= ltrim($line); } } return $data; } // Support for package DTD v1.0: // {{{ _element_start_1_0() /** * XML parser callback for ending elements. Used for version 1.0 * packages. * * @param resource $xp XML parser resource * @param string $name name of ending element * * @return void * * @access private */ function _element_start_1_0($xp, $name, $attribs) { array_push($this->element_stack, $name); $this->current_element = $name; $spos = sizeof($this->element_stack) - 2; $this->prev_element = ($spos >= 0) ? $this->element_stack[$spos] : ''; $this->current_attributes = $attribs; $this->cdata = ''; switch ($name) { case 'dir': if ($this->in_changelog) { break; } if (array_key_exists('name', $attribs) && $attribs['name'] != '/') { $attribs['name'] = preg_replace(array('!\\\\+!', '!/+!'), array('/', '/'), $attribs['name']); if (strrpos($attribs['name'], '/') === strlen($attribs['name']) - 1) { $attribs['name'] = substr($attribs['name'], 0, strlen($attribs['name']) - 1); } if (strpos($attribs['name'], '/') === 0) { $attribs['name'] = substr($attribs['name'], 1); } $this->dir_names[] = $attribs['name']; } if (isset($attribs['baseinstalldir'])) { $this->dir_install = $attribs['baseinstalldir']; } if (isset($attribs['role'])) { $this->dir_role = $attribs['role']; } break; case 'file': if ($this->in_changelog) { break; } if (isset($attribs['name'])) { $path = ''; if (count($this->dir_names)) { foreach ($this->dir_names as $dir) { $path .= $dir . '/'; } } $path .= preg_replace(array('!\\\\+!', '!/+!'), array('/', '/'), $attribs['name']); unset($attribs['name']); $this->current_path = $path; $this->filelist[$path] = $attribs; // Set the baseinstalldir only if the file don't have this attrib if (!isset($this->filelist[$path]['baseinstalldir']) && isset($this->dir_install)) { $this->filelist[$path]['baseinstalldir'] = $this->dir_install; } // Set the Role if (!isset($this->filelist[$path]['role']) && isset($this->dir_role)) { $this->filelist[$path]['role'] = $this->dir_role; } } break; case 'replace': if (!$this->in_changelog) { $this->filelist[$this->current_path]['replacements'][] = $attribs; } break; case 'maintainers': $this->_packageInfo['maintainers'] = array(); $this->m_i = 0; // maintainers array index break; case 'maintainer': // compatibility check if (!isset($this->_packageInfo['maintainers'])) { $this->_packageInfo['maintainers'] = array(); $this->m_i = 0; } $this->_packageInfo['maintainers'][$this->m_i] = array(); $this->current_maintainer =& $this->_packageInfo['maintainers'][$this->m_i]; break; case 'changelog': $this->_packageInfo['changelog'] = array(); $this->c_i = 0; // changelog array index $this->in_changelog = true; break; case 'release': if ($this->in_changelog) { $this->_packageInfo['changelog'][$this->c_i] = array(); $this->current_release = &$this->_packageInfo['changelog'][$this->c_i]; } else { $this->current_release = &$this->_packageInfo; } break; case 'deps': if (!$this->in_changelog) { $this->_packageInfo['release_deps'] = array(); } break; case 'dep': // dependencies array index if (!$this->in_changelog) { $this->d_i++; isset($attribs['type']) ? ($attribs['type'] = strtolower($attribs['type'])) : false; $this->_packageInfo['release_deps'][$this->d_i] = $attribs; } break; case 'configureoptions': if (!$this->in_changelog) { $this->_packageInfo['configure_options'] = array(); } break; case 'configureoption': if (!$this->in_changelog) { $this->_packageInfo['configure_options'][] = $attribs; } break; case 'provides': if (empty($attribs['type']) || empty($attribs['name'])) { break; } $attribs['explicit'] = true; $this->_packageInfo['provides']["$attribs[type];$attribs[name]"] = $attribs; break; case 'package' : if (isset($attribs['version'])) { $this->_packageInfo['xsdversion'] = trim($attribs['version']); } else { $this->_packageInfo['xsdversion'] = '1.0'; } if (isset($attribs['packagerversion'])) { $this->_packageInfo['packagerversion'] = $attribs['packagerversion']; } break; } } // }}} // {{{ _element_end_1_0() /** * XML parser callback for ending elements. Used for version 1.0 * packages. * * @param resource $xp XML parser resource * @param string $name name of ending element * * @return void * * @access private */ function _element_end_1_0($xp, $name) { $data = trim($this->cdata); switch ($name) { case 'name': switch ($this->prev_element) { case 'package': $this->_packageInfo['package'] = $data; break; case 'maintainer': $this->current_maintainer['name'] = $data; break; } break; case 'extends' : $this->_packageInfo['extends'] = $data; break; case 'summary': $this->_packageInfo['summary'] = $data; break; case 'description': $data = $this->_unIndent($this->cdata); $this->_packageInfo['description'] = $data; break; case 'user': $this->current_maintainer['handle'] = $data; break; case 'email': $this->current_maintainer['email'] = $data; break; case 'role': $this->current_maintainer['role'] = $data; break; case 'version': if ($this->in_changelog) { $this->current_release['version'] = $data; } else { $this->_packageInfo['version'] = $data; } break; case 'date': if ($this->in_changelog) { $this->current_release['release_date'] = $data; } else { $this->_packageInfo['release_date'] = $data; } break; case 'notes': // try to "de-indent" release notes in case someone // has been over-indenting their xml ;-) // Trim only on the right side $data = rtrim($this->_unIndent($this->cdata)); if ($this->in_changelog) { $this->current_release['release_notes'] = $data; } else { $this->_packageInfo['release_notes'] = $data; } break; case 'warnings': if ($this->in_changelog) { $this->current_release['release_warnings'] = $data; } else { $this->_packageInfo['release_warnings'] = $data; } break; case 'state': if ($this->in_changelog) { $this->current_release['release_state'] = $data; } else { $this->_packageInfo['release_state'] = $data; } break; case 'license': if ($this->in_changelog) { $this->current_release['release_license'] = $data; } else { $this->_packageInfo['release_license'] = $data; } break; case 'dep': if ($data && !$this->in_changelog) { $this->_packageInfo['release_deps'][$this->d_i]['name'] = $data; } break; case 'dir': if ($this->in_changelog) { break; } array_pop($this->dir_names); break; case 'file': if ($this->in_changelog) { break; } if ($data) { $path = ''; if (count($this->dir_names)) { foreach ($this->dir_names as $dir) { $path .= $dir . '/'; } } $path .= $data; $this->filelist[$path] = $this->current_attributes; // Set the baseinstalldir only if the file don't have this attrib if (!isset($this->filelist[$path]['baseinstalldir']) && isset($this->dir_install)) { $this->filelist[$path]['baseinstalldir'] = $this->dir_install; } // Set the Role if (!isset($this->filelist[$path]['role']) && isset($this->dir_role)) { $this->filelist[$path]['role'] = $this->dir_role; } } break; case 'maintainer': if (empty($this->_packageInfo['maintainers'][$this->m_i]['role'])) { $this->_packageInfo['maintainers'][$this->m_i]['role'] = 'lead'; } $this->m_i++; break; case 'release': if ($this->in_changelog) { $this->c_i++; } break; case 'changelog': $this->in_changelog = false; break; } array_pop($this->element_stack); $spos = sizeof($this->element_stack) - 1; $this->current_element = ($spos > 0) ? $this->element_stack[$spos] : ''; $this->cdata = ''; } // }}} // {{{ _pkginfo_cdata_1_0() /** * XML parser callback for character data. Used for version 1.0 * packages. * * @param resource $xp XML parser resource * @param string $name character data * * @return void * * @access private */ function _pkginfo_cdata_1_0($xp, $data) { if (isset($this->cdata)) { $this->cdata .= $data; } } // }}} } ?>PKu]wv@@PEAR/PackageFile/v2.phpnu[ * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ /** * For error handling */ require_once 'PEAR/ErrorStack.php'; /** * @category pear * @package PEAR * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ class PEAR_PackageFile_v2 { /** * Parsed package information * @var array * @access private */ var $_packageInfo = array(); /** * path to package .tgz or false if this is a local/extracted package.xml * @var string|false * @access private */ var $_archiveFile; /** * path to package .xml or false if this is an abstract parsed-from-string xml * @var string|false * @access private */ var $_packageFile; /** * This is used by file analysis routines to log progress information * @var PEAR_Common * @access protected */ var $_logger; /** * This is set to the highest validation level that has been validated * * If the package.xml is invalid or unknown, this is set to 0. If * normal validation has occurred, this is set to PEAR_VALIDATE_NORMAL. If * downloading/installation validation has occurred it is set to PEAR_VALIDATE_DOWNLOADING * or INSTALLING, and so on up to PEAR_VALIDATE_PACKAGING. This allows validation * "caching" to occur, which is particularly important for package validation, so * that PHP files are not validated twice * @var int * @access private */ var $_isValid = 0; /** * True if the filelist has been validated * @param bool */ var $_filesValid = false; /** * @var PEAR_Registry * @access protected */ var $_registry; /** * @var PEAR_Config * @access protected */ var $_config; /** * Optional Dependency group requested for installation * @var string * @access private */ var $_requestedGroup = false; /** * @var PEAR_ErrorStack * @access protected */ var $_stack; /** * Namespace prefix used for tasks in this package.xml - use tasks: whenever possible */ var $_tasksNs; /** * Determines whether this packagefile was initialized only with partial package info * * If this package file was constructed via parsing REST, it will only contain * * - package name * - channel name * - dependencies * @var boolean * @access private */ var $_incomplete = true; /** * @var PEAR_PackageFile_v2_Validator */ var $_v2Validator; /** * The constructor merely sets up the private error stack */ function __construct() { $this->_stack = new PEAR_ErrorStack('PEAR_PackageFile_v2', false, null); $this->_isValid = false; } /** * PHP 4 style constructor for backwards compatibility. * Used by PEAR_PackageFileManager2 */ public function PEAR_PackageFile_v2() { $this->__construct(); } /** * To make unit-testing easier * @param PEAR_Frontend_* * @param array options * @param PEAR_Config * @return PEAR_Downloader * @access protected */ function &getPEARDownloader(&$i, $o, &$c) { $z = new PEAR_Downloader($i, $o, $c); return $z; } /** * To make unit-testing easier * @param PEAR_Config * @param array options * @param array package name as returned from {@link PEAR_Registry::parsePackageName()} * @param int PEAR_VALIDATE_* constant * @return PEAR_Dependency2 * @access protected */ function &getPEARDependency2(&$c, $o, $p, $s = PEAR_VALIDATE_INSTALLING) { if (!class_exists('PEAR_Dependency2')) { require_once 'PEAR/Dependency2.php'; } $z = new PEAR_Dependency2($c, $o, $p, $s); return $z; } function getInstalledBinary() { return isset($this->_packageInfo['#binarypackage']) ? $this->_packageInfo['#binarypackage'] : false; } /** * Installation of source package has failed, attempt to download and install the * binary version of this package. * @param PEAR_Installer * @return array|false */ function installBinary(&$installer) { if (!OS_WINDOWS) { $a = false; return $a; } if ($this->getPackageType() == 'extsrc' || $this->getPackageType() == 'zendextsrc') { $releasetype = $this->getPackageType() . 'release'; if (!is_array($installer->getInstallPackages())) { $a = false; return $a; } foreach ($installer->getInstallPackages() as $p) { if ($p->isExtension($this->_packageInfo['providesextension'])) { if ($p->getPackageType() != 'extsrc' && $p->getPackageType() != 'zendextsrc') { $a = false; return $a; // the user probably downloaded it separately } } } if (isset($this->_packageInfo[$releasetype]['binarypackage'])) { $installer->log(0, 'Attempting to download binary version of extension "' . $this->_packageInfo['providesextension'] . '"'); $params = $this->_packageInfo[$releasetype]['binarypackage']; if (!is_array($params) || !isset($params[0])) { $params = array($params); } if (isset($this->_packageInfo['channel'])) { foreach ($params as $i => $param) { $params[$i] = array('channel' => $this->_packageInfo['channel'], 'package' => $param, 'version' => $this->getVersion()); } } $dl = &$this->getPEARDownloader($installer->ui, $installer->getOptions(), $installer->config); $verbose = $dl->config->get('verbose'); $dl->config->set('verbose', -1); foreach ($params as $param) { PEAR::pushErrorHandling(PEAR_ERROR_RETURN); $ret = $dl->download(array($param)); PEAR::popErrorHandling(); if (is_array($ret) && count($ret)) { break; } } $dl->config->set('verbose', $verbose); if (is_array($ret)) { if (count($ret) == 1) { $pf = $ret[0]->getPackageFile(); PEAR::pushErrorHandling(PEAR_ERROR_RETURN); $err = $installer->install($ret[0]); PEAR::popErrorHandling(); if (is_array($err)) { $this->_packageInfo['#binarypackage'] = $ret[0]->getPackage(); // "install" self, so all dependencies will work transparently $this->_registry->addPackage2($this); $installer->log(0, 'Download and install of binary extension "' . $this->_registry->parsedPackageNameToString( array('channel' => $pf->getChannel(), 'package' => $pf->getPackage()), true) . '" successful'); $a = array($ret[0], $err); return $a; } $installer->log(0, 'Download and install of binary extension "' . $this->_registry->parsedPackageNameToString( array('channel' => $pf->getChannel(), 'package' => $pf->getPackage()), true) . '" failed'); } } } } $a = false; return $a; } /** * @return string|false Extension name */ function getProvidesExtension() { if (in_array($this->getPackageType(), array('extsrc', 'extbin', 'zendextsrc', 'zendextbin'))) { if (isset($this->_packageInfo['providesextension'])) { return $this->_packageInfo['providesextension']; } } return false; } /** * @param string Extension name * @return bool */ function isExtension($extension) { if (in_array($this->getPackageType(), array('extsrc', 'extbin', 'zendextsrc', 'zendextbin'))) { return $this->_packageInfo['providesextension'] == $extension; } return false; } /** * Tests whether every part of the package.xml 1.0 is represented in * this package.xml 2.0 * @param PEAR_PackageFile_v1 * @return bool */ function isEquivalent($pf1) { if (!$pf1) { return true; } if ($this->getPackageType() == 'bundle') { return false; } $this->_stack->getErrors(true); if (!$pf1->validate(PEAR_VALIDATE_NORMAL)) { return false; } $pass = true; if ($pf1->getPackage() != $this->getPackage()) { $this->_differentPackage($pf1->getPackage()); $pass = false; } if ($pf1->getVersion() != $this->getVersion()) { $this->_differentVersion($pf1->getVersion()); $pass = false; } if (trim($pf1->getSummary()) != $this->getSummary()) { $this->_differentSummary($pf1->getSummary()); $pass = false; } if (preg_replace('/\s+/', '', $pf1->getDescription()) != preg_replace('/\s+/', '', $this->getDescription())) { $this->_differentDescription($pf1->getDescription()); $pass = false; } if ($pf1->getState() != $this->getState()) { $this->_differentState($pf1->getState()); $pass = false; } if (!strstr(preg_replace('/\s+/', '', $this->getNotes()), preg_replace('/\s+/', '', $pf1->getNotes()))) { $this->_differentNotes($pf1->getNotes()); $pass = false; } $mymaintainers = $this->getMaintainers(); $yourmaintainers = $pf1->getMaintainers(); for ($i1 = 0; $i1 < count($yourmaintainers); $i1++) { $reset = false; for ($i2 = 0; $i2 < count($mymaintainers); $i2++) { if ($mymaintainers[$i2]['handle'] == $yourmaintainers[$i1]['handle']) { if ($mymaintainers[$i2]['role'] != $yourmaintainers[$i1]['role']) { $this->_differentRole($mymaintainers[$i2]['handle'], $yourmaintainers[$i1]['role'], $mymaintainers[$i2]['role']); $pass = false; } if ($mymaintainers[$i2]['email'] != $yourmaintainers[$i1]['email']) { $this->_differentEmail($mymaintainers[$i2]['handle'], $yourmaintainers[$i1]['email'], $mymaintainers[$i2]['email']); $pass = false; } if ($mymaintainers[$i2]['name'] != $yourmaintainers[$i1]['name']) { $this->_differentName($mymaintainers[$i2]['handle'], $yourmaintainers[$i1]['name'], $mymaintainers[$i2]['name']); $pass = false; } unset($mymaintainers[$i2]); $mymaintainers = array_values($mymaintainers); unset($yourmaintainers[$i1]); $yourmaintainers = array_values($yourmaintainers); $reset = true; break; } } if ($reset) { $i1 = -1; } } $this->_unmatchedMaintainers($mymaintainers, $yourmaintainers); $filelist = $this->getFilelist(); foreach ($pf1->getFilelist() as $file => $atts) { if (!isset($filelist[$file])) { $this->_missingFile($file); $pass = false; } } return $pass; } function _differentPackage($package) { $this->_stack->push(__FUNCTION__, 'error', array('package' => $package, 'self' => $this->getPackage()), 'package.xml 1.0 package "%package%" does not match "%self%"'); } function _differentVersion($version) { $this->_stack->push(__FUNCTION__, 'error', array('version' => $version, 'self' => $this->getVersion()), 'package.xml 1.0 version "%version%" does not match "%self%"'); } function _differentState($state) { $this->_stack->push(__FUNCTION__, 'error', array('state' => $state, 'self' => $this->getState()), 'package.xml 1.0 state "%state%" does not match "%self%"'); } function _differentRole($handle, $role, $selfrole) { $this->_stack->push(__FUNCTION__, 'error', array('handle' => $handle, 'role' => $role, 'self' => $selfrole), 'package.xml 1.0 maintainer "%handle%" role "%role%" does not match "%self%"'); } function _differentEmail($handle, $email, $selfemail) { $this->_stack->push(__FUNCTION__, 'error', array('handle' => $handle, 'email' => $email, 'self' => $selfemail), 'package.xml 1.0 maintainer "%handle%" email "%email%" does not match "%self%"'); } function _differentName($handle, $name, $selfname) { $this->_stack->push(__FUNCTION__, 'error', array('handle' => $handle, 'name' => $name, 'self' => $selfname), 'package.xml 1.0 maintainer "%handle%" name "%name%" does not match "%self%"'); } function _unmatchedMaintainers($my, $yours) { if ($my) { array_walk($my, function(&$i, $k) { $i = $i["handle"]; }); $this->_stack->push(__FUNCTION__, 'error', array('handles' => $my), 'package.xml 2.0 has unmatched extra maintainers "%handles%"'); } if ($yours) { array_walk($yours, function(&$i, $k) { $i = $i["handle"]; }); $this->_stack->push(__FUNCTION__, 'error', array('handles' => $yours), 'package.xml 1.0 has unmatched extra maintainers "%handles%"'); } } function _differentNotes($notes) { $truncnotes = strlen($notes) < 25 ? $notes : substr($notes, 0, 24) . '...'; $truncmynotes = strlen($this->getNotes()) < 25 ? $this->getNotes() : substr($this->getNotes(), 0, 24) . '...'; $this->_stack->push(__FUNCTION__, 'error', array('notes' => $truncnotes, 'self' => $truncmynotes), 'package.xml 1.0 release notes "%notes%" do not match "%self%"'); } function _differentSummary($summary) { $truncsummary = strlen($summary) < 25 ? $summary : substr($summary, 0, 24) . '...'; $truncmysummary = strlen($this->getsummary()) < 25 ? $this->getSummary() : substr($this->getsummary(), 0, 24) . '...'; $this->_stack->push(__FUNCTION__, 'error', array('summary' => $truncsummary, 'self' => $truncmysummary), 'package.xml 1.0 summary "%summary%" does not match "%self%"'); } function _differentDescription($description) { $truncdescription = trim(strlen($description) < 25 ? $description : substr($description, 0, 24) . '...'); $truncmydescription = trim(strlen($this->getDescription()) < 25 ? $this->getDescription() : substr($this->getdescription(), 0, 24) . '...'); $this->_stack->push(__FUNCTION__, 'error', array('description' => $truncdescription, 'self' => $truncmydescription), 'package.xml 1.0 description "%description%" does not match "%self%"'); } function _missingFile($file) { $this->_stack->push(__FUNCTION__, 'error', array('file' => $file), 'package.xml 1.0 file "%file%" is not present in '); } /** * WARNING - do not use this function unless you know what you're doing */ function setRawState($state) { if (!isset($this->_packageInfo['stability'])) { $this->_packageInfo['stability'] = array(); } $this->_packageInfo['stability']['release'] = $state; } /** * WARNING - do not use this function unless you know what you're doing */ function setRawCompatible($compatible) { $this->_packageInfo['compatible'] = $compatible; } /** * WARNING - do not use this function unless you know what you're doing */ function setRawPackage($package) { $this->_packageInfo['name'] = $package; } /** * WARNING - do not use this function unless you know what you're doing */ function setRawChannel($channel) { $this->_packageInfo['channel'] = $channel; } function setRequestedGroup($group) { $this->_requestedGroup = $group; } function getRequestedGroup() { if (isset($this->_requestedGroup)) { return $this->_requestedGroup; } return false; } /** * For saving in the registry. * * Set the last version that was installed * @param string */ function setLastInstalledVersion($version) { $this->_packageInfo['_lastversion'] = $version; } /** * @return string|false */ function getLastInstalledVersion() { if (isset($this->_packageInfo['_lastversion'])) { return $this->_packageInfo['_lastversion']; } return false; } /** * Determines whether this package.xml has post-install scripts or not * @return array|false */ function listPostinstallScripts() { $filelist = $this->getFilelist(); $contents = $this->getContents(); $contents = $contents['dir']['file']; if (!is_array($contents) || !isset($contents[0])) { $contents = array($contents); } $taskfiles = array(); foreach ($contents as $file) { $atts = $file['attribs']; unset($file['attribs']); if (count($file)) { $taskfiles[$atts['name']] = $file; } } $common = new PEAR_Common; $common->debug = $this->_config->get('verbose'); $this->_scripts = array(); $ret = array(); foreach ($taskfiles as $name => $tasks) { if (!isset($filelist[$name])) { // ignored files will not be in the filelist continue; } $atts = $filelist[$name]; foreach ($tasks as $tag => $raw) { $task = $this->getTask($tag); $task = new $task($this->_config, $common, PEAR_TASK_INSTALL); if ($task->isScript()) { $ret[] = $filelist[$name]['installed_as']; } } } if (count($ret)) { return $ret; } return false; } /** * Initialize post-install scripts for running * * This method can be used to detect post-install scripts, as the return value * indicates whether any exist * @return bool */ function initPostinstallScripts() { $filelist = $this->getFilelist(); $contents = $this->getContents(); $contents = $contents['dir']['file']; if (!is_array($contents) || !isset($contents[0])) { $contents = array($contents); } $taskfiles = array(); foreach ($contents as $file) { $atts = $file['attribs']; unset($file['attribs']); if (count($file)) { $taskfiles[$atts['name']] = $file; } } $common = new PEAR_Common; $common->debug = $this->_config->get('verbose'); $this->_scripts = array(); foreach ($taskfiles as $name => $tasks) { if (!isset($filelist[$name])) { // file was not installed due to installconditions continue; } $atts = $filelist[$name]; foreach ($tasks as $tag => $raw) { $taskname = $this->getTask($tag); $task = new $taskname($this->_config, $common, PEAR_TASK_INSTALL); if (!$task->isScript()) { continue; // scripts are only handled after installation } $lastversion = isset($this->_packageInfo['_lastversion']) ? $this->_packageInfo['_lastversion'] : null; $task->init($raw, $atts, $lastversion); $res = $task->startSession($this, $atts['installed_as'], null); if (!$res) { continue; // skip this file } if (PEAR::isError($res)) { return $res; } $this->_scripts[] = $task; } } if (count($this->_scripts)) { return true; } return false; } function runPostinstallScripts() { if ($this->initPostinstallScripts()) { $ui = &PEAR_Frontend::singleton(); if ($ui) { $ui->runPostinstallScripts($this->_scripts, $this); } } } /** * Convert a recursive set of and tags into a single tag with * tags. */ function flattenFilelist() { if (isset($this->_packageInfo['bundle'])) { return; } $filelist = array(); if (isset($this->_packageInfo['contents']['dir']['dir'])) { $this->_getFlattenedFilelist($filelist, $this->_packageInfo['contents']['dir']); if (!isset($filelist[1])) { $filelist = $filelist[0]; } $this->_packageInfo['contents']['dir']['file'] = $filelist; unset($this->_packageInfo['contents']['dir']['dir']); } else { // else already flattened but check for baseinstalldir propagation if (isset($this->_packageInfo['contents']['dir']['attribs']['baseinstalldir'])) { if (isset($this->_packageInfo['contents']['dir']['file'][0])) { foreach ($this->_packageInfo['contents']['dir']['file'] as $i => $file) { if (isset($file['attribs']['baseinstalldir'])) { continue; } $this->_packageInfo['contents']['dir']['file'][$i]['attribs']['baseinstalldir'] = $this->_packageInfo['contents']['dir']['attribs']['baseinstalldir']; } } else { if (!isset($this->_packageInfo['contents']['dir']['file']['attribs']['baseinstalldir'])) { $this->_packageInfo['contents']['dir']['file']['attribs']['baseinstalldir'] = $this->_packageInfo['contents']['dir']['attribs']['baseinstalldir']; } } } } } /** * @param array the final flattened file list * @param array the current directory being processed * @param string|false any recursively inherited baeinstalldir attribute * @param string private recursion variable * @return array * @access protected */ function _getFlattenedFilelist(&$files, $dir, $baseinstall = false, $path = '') { if (isset($dir['attribs']) && isset($dir['attribs']['baseinstalldir'])) { $baseinstall = $dir['attribs']['baseinstalldir']; } if (isset($dir['dir'])) { if (!isset($dir['dir'][0])) { $dir['dir'] = array($dir['dir']); } foreach ($dir['dir'] as $subdir) { if (!isset($subdir['attribs']) || !isset($subdir['attribs']['name'])) { $name = '*unknown*'; } else { $name = $subdir['attribs']['name']; } $newpath = empty($path) ? $name : $path . '/' . $name; $this->_getFlattenedFilelist($files, $subdir, $baseinstall, $newpath); } } if (isset($dir['file'])) { if (!isset($dir['file'][0])) { $dir['file'] = array($dir['file']); } foreach ($dir['file'] as $file) { $attrs = $file['attribs']; $name = $attrs['name']; if ($baseinstall && !isset($attrs['baseinstalldir'])) { $attrs['baseinstalldir'] = $baseinstall; } $attrs['name'] = empty($path) ? $name : $path . '/' . $name; $attrs['name'] = preg_replace(array('!\\\\+!', '!/+!'), array('/', '/'), $attrs['name']); $file['attribs'] = $attrs; $files[] = $file; } } } function setConfig(&$config) { $this->_config = &$config; $this->_registry = &$config->getRegistry(); } function setLogger(&$logger) { if (!is_object($logger) || !method_exists($logger, 'log')) { return PEAR::raiseError('Logger must be compatible with PEAR_Common::log'); } $this->_logger = &$logger; } /** * WARNING - do not use this function directly unless you know what you're doing */ function setDeps($deps) { $this->_packageInfo['dependencies'] = $deps; } /** * WARNING - do not use this function directly unless you know what you're doing */ function setCompatible($compat) { $this->_packageInfo['compatible'] = $compat; } function setPackagefile($file, $archive = false) { $this->_packageFile = $file; $this->_archiveFile = $archive ? $archive : $file; } /** * Wrapper to {@link PEAR_ErrorStack::getErrors()} * @param boolean determines whether to purge the error stack after retrieving * @return array */ function getValidationWarnings($purge = true) { return $this->_stack->getErrors($purge); } function getPackageFile() { return $this->_packageFile; } function getArchiveFile() { return $this->_archiveFile; } /** * Directly set the array that defines this packagefile * * WARNING: no validation. This should only be performed by internal methods * inside PEAR or by inputting an array saved from an existing PEAR_PackageFile_v2 * @param array */ function fromArray($pinfo) { unset($pinfo['old']); unset($pinfo['xsdversion']); // If the changelog isn't an array then it was passed in as an empty tag if (isset($pinfo['changelog']) && !is_array($pinfo['changelog'])) { unset($pinfo['changelog']); } $this->_incomplete = false; $this->_packageInfo = $pinfo; } function isIncomplete() { return $this->_incomplete; } /** * @return array */ function toArray($forreg = false) { if (!$this->validate(PEAR_VALIDATE_NORMAL)) { return false; } return $this->getArray($forreg); } function getArray($forReg = false) { if ($forReg) { $arr = $this->_packageInfo; $arr['old'] = array(); $arr['old']['version'] = $this->getVersion(); $arr['old']['release_date'] = $this->getDate(); $arr['old']['release_state'] = $this->getState(); $arr['old']['release_license'] = $this->getLicense(); $arr['old']['release_notes'] = $this->getNotes(); $arr['old']['release_deps'] = $this->getDeps(); $arr['old']['maintainers'] = $this->getMaintainers(); $arr['xsdversion'] = '2.0'; return $arr; } else { $info = $this->_packageInfo; unset($info['dirtree']); if (isset($info['_lastversion'])) { unset($info['_lastversion']); } if (isset($info['#binarypackage'])) { unset($info['#binarypackage']); } return $info; } } function packageInfo($field) { $arr = $this->getArray(true); if ($field == 'state') { return $arr['stability']['release']; } if ($field == 'api-version') { return $arr['version']['api']; } if ($field == 'api-state') { return $arr['stability']['api']; } if (isset($arr['old'][$field])) { if (!is_string($arr['old'][$field])) { return null; } return $arr['old'][$field]; } if (isset($arr[$field])) { if (!is_string($arr[$field])) { return null; } return $arr[$field]; } return null; } function getName() { return $this->getPackage(); } function getPackage() { if (isset($this->_packageInfo['name'])) { return $this->_packageInfo['name']; } return false; } function getChannel() { if (isset($this->_packageInfo['uri'])) { return '__uri'; } if (isset($this->_packageInfo['channel'])) { return strtolower($this->_packageInfo['channel']); } return false; } function getUri() { if (isset($this->_packageInfo['uri'])) { return $this->_packageInfo['uri']; } return false; } function getExtends() { if (isset($this->_packageInfo['extends'])) { return $this->_packageInfo['extends']; } return false; } function getSummary() { if (isset($this->_packageInfo['summary'])) { return $this->_packageInfo['summary']; } return false; } function getDescription() { if (isset($this->_packageInfo['description'])) { return $this->_packageInfo['description']; } return false; } function getMaintainers($raw = false) { if (!isset($this->_packageInfo['lead'])) { return false; } if ($raw) { $ret = array('lead' => $this->_packageInfo['lead']); (isset($this->_packageInfo['developer'])) ? $ret['developer'] = $this->_packageInfo['developer'] :null; (isset($this->_packageInfo['contributor'])) ? $ret['contributor'] = $this->_packageInfo['contributor'] :null; (isset($this->_packageInfo['helper'])) ? $ret['helper'] = $this->_packageInfo['helper'] :null; return $ret; } else { $ret = array(); $leads = isset($this->_packageInfo['lead'][0]) ? $this->_packageInfo['lead'] : array($this->_packageInfo['lead']); foreach ($leads as $lead) { $s = $lead; $s['handle'] = $s['user']; unset($s['user']); $s['role'] = 'lead'; $ret[] = $s; } if (isset($this->_packageInfo['developer'])) { $leads = isset($this->_packageInfo['developer'][0]) ? $this->_packageInfo['developer'] : array($this->_packageInfo['developer']); foreach ($leads as $maintainer) { $s = $maintainer; $s['handle'] = $s['user']; unset($s['user']); $s['role'] = 'developer'; $ret[] = $s; } } if (isset($this->_packageInfo['contributor'])) { $leads = isset($this->_packageInfo['contributor'][0]) ? $this->_packageInfo['contributor'] : array($this->_packageInfo['contributor']); foreach ($leads as $maintainer) { $s = $maintainer; $s['handle'] = $s['user']; unset($s['user']); $s['role'] = 'contributor'; $ret[] = $s; } } if (isset($this->_packageInfo['helper'])) { $leads = isset($this->_packageInfo['helper'][0]) ? $this->_packageInfo['helper'] : array($this->_packageInfo['helper']); foreach ($leads as $maintainer) { $s = $maintainer; $s['handle'] = $s['user']; unset($s['user']); $s['role'] = 'helper'; $ret[] = $s; } } return $ret; } return false; } function getLeads() { if (isset($this->_packageInfo['lead'])) { return $this->_packageInfo['lead']; } return false; } function getDevelopers() { if (isset($this->_packageInfo['developer'])) { return $this->_packageInfo['developer']; } return false; } function getContributors() { if (isset($this->_packageInfo['contributor'])) { return $this->_packageInfo['contributor']; } return false; } function getHelpers() { if (isset($this->_packageInfo['helper'])) { return $this->_packageInfo['helper']; } return false; } function setDate($date) { if (!isset($this->_packageInfo['date'])) { // ensure that the extends tag is set up in the right location $this->_packageInfo = $this->_insertBefore($this->_packageInfo, array('time', 'version', 'stability', 'license', 'notes', 'contents', 'compatible', 'dependencies', 'providesextension', 'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'), array(), 'date'); } $this->_packageInfo['date'] = $date; $this->_isValid = 0; } function setTime($time) { $this->_isValid = 0; if (!isset($this->_packageInfo['time'])) { // ensure that the time tag is set up in the right location $this->_packageInfo = $this->_insertBefore($this->_packageInfo, array('version', 'stability', 'license', 'notes', 'contents', 'compatible', 'dependencies', 'providesextension', 'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'), $time, 'time'); } $this->_packageInfo['time'] = $time; } function getDate() { if (isset($this->_packageInfo['date'])) { return $this->_packageInfo['date']; } return false; } function getTime() { if (isset($this->_packageInfo['time'])) { return $this->_packageInfo['time']; } return false; } /** * @param package|api version category to return */ function getVersion($key = 'release') { if (isset($this->_packageInfo['version'][$key])) { return $this->_packageInfo['version'][$key]; } return false; } function getStability() { if (isset($this->_packageInfo['stability'])) { return $this->_packageInfo['stability']; } return false; } function getState($key = 'release') { if (isset($this->_packageInfo['stability'][$key])) { return $this->_packageInfo['stability'][$key]; } return false; } function getLicense($raw = false) { if (isset($this->_packageInfo['license'])) { if ($raw) { return $this->_packageInfo['license']; } if (is_array($this->_packageInfo['license'])) { return $this->_packageInfo['license']['_content']; } else { return $this->_packageInfo['license']; } } return false; } function getLicenseLocation() { if (!isset($this->_packageInfo['license']) || !is_array($this->_packageInfo['license'])) { return false; } return $this->_packageInfo['license']['attribs']; } function getNotes() { if (isset($this->_packageInfo['notes'])) { return $this->_packageInfo['notes']; } return false; } /** * Return the tag contents, if any * @return array|false */ function getUsesrole() { if (isset($this->_packageInfo['usesrole'])) { return $this->_packageInfo['usesrole']; } return false; } /** * Return the tag contents, if any * @return array|false */ function getUsestask() { if (isset($this->_packageInfo['usestask'])) { return $this->_packageInfo['usestask']; } return false; } /** * This should only be used to retrieve filenames and install attributes */ function getFilelist($preserve = false) { if (isset($this->_packageInfo['filelist']) && !$preserve) { return $this->_packageInfo['filelist']; } $this->flattenFilelist(); if ($contents = $this->getContents()) { $ret = array(); if (!isset($contents['dir'])) { return false; } if (!isset($contents['dir']['file'][0])) { $contents['dir']['file'] = array($contents['dir']['file']); } foreach ($contents['dir']['file'] as $file) { if (!isset($file['attribs']['name'])) { continue; } $name = $file['attribs']['name']; if (!$preserve) { $file = $file['attribs']; } $ret[$name] = $file; } if (!$preserve) { $this->_packageInfo['filelist'] = $ret; } return $ret; } return false; } /** * Return configure options array, if any * * @return array|false */ function getConfigureOptions() { if ($this->getPackageType() != 'extsrc' && $this->getPackageType() != 'zendextsrc') { return false; } $releases = $this->getReleases(); if (isset($releases[0])) { $releases = $releases[0]; } if (isset($releases['configureoption'])) { if (!isset($releases['configureoption'][0])) { $releases['configureoption'] = array($releases['configureoption']); } for ($i = 0; $i < count($releases['configureoption']); $i++) { $releases['configureoption'][$i] = $releases['configureoption'][$i]['attribs']; } return $releases['configureoption']; } return false; } /** * This is only used at install-time, after all serialization * is over. */ function resetFilelist() { $this->_packageInfo['filelist'] = array(); } /** * Retrieve a list of files that should be installed on this computer * @return array */ function getInstallationFilelist($forfilecheck = false) { $contents = $this->getFilelist(true); if (isset($contents['dir']['attribs']['baseinstalldir'])) { $base = $contents['dir']['attribs']['baseinstalldir']; } if (isset($this->_packageInfo['bundle'])) { return PEAR::raiseError( 'Exception: bundles should be handled in download code only'); } $release = $this->getReleases(); if ($release) { if (!isset($release[0])) { if (!isset($release['installconditions']) && !isset($release['filelist'])) { if ($forfilecheck) { return $this->getFilelist(); } return $contents; } $release = array($release); } $depchecker = &$this->getPEARDependency2($this->_config, array(), array('channel' => $this->getChannel(), 'package' => $this->getPackage()), PEAR_VALIDATE_INSTALLING); foreach ($release as $instance) { if (isset($instance['installconditions'])) { $installconditions = $instance['installconditions']; if (is_array($installconditions)) { PEAR::pushErrorHandling(PEAR_ERROR_RETURN); foreach ($installconditions as $type => $conditions) { if (!isset($conditions[0])) { $conditions = array($conditions); } foreach ($conditions as $condition) { $ret = $depchecker->{"validate{$type}Dependency"}($condition); if (PEAR::isError($ret)) { PEAR::popErrorHandling(); continue 3; // skip this release } } } PEAR::popErrorHandling(); } } // this is the release to use if (isset($instance['filelist'])) { // ignore files if (isset($instance['filelist']['ignore'])) { $ignore = isset($instance['filelist']['ignore'][0]) ? $instance['filelist']['ignore'] : array($instance['filelist']['ignore']); foreach ($ignore as $ig) { unset ($contents[$ig['attribs']['name']]); } } // install files as this name if (isset($instance['filelist']['install'])) { $installas = isset($instance['filelist']['install'][0]) ? $instance['filelist']['install'] : array($instance['filelist']['install']); foreach ($installas as $as) { $contents[$as['attribs']['name']]['attribs']['install-as'] = $as['attribs']['as']; } } } if ($forfilecheck) { foreach ($contents as $file => $attrs) { $contents[$file] = $attrs['attribs']; } } return $contents; } } else { // simple release - no installconditions or install-as if ($forfilecheck) { return $this->getFilelist(); } return $contents; } // no releases matched return PEAR::raiseError('No releases in package.xml matched the existing operating ' . 'system, extensions installed, or architecture, cannot install'); } /** * This is only used at install-time, after all serialization * is over. * @param string file name * @param string installed path */ function setInstalledAs($file, $path) { if ($path) { return $this->_packageInfo['filelist'][$file]['installed_as'] = $path; } unset($this->_packageInfo['filelist'][$file]['installed_as']); } function getInstalledLocation($file) { if (isset($this->_packageInfo['filelist'][$file]['installed_as'])) { return $this->_packageInfo['filelist'][$file]['installed_as']; } return false; } /** * This is only used at install-time, after all serialization * is over. */ function installedFile($file, $atts) { if (isset($this->_packageInfo['filelist'][$file])) { $this->_packageInfo['filelist'][$file] = array_merge($this->_packageInfo['filelist'][$file], $atts['attribs']); } else { $this->_packageInfo['filelist'][$file] = $atts['attribs']; } } /** * Retrieve the contents tag */ function getContents() { if (isset($this->_packageInfo['contents'])) { return $this->_packageInfo['contents']; } return false; } /** * @param string full path to file * @param string attribute name * @param string attribute value * @param int risky but fast - use this to choose a file based on its position in the list * of files. Index is zero-based like PHP arrays. * @return bool success of operation */ function setFileAttribute($filename, $attr, $value, $index = false) { $this->_isValid = 0; if (in_array($attr, array('role', 'name', 'baseinstalldir'))) { $this->_filesValid = false; } if ($index !== false && isset($this->_packageInfo['contents']['dir']['file'][$index]['attribs'])) { $this->_packageInfo['contents']['dir']['file'][$index]['attribs'][$attr] = $value; return true; } if (!isset($this->_packageInfo['contents']['dir']['file'])) { return false; } $files = $this->_packageInfo['contents']['dir']['file']; if (!isset($files[0])) { $files = array($files); $ind = false; } else { $ind = true; } foreach ($files as $i => $file) { if (isset($file['attribs'])) { if ($file['attribs']['name'] == $filename) { if ($ind) { $this->_packageInfo['contents']['dir']['file'][$i]['attribs'][$attr] = $value; } else { $this->_packageInfo['contents']['dir']['file']['attribs'][$attr] = $value; } return true; } } } return false; } function setDirtree($path) { if (!isset($this->_packageInfo['dirtree'])) { $this->_packageInfo['dirtree'] = array(); } $this->_packageInfo['dirtree'][$path] = true; } function getDirtree() { if (isset($this->_packageInfo['dirtree']) && count($this->_packageInfo['dirtree'])) { return $this->_packageInfo['dirtree']; } return false; } function resetDirtree() { unset($this->_packageInfo['dirtree']); } /** * Determines whether this package claims it is compatible with the version of * the package that has a recommended version dependency * @param PEAR_PackageFile_v2|PEAR_PackageFile_v1|PEAR_Downloader_Package * @return boolean */ function isCompatible($pf) { if (!isset($this->_packageInfo['compatible'])) { return false; } if (!isset($this->_packageInfo['channel'])) { return false; } $me = $pf->getVersion(); $compatible = $this->_packageInfo['compatible']; if (!isset($compatible[0])) { $compatible = array($compatible); } $found = false; foreach ($compatible as $info) { if (strtolower($info['name']) == strtolower($pf->getPackage())) { if (strtolower($info['channel']) == strtolower($pf->getChannel())) { $found = true; break; } } } if (!$found) { return false; } if (isset($info['exclude'])) { if (!isset($info['exclude'][0])) { $info['exclude'] = array($info['exclude']); } foreach ($info['exclude'] as $exclude) { if (version_compare($me, $exclude, '==')) { return false; } } } if (version_compare($me, $info['min'], '>=') && version_compare($me, $info['max'], '<=')) { return true; } return false; } /** * @return array|false */ function getCompatible() { if (isset($this->_packageInfo['compatible'])) { return $this->_packageInfo['compatible']; } return false; } function getDependencies() { if (isset($this->_packageInfo['dependencies'])) { return $this->_packageInfo['dependencies']; } return false; } function isSubpackageOf($p) { return $p->isSubpackage($this); } /** * Determines whether the passed in package is a subpackage of this package. * * No version checking is done, only name verification. * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 * @return bool */ function isSubpackage($p) { $sub = array(); if (isset($this->_packageInfo['dependencies']['required']['subpackage'])) { $sub = $this->_packageInfo['dependencies']['required']['subpackage']; if (!isset($sub[0])) { $sub = array($sub); } } if (isset($this->_packageInfo['dependencies']['optional']['subpackage'])) { $sub1 = $this->_packageInfo['dependencies']['optional']['subpackage']; if (!isset($sub1[0])) { $sub1 = array($sub1); } $sub = array_merge($sub, $sub1); } if (isset($this->_packageInfo['dependencies']['group'])) { $group = $this->_packageInfo['dependencies']['group']; if (!isset($group[0])) { $group = array($group); } foreach ($group as $deps) { if (isset($deps['subpackage'])) { $sub2 = $deps['subpackage']; if (!isset($sub2[0])) { $sub2 = array($sub2); } $sub = array_merge($sub, $sub2); } } } foreach ($sub as $dep) { if (strtolower($dep['name']) == strtolower($p->getPackage())) { if (isset($dep['channel'])) { if (strtolower($dep['channel']) == strtolower($p->getChannel())) { return true; } } else { if ($dep['uri'] == $p->getURI()) { return true; } } } } return false; } function dependsOn($package, $channel) { if (!($deps = $this->getDependencies())) { return false; } foreach (array('package', 'subpackage') as $type) { foreach (array('required', 'optional') as $needed) { if (isset($deps[$needed][$type])) { if (!isset($deps[$needed][$type][0])) { $deps[$needed][$type] = array($deps[$needed][$type]); } foreach ($deps[$needed][$type] as $dep) { $depchannel = isset($dep['channel']) ? $dep['channel'] : '__uri'; if (strtolower($dep['name']) == strtolower($package) && $depchannel == $channel) { return true; } } } } if (isset($deps['group'])) { if (!isset($deps['group'][0])) { $dep['group'] = array($deps['group']); } foreach ($deps['group'] as $group) { if (isset($group[$type])) { if (!is_array($group[$type])) { $group[$type] = array($group[$type]); } foreach ($group[$type] as $dep) { $depchannel = isset($dep['channel']) ? $dep['channel'] : '__uri'; if (strtolower($dep['name']) == strtolower($package) && $depchannel == $channel) { return true; } } } } } } return false; } /** * Get the contents of a dependency group * @param string * @return array|false */ function getDependencyGroup($name) { $name = strtolower($name); if (!isset($this->_packageInfo['dependencies']['group'])) { return false; } $groups = $this->_packageInfo['dependencies']['group']; if (!isset($groups[0])) { $groups = array($groups); } foreach ($groups as $group) { if (strtolower($group['attribs']['name']) == $name) { return $group; } } return false; } /** * Retrieve a partial package.xml 1.0 representation of dependencies * * a very limited representation of dependencies is returned by this method. * The tag for excluding certain versions of a dependency is * completely ignored. In addition, dependency groups are ignored, with the * assumption that all dependencies in dependency groups are also listed in * the optional group that work with all dependency groups * @param boolean return package.xml 2.0 tag * @return array|false */ function getDeps($raw = false, $nopearinstaller = false) { if (isset($this->_packageInfo['dependencies'])) { if ($raw) { return $this->_packageInfo['dependencies']; } $ret = array(); $map = array( 'php' => 'php', 'package' => 'pkg', 'subpackage' => 'pkg', 'extension' => 'ext', 'os' => 'os', 'pearinstaller' => 'pkg', ); foreach (array('required', 'optional') as $type) { $optional = ($type == 'optional') ? 'yes' : 'no'; if (!isset($this->_packageInfo['dependencies'][$type]) || empty($this->_packageInfo['dependencies'][$type])) { continue; } foreach ($this->_packageInfo['dependencies'][$type] as $dtype => $deps) { if ($dtype == 'pearinstaller' && $nopearinstaller) { continue; } if ((is_array($deps) && !isset($deps[0])) || !is_array($deps)) { $deps = array($deps); } foreach ($deps as $dep) { if (!isset($map[$dtype])) { // no support for arch type continue; } if ($dtype == 'pearinstaller') { $dep['name'] = 'PEAR'; $dep['channel'] = 'pear.php.net'; } $s = array('type' => $map[$dtype]); if (isset($dep['channel'])) { $s['channel'] = $dep['channel']; } if (isset($dep['uri'])) { $s['uri'] = $dep['uri']; } if (isset($dep['name'])) { $s['name'] = $dep['name']; } if (isset($dep['conflicts'])) { $s['rel'] = 'not'; } else { if (!isset($dep['min']) && !isset($dep['max'])) { $s['rel'] = 'has'; $s['optional'] = $optional; } elseif (isset($dep['min']) && isset($dep['max'])) { $s['rel'] = 'ge'; $s1 = $s; $s1['rel'] = 'le'; $s['version'] = $dep['min']; $s1['version'] = $dep['max']; if (isset($dep['channel'])) { $s1['channel'] = $dep['channel']; } if ($dtype != 'php') { $s['name'] = $dep['name']; $s1['name'] = $dep['name']; } $s['optional'] = $optional; $s1['optional'] = $optional; $ret[] = $s1; } elseif (isset($dep['min'])) { if (isset($dep['exclude']) && $dep['exclude'] == $dep['min']) { $s['rel'] = 'gt'; } else { $s['rel'] = 'ge'; } $s['version'] = $dep['min']; $s['optional'] = $optional; if ($dtype != 'php') { $s['name'] = $dep['name']; } } elseif (isset($dep['max'])) { if (isset($dep['exclude']) && $dep['exclude'] == $dep['max']) { $s['rel'] = 'lt'; } else { $s['rel'] = 'le'; } $s['version'] = $dep['max']; $s['optional'] = $optional; if ($dtype != 'php') { $s['name'] = $dep['name']; } } } $ret[] = $s; } } } if (count($ret)) { return $ret; } } return false; } /** * @return php|extsrc|extbin|zendextsrc|zendextbin|bundle|false */ function getPackageType() { if (isset($this->_packageInfo['phprelease'])) { return 'php'; } if (isset($this->_packageInfo['extsrcrelease'])) { return 'extsrc'; } if (isset($this->_packageInfo['extbinrelease'])) { return 'extbin'; } if (isset($this->_packageInfo['zendextsrcrelease'])) { return 'zendextsrc'; } if (isset($this->_packageInfo['zendextbinrelease'])) { return 'zendextbin'; } if (isset($this->_packageInfo['bundle'])) { return 'bundle'; } return false; } /** * @return array|false */ function getReleases() { $type = $this->getPackageType(); if ($type != 'bundle') { $type .= 'release'; } if ($this->getPackageType() && isset($this->_packageInfo[$type])) { return $this->_packageInfo[$type]; } return false; } /** * @return array */ function getChangelog() { if (isset($this->_packageInfo['changelog'])) { return $this->_packageInfo['changelog']; } return false; } function hasDeps() { return isset($this->_packageInfo['dependencies']); } function getPackagexmlVersion() { if (isset($this->_packageInfo['zendextsrcrelease'])) { return '2.1'; } if (isset($this->_packageInfo['zendextbinrelease'])) { return '2.1'; } return '2.0'; } /** * @return array|false */ function getSourcePackage() { if (isset($this->_packageInfo['extbinrelease']) || isset($this->_packageInfo['zendextbinrelease'])) { return array('channel' => $this->_packageInfo['srcchannel'], 'package' => $this->_packageInfo['srcpackage']); } return false; } function getBundledPackages() { if (isset($this->_packageInfo['bundle'])) { return $this->_packageInfo['contents']['bundledpackage']; } return false; } function getLastModified() { if (isset($this->_packageInfo['_lastmodified'])) { return $this->_packageInfo['_lastmodified']; } return false; } /** * Get the contents of a file listed within the package.xml * @param string * @return string */ function getFileContents($file) { if ($this->_archiveFile == $this->_packageFile) { // unpacked $dir = dirname($this->_packageFile); $file = $dir . DIRECTORY_SEPARATOR . $file; $file = str_replace(array('/', '\\'), array(DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR), $file); if (file_exists($file) && is_readable($file)) { return implode('', file($file)); } } else { // tgz $tar = new Archive_Tar($this->_archiveFile); $tar->pushErrorHandling(PEAR_ERROR_RETURN); if ($file != 'package.xml' && $file != 'package2.xml') { $file = $this->getPackage() . '-' . $this->getVersion() . '/' . $file; } $file = $tar->extractInString($file); $tar->popErrorHandling(); if (PEAR::isError($file)) { return PEAR::raiseError("Cannot locate file '$file' in archive"); } return $file; } } function &getRW() { if (!class_exists('PEAR_PackageFile_v2_rw')) { require_once 'PEAR/PackageFile/v2/rw.php'; } $a = new PEAR_PackageFile_v2_rw; foreach (get_object_vars($this) as $name => $unused) { if (!isset($this->$name)) { continue; } if ($name == '_config' || $name == '_logger'|| $name == '_registry' || $name == '_stack') { $a->$name = &$this->$name; } else { $a->$name = $this->$name; } } return $a; } function &getDefaultGenerator() { if (!class_exists('PEAR_PackageFile_Generator_v2')) { require_once 'PEAR/PackageFile/Generator/v2.php'; } $a = new PEAR_PackageFile_Generator_v2($this); return $a; } function analyzeSourceCode($file, $string = false) { if (!isset($this->_v2Validator) || !is_a($this->_v2Validator, 'PEAR_PackageFile_v2_Validator')) { if (!class_exists('PEAR_PackageFile_v2_Validator')) { require_once 'PEAR/PackageFile/v2/Validator.php'; } $this->_v2Validator = new PEAR_PackageFile_v2_Validator; } return $this->_v2Validator->analyzeSourceCode($file, $string); } function validate($state = PEAR_VALIDATE_NORMAL) { if (!isset($this->_packageInfo) || !is_array($this->_packageInfo)) { return false; } if (!isset($this->_v2Validator) || !is_a($this->_v2Validator, 'PEAR_PackageFile_v2_Validator')) { if (!class_exists('PEAR_PackageFile_v2_Validator')) { require_once 'PEAR/PackageFile/v2/Validator.php'; } $this->_v2Validator = new PEAR_PackageFile_v2_Validator; } if (isset($this->_packageInfo['xsdversion'])) { unset($this->_packageInfo['xsdversion']); } return $this->_v2Validator->validate($this, $state); } function getTasksNs() { if (!isset($this->_tasksNs)) { if (isset($this->_packageInfo['attribs'])) { foreach ($this->_packageInfo['attribs'] as $name => $value) { if ($value == 'http://pear.php.net/dtd/tasks-1.0') { $this->_tasksNs = str_replace('xmlns:', '', $name); break; } } } } return $this->_tasksNs; } /** * Determine whether a task name is a valid task. Custom tasks may be defined * using subdirectories by putting a "-" in the name, as in * * Note that this method will auto-load the task class file and test for the existence * of the name with "-" replaced by "_" as in PEAR/Task/mycustom/task.php makes class * PEAR_Task_mycustom_task * @param string * @return boolean */ function getTask($task) { $this->getTasksNs(); // transform all '-' to '/' and 'tasks:' to '' so tasks:replace becomes replace $task = str_replace(array($this->_tasksNs . ':', '-'), array('', ' '), $task); $taskfile = str_replace(' ', '/', ucwords($task)); $task = str_replace(array(' ', '/'), '_', ucwords($task)); if (class_exists("PEAR_Task_$task")) { return "PEAR_Task_$task"; } $fp = @fopen("PEAR/Task/$taskfile.php", 'r', true); if ($fp) { fclose($fp); require_once "PEAR/Task/$taskfile.php"; return "PEAR_Task_$task"; } return false; } /** * Key-friendly array_splice * @param tagname to splice a value in before * @param mixed the value to splice in * @param string the new tag name */ function _ksplice($array, $key, $value, $newkey) { $offset = array_search($key, array_keys($array)); $after = array_slice($array, $offset); $before = array_slice($array, 0, $offset); $before[$newkey] = $value; return array_merge($before, $after); } /** * @param array a list of possible keys, in the order they may occur * @param mixed contents of the new package.xml tag * @param string tag name * @access private */ function _insertBefore($array, $keys, $contents, $newkey) { foreach ($keys as $key) { if (isset($array[$key])) { return $array = $this->_ksplice($array, $key, $contents, $newkey); } } $array[$newkey] = $contents; return $array; } /** * @param subsection of {@link $_packageInfo} * @param array|string tag contents * @param array format: *
     * array(
     *   tagname => array(list of tag names that follow this one),
     *   childtagname => array(list of child tag names that follow this one),
     * )
     * 
* * This allows construction of nested tags * @access private */ function _mergeTag($manip, $contents, $order) { if (count($order)) { foreach ($order as $tag => $curorder) { if (!isset($manip[$tag])) { // ensure that the tag is set up $manip = $this->_insertBefore($manip, $curorder, array(), $tag); } if (count($order) > 1) { $manip[$tag] = $this->_mergeTag($manip[$tag], $contents, array_slice($order, 1)); return $manip; } } } else { return $manip; } if (is_array($manip[$tag]) && !empty($manip[$tag]) && isset($manip[$tag][0])) { $manip[$tag][] = $contents; } else { if (is_array($manip[$tag]) && !count($manip[$tag])) { $manip[$tag] = $contents; } else { $manip[$tag] = array($manip[$tag]); $manip[$tag][] = $contents; } } return $manip; } } ?> PKu]ɁɁ!PEAR/PackageFile/Generator/v2.phpnu[ * @author Stephan Schmidt (original XML_Serializer code) * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ /** * file/dir manipulation routines */ require_once 'System.php'; require_once 'XML/Util.php'; /** * This class converts a PEAR_PackageFile_v2 object into any output format. * * Supported output formats include array, XML string (using S. Schmidt's * XML_Serializer, slightly customized) * @category pear * @package PEAR * @author Greg Beaver * @author Stephan Schmidt (original XML_Serializer code) * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ class PEAR_PackageFile_Generator_v2 { /** * default options for the serialization * @access private * @var array $_defaultOptions */ var $_defaultOptions = array( 'indent' => ' ', // string used for indentation 'linebreak' => "\n", // string used for newlines 'typeHints' => false, // automatically add type hin attributes 'addDecl' => true, // add an XML declaration 'defaultTagName' => 'XML_Serializer_Tag', // tag used for indexed arrays or invalid names 'classAsTagName' => false, // use classname for objects in indexed arrays 'keyAttribute' => '_originalKey', // attribute where original key is stored 'typeAttribute' => '_type', // attribute for type (only if typeHints => true) 'classAttribute' => '_class', // attribute for class of objects (only if typeHints => true) 'scalarAsAttributes' => false, // scalar values (strings, ints,..) will be serialized as attribute 'prependAttributes' => '', // prepend string for attributes 'indentAttributes' => false, // indent the attributes, if set to '_auto', it will indent attributes so they all start at the same column 'mode' => 'simplexml', // use 'simplexml' to use parent name as tagname if transforming an indexed array 'addDoctype' => false, // add a doctype declaration 'doctype' => null, // supply a string or an array with id and uri ({@see XML_Util::getDoctypeDeclaration()} 'rootName' => 'package', // name of the root tag 'rootAttributes' => array( 'version' => '2.0', 'xmlns' => 'http://pear.php.net/dtd/package-2.0', 'xmlns:tasks' => 'http://pear.php.net/dtd/tasks-1.0', 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', 'xsi:schemaLocation' => 'http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd', ), // attributes of the root tag 'attributesArray' => 'attribs', // all values in this key will be treated as attributes 'contentName' => '_content', // this value will be used directly as content, instead of creating a new tag, may only be used in conjunction with attributesArray 'beautifyFilelist' => false, 'encoding' => 'UTF-8', ); /** * options for the serialization * @access private * @var array $options */ var $options = array(); /** * current tag depth * @var integer $_tagDepth */ var $_tagDepth = 0; /** * serilialized representation of the data * @var string $_serializedData */ var $_serializedData = null; /** * @var PEAR_PackageFile_v2 */ var $_packagefile; /** * @param PEAR_PackageFile_v2 */ function __construct(&$packagefile) { $this->_packagefile = &$packagefile; if (isset($this->_packagefile->encoding)) { $this->_defaultOptions['encoding'] = $this->_packagefile->encoding; } } /** * @return string */ function getPackagerVersion() { return '1.10.16'; } /** * @param PEAR_Packager * @param bool generate a .tgz or a .tar * @param string|null temporary directory to package in */ function toTgz(&$packager, $compress = true, $where = null) { $a = null; return $this->toTgz2($packager, $a, $compress, $where); } /** * Package up both a package.xml and package2.xml for the same release * @param PEAR_Packager * @param PEAR_PackageFile_v1 * @param bool generate a .tgz or a .tar * @param string|null temporary directory to package in */ function toTgz2(&$packager, &$pf1, $compress = true, $where = null) { require_once 'Archive/Tar.php'; if (!$this->_packagefile->isEquivalent($pf1)) { return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: "' . basename($pf1->getPackageFile()) . '" is not equivalent to "' . basename($this->_packagefile->getPackageFile()) . '"'); } if ($where === null) { if (!($where = System::mktemp(array('-d')))) { return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: mktemp failed'); } } elseif (!@System::mkDir(array('-p', $where))) { return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: "' . $where . '" could' . ' not be created'); } $file = $where . DIRECTORY_SEPARATOR . 'package.xml'; if (file_exists($file) && !is_file($file)) { return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: unable to save package.xml as' . ' "' . $file .'"'); } if (!$this->_packagefile->validate(PEAR_VALIDATE_PACKAGING)) { return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: invalid package.xml'); } $ext = $compress ? '.tgz' : '.tar'; $pkgver = $this->_packagefile->getPackage() . '-' . $this->_packagefile->getVersion(); $dest_package = getcwd() . DIRECTORY_SEPARATOR . $pkgver . $ext; if (file_exists($dest_package) && !is_file($dest_package)) { return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: cannot create tgz file "' . $dest_package . '"'); } $pkgfile = $this->_packagefile->getPackageFile(); if (!$pkgfile) { return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: package file object must ' . 'be created from a real file'); } $pkgdir = dirname(realpath($pkgfile)); $pkgfile = basename($pkgfile); // {{{ Create the package file list $filelist = array(); $i = 0; $this->_packagefile->flattenFilelist(); $contents = $this->_packagefile->getContents(); if (isset($contents['bundledpackage'])) { // bundles of packages $contents = $contents['bundledpackage']; if (!isset($contents[0])) { $contents = array($contents); } $packageDir = $where; foreach ($contents as $i => $package) { $fname = $package; $file = $pkgdir . DIRECTORY_SEPARATOR . $fname; if (!file_exists($file)) { return $packager->raiseError("File does not exist: $fname"); } $tfile = $packageDir . DIRECTORY_SEPARATOR . $fname; System::mkdir(array('-p', dirname($tfile))); copy($file, $tfile); $filelist[$i++] = $tfile; $packager->log(2, "Adding package $fname"); } } else { // normal packages $contents = $contents['dir']['file']; if (!isset($contents[0])) { $contents = array($contents); } $packageDir = $where; foreach ($contents as $i => $file) { $fname = $file['attribs']['name']; $atts = $file['attribs']; $orig = $file; $file = $pkgdir . DIRECTORY_SEPARATOR . $fname; if (!file_exists($file)) { return $packager->raiseError("File does not exist: $fname"); } $origperms = fileperms($file); $tfile = $packageDir . DIRECTORY_SEPARATOR . $fname; unset($orig['attribs']); if (count($orig)) { // file with tasks // run any package-time tasks $contents = file_get_contents($file); foreach ($orig as $tag => $raw) { $tag = str_replace( array($this->_packagefile->getTasksNs() . ':', '-'), array('', '_'), $tag); $task = "PEAR_Task_$tag"; $task = new $task($this->_packagefile->_config, $this->_packagefile->_logger, PEAR_TASK_PACKAGE); $task->init($raw, $atts, null); $res = $task->startSession($this->_packagefile, $contents, $tfile); if (!$res) { continue; // skip this task } if (PEAR::isError($res)) { return $res; } $contents = $res; // save changes System::mkdir(array('-p', dirname($tfile))); $wp = fopen($tfile, "wb"); fwrite($wp, $contents); fclose($wp); } } if (!file_exists($tfile)) { System::mkdir(array('-p', dirname($tfile))); copy($file, $tfile); } chmod($tfile, $origperms); $filelist[$i++] = $tfile; $this->_packagefile->setFileAttribute($fname, 'md5sum', md5_file($tfile), $i - 1); $packager->log(2, "Adding file $fname"); } } // }}} $name = $pf1 !== null ? 'package2.xml' : 'package.xml'; $packagexml = $this->toPackageFile($where, PEAR_VALIDATE_PACKAGING, $name); if ($packagexml) { $tar = new Archive_Tar($dest_package, $compress); $tar->setErrorHandling(PEAR_ERROR_RETURN); // XXX Don't print errors // ----- Creates with the package.xml file $ok = $tar->createModify(array($packagexml), '', $where); if (PEAR::isError($ok)) { return $packager->raiseError($ok); } elseif (!$ok) { return $packager->raiseError('PEAR_Packagefile_v2::toTgz(): adding ' . $name . ' failed'); } // ----- Add the content of the package if (!$tar->addModify($filelist, $pkgver, $where)) { return $packager->raiseError( 'PEAR_Packagefile_v2::toTgz(): tarball creation failed'); } // add the package.xml version 1.0 if ($pf1 !== null) { $pfgen = &$pf1->getDefaultGenerator(); $packagexml1 = $pfgen->toPackageFile($where, PEAR_VALIDATE_PACKAGING, 'package.xml', true); if (!$tar->addModify(array($packagexml1), '', $where)) { return $packager->raiseError( 'PEAR_Packagefile_v2::toTgz(): adding package.xml failed'); } } return $dest_package; } } function toPackageFile($where = null, $state = PEAR_VALIDATE_NORMAL, $name = 'package.xml') { if (!$this->_packagefile->validate($state)) { return PEAR::raiseError('PEAR_Packagefile_v2::toPackageFile: invalid package.xml', null, null, null, $this->_packagefile->getValidationWarnings()); } if ($where === null) { if (!($where = System::mktemp(array('-d')))) { return PEAR::raiseError('PEAR_Packagefile_v2::toPackageFile: mktemp failed'); } } elseif (!@System::mkDir(array('-p', $where))) { return PEAR::raiseError('PEAR_Packagefile_v2::toPackageFile: "' . $where . '" could' . ' not be created'); } $newpkgfile = $where . DIRECTORY_SEPARATOR . $name; $np = @fopen($newpkgfile, 'wb'); if (!$np) { return PEAR::raiseError('PEAR_Packagefile_v2::toPackageFile: unable to save ' . "$name as $newpkgfile"); } fwrite($np, $this->toXml($state)); fclose($np); return $newpkgfile; } function &toV2() { return $this->_packagefile; } /** * Return an XML document based on the package info (as returned * by the PEAR_Common::infoFrom* methods). * * @return string XML data */ function toXml($state = PEAR_VALIDATE_NORMAL, $options = array()) { $this->_packagefile->setDate(date('Y-m-d')); $this->_packagefile->setTime(date('H:i:s')); if (!$this->_packagefile->validate($state)) { return false; } if (is_array($options)) { $this->options = array_merge($this->_defaultOptions, $options); } else { $this->options = $this->_defaultOptions; } $arr = $this->_packagefile->getArray(); if (isset($arr['filelist'])) { unset($arr['filelist']); } if (isset($arr['_lastversion'])) { unset($arr['_lastversion']); } // Fix the notes a little bit if (isset($arr['notes'])) { // This trims out the indenting, needs fixing $arr['notes'] = "\n" . trim($arr['notes']) . "\n"; } if (isset($arr['changelog']) && !empty($arr['changelog'])) { // Fix for inconsistency how the array is filled depending on the changelog release amount if (!isset($arr['changelog']['release'][0])) { $release = $arr['changelog']['release']; unset($arr['changelog']['release']); $arr['changelog']['release'] = array(); $arr['changelog']['release'][0] = $release; } foreach (array_keys($arr['changelog']['release']) as $key) { $c =& $arr['changelog']['release'][$key]; if (isset($c['notes'])) { // This trims out the indenting, needs fixing $c['notes'] = "\n" . trim($c['notes']) . "\n"; } } } if ($state ^ PEAR_VALIDATE_PACKAGING && !isset($arr['bundle'])) { $use = $this->_recursiveXmlFilelist($arr['contents']['dir']['file']); unset($arr['contents']['dir']['file']); if (isset($use['dir'])) { $arr['contents']['dir']['dir'] = $use['dir']; } if (isset($use['file'])) { $arr['contents']['dir']['file'] = $use['file']; } $this->options['beautifyFilelist'] = true; } $arr['attribs']['packagerversion'] = '1.10.16'; if ($this->serialize($arr, $options)) { return $this->_serializedData . "\n"; } return false; } function _recursiveXmlFilelist($list) { $dirs = array(); if (isset($list['attribs'])) { $file = $list['attribs']['name']; unset($list['attribs']['name']); $attributes = $list['attribs']; $this->_addDir($dirs, explode('/', dirname($file)), $file, $attributes); } else { foreach ($list as $a) { $file = $a['attribs']['name']; $attributes = $a['attribs']; unset($a['attribs']); $this->_addDir($dirs, explode('/', dirname($file)), $file, $attributes, $a); } } $this->_formatDir($dirs); $this->_deFormat($dirs); return $dirs; } function _addDir(&$dirs, $dir, $file = null, $attributes = null, $tasks = null) { if (!$tasks) { $tasks = array(); } if ($dir == array() || $dir == array('.')) { $dirs['file'][basename($file)] = $tasks; $attributes['name'] = basename($file); $dirs['file'][basename($file)]['attribs'] = $attributes; return; } $curdir = array_shift($dir); if (!isset($dirs['dir'][$curdir])) { $dirs['dir'][$curdir] = array(); } $this->_addDir($dirs['dir'][$curdir], $dir, $file, $attributes, $tasks); } function _formatDir(&$dirs) { if (!count($dirs)) { return array(); } $newdirs = array(); if (isset($dirs['dir'])) { $newdirs['dir'] = $dirs['dir']; } if (isset($dirs['file'])) { $newdirs['file'] = $dirs['file']; } $dirs = $newdirs; if (isset($dirs['dir'])) { uksort($dirs['dir'], 'strnatcasecmp'); foreach ($dirs['dir'] as $dir => $contents) { $this->_formatDir($dirs['dir'][$dir]); } } if (isset($dirs['file'])) { uksort($dirs['file'], 'strnatcasecmp'); }; } function _deFormat(&$dirs) { if (!count($dirs)) { return array(); } $newdirs = array(); if (isset($dirs['dir'])) { foreach ($dirs['dir'] as $dir => $contents) { $newdir = array(); $newdir['attribs']['name'] = $dir; $this->_deFormat($contents); foreach ($contents as $tag => $val) { $newdir[$tag] = $val; } $newdirs['dir'][] = $newdir; } if (count($newdirs['dir']) == 1) { $newdirs['dir'] = $newdirs['dir'][0]; } } if (isset($dirs['file'])) { foreach ($dirs['file'] as $name => $file) { $newdirs['file'][] = $file; } if (count($newdirs['file']) == 1) { $newdirs['file'] = $newdirs['file'][0]; } } $dirs = $newdirs; } /** * reset all options to default options * * @access public * @see setOption(), XML_Unserializer() */ function resetOptions() { $this->options = $this->_defaultOptions; } /** * set an option * * You can use this method if you do not want to set all options in the constructor * * @access public * @see resetOption(), XML_Serializer() */ function setOption($name, $value) { $this->options[$name] = $value; } /** * sets several options at once * * You can use this method if you do not want to set all options in the constructor * * @access public * @see resetOption(), XML_Unserializer(), setOption() */ function setOptions($options) { $this->options = array_merge($this->options, $options); } /** * serialize data * * @access public * @param mixed $data data to serialize * @return boolean true on success, pear error on failure */ function serialize($data, $options = null) { // if options have been specified, use them instead // of the previously defined ones if (is_array($options)) { $optionsBak = $this->options; if (isset($options['overrideOptions']) && $options['overrideOptions'] == true) { $this->options = array_merge($this->_defaultOptions, $options); } else { $this->options = array_merge($this->options, $options); } } else { $optionsBak = null; } // start depth is zero $this->_tagDepth = 0; $this->_serializedData = ''; // serialize an array if (is_array($data)) { $tagName = isset($this->options['rootName']) ? $this->options['rootName'] : 'array'; $this->_serializedData .= $this->_serializeArray($data, $tagName, $this->options['rootAttributes']); } // add doctype declaration if ($this->options['addDoctype'] === true) { $this->_serializedData = XML_Util::getDoctypeDeclaration($tagName, $this->options['doctype']) . $this->options['linebreak'] . $this->_serializedData; } // build xml declaration if ($this->options['addDecl']) { $atts = array(); $encoding = isset($this->options['encoding']) ? $this->options['encoding'] : null; $this->_serializedData = XML_Util::getXMLDeclaration('1.0', $encoding) . $this->options['linebreak'] . $this->_serializedData; } if ($optionsBak !== null) { $this->options = $optionsBak; } return true; } /** * get the result of the serialization * * @access public * @return string serialized XML */ function getSerializedData() { if ($this->_serializedData === null) { return $this->raiseError('No serialized data available. Use XML_Serializer::serialize() first.', XML_SERIALIZER_ERROR_NO_SERIALIZATION); } return $this->_serializedData; } /** * serialize any value * * This method checks for the type of the value and calls the appropriate method * * @access private * @param mixed $value * @param string $tagName * @param array $attributes * @return string */ function _serializeValue($value, $tagName = null, $attributes = array()) { if (is_array($value)) { $xml = $this->_serializeArray($value, $tagName, $attributes); } elseif (is_object($value)) { $xml = $this->_serializeObject($value, $tagName); } else { $tag = array( 'qname' => $tagName, 'attributes' => $attributes, 'content' => $value ); $xml = $this->_createXMLTag($tag); } return $xml; } /** * serialize an array * * @access private * @param array $array array to serialize * @param string $tagName name of the root tag * @param array $attributes attributes for the root tag * @return string $string serialized data * @uses XML_Util::isValidName() to check, whether key has to be substituted */ function _serializeArray(&$array, $tagName = null, $attributes = array()) { $_content = null; /** * check for special attributes */ if ($this->options['attributesArray'] !== null) { if (isset($array[$this->options['attributesArray']])) { $attributes = $array[$this->options['attributesArray']]; unset($array[$this->options['attributesArray']]); } /** * check for special content */ if ($this->options['contentName'] !== null) { if (isset($array[$this->options['contentName']])) { $_content = $array[$this->options['contentName']]; unset($array[$this->options['contentName']]); } } } /* * if mode is set to simpleXML, check whether * the array is associative or indexed */ if (is_array($array) && $this->options['mode'] == 'simplexml') { $indexed = true; if (!count($array)) { $indexed = false; } foreach ($array as $key => $val) { if (!is_int($key)) { $indexed = false; break; } } if ($indexed && $this->options['mode'] == 'simplexml') { $string = ''; foreach ($array as $key => $val) { if ($this->options['beautifyFilelist'] && $tagName == 'dir') { if (!isset($this->_curdir)) { $this->_curdir = ''; } $savedir = $this->_curdir; if (isset($val['attribs'])) { if ($val['attribs']['name'] == '/') { $this->_curdir = '/'; } else { if ($this->_curdir == '/') { $this->_curdir = ''; } $this->_curdir .= '/' . $val['attribs']['name']; } } } $string .= $this->_serializeValue( $val, $tagName, $attributes); if ($this->options['beautifyFilelist'] && $tagName == 'dir') { $string .= ' '; if (empty($savedir)) { unset($this->_curdir); } else { $this->_curdir = $savedir; } } $string .= $this->options['linebreak']; // do indentation if ($this->options['indent'] !== null && $this->_tagDepth > 0) { $string .= str_repeat($this->options['indent'], $this->_tagDepth); } } return rtrim($string); } } if ($this->options['scalarAsAttributes'] === true) { foreach ($array as $key => $value) { if (is_scalar($value) && (XML_Util::isValidName($key) === true)) { unset($array[$key]); $attributes[$this->options['prependAttributes'].$key] = $value; } } } // check for empty array => create empty tag if (empty($array)) { $tag = array( 'qname' => $tagName, 'content' => $_content, 'attributes' => $attributes ); } else { $this->_tagDepth++; $tmp = $this->options['linebreak']; foreach ($array as $key => $value) { // do indentation if ($this->options['indent'] !== null && $this->_tagDepth > 0) { $tmp .= str_repeat($this->options['indent'], $this->_tagDepth); } // copy key $origKey = $key; // key cannot be used as tagname => use default tag $valid = XML_Util::isValidName($key); if (PEAR::isError($valid)) { if ($this->options['classAsTagName'] && is_object($value)) { $key = get_class($value); } else { $key = $this->options['defaultTagName']; } } $atts = array(); if ($this->options['typeHints'] === true) { $atts[$this->options['typeAttribute']] = gettype($value); if ($key !== $origKey) { $atts[$this->options['keyAttribute']] = (string)$origKey; } } if ($this->options['beautifyFilelist'] && $key == 'dir') { if (!isset($this->_curdir)) { $this->_curdir = ''; } $savedir = $this->_curdir; if (isset($value['attribs'])) { if ($value['attribs']['name'] == '/') { $this->_curdir = '/'; } else { $this->_curdir .= '/' . $value['attribs']['name']; } } } if (is_string($value) && $value && ($value[strlen($value) - 1] == "\n")) { $value .= str_repeat($this->options['indent'], $this->_tagDepth); } $tmp .= $this->_createXMLTag(array( 'qname' => $key, 'attributes' => $atts, 'content' => $value ) ); if ($this->options['beautifyFilelist'] && $key == 'dir') { if (isset($value['attribs'])) { $tmp .= ' '; if (empty($savedir)) { unset($this->_curdir); } else { $this->_curdir = $savedir; } } } $tmp .= $this->options['linebreak']; } $this->_tagDepth--; if ($this->options['indent']!==null && $this->_tagDepth>0) { $tmp .= str_repeat($this->options['indent'], $this->_tagDepth); } if (trim($tmp) === '') { $tmp = null; } $tag = array( 'qname' => $tagName, 'content' => $tmp, 'attributes' => $attributes ); } if ($this->options['typeHints'] === true) { if (!isset($tag['attributes'][$this->options['typeAttribute']])) { $tag['attributes'][$this->options['typeAttribute']] = 'array'; } } $string = $this->_createXMLTag($tag, false); return $string; } /** * create a tag from an array * this method awaits an array in the following format * array( * 'qname' => $tagName, * 'attributes' => array(), * 'content' => $content, // optional * 'namespace' => $namespace // optional * 'namespaceUri' => $namespaceUri // optional * ) * * @access private * @param array $tag tag definition * @param boolean $replaceEntities whether to replace XML entities in content or not * @return string $string XML tag */ function _createXMLTag($tag, $replaceEntities = true) { if ($this->options['indentAttributes'] !== false) { $multiline = true; $indent = str_repeat($this->options['indent'], $this->_tagDepth); if ($this->options['indentAttributes'] == '_auto') { $indent .= str_repeat(' ', (strlen($tag['qname'])+2)); } else { $indent .= $this->options['indentAttributes']; } } else { $indent = $multiline = false; } if (is_array($tag['content'])) { if (empty($tag['content'])) { $tag['content'] = ''; } } elseif(is_scalar($tag['content']) && (string)$tag['content'] == '') { $tag['content'] = ''; } if (is_scalar($tag['content']) || is_null($tag['content'])) { if ($replaceEntities === true) { $replaceEntities = XML_UTIL_ENTITIES_XML; } $tag = XML_Util::createTagFromArray($tag, $replaceEntities, $multiline, $indent, $this->options['linebreak']); } elseif (is_array($tag['content'])) { $tag = $this->_serializeArray($tag['content'], $tag['qname'], $tag['attributes']); } elseif (is_object($tag['content'])) { $tag = $this->_serializeObject($tag['content'], $tag['qname'], $tag['attributes']); } elseif (is_resource($tag['content'])) { settype($tag['content'], 'string'); $tag = XML_Util::createTagFromArray($tag, $replaceEntities); } return $tag; } } PKu]`=!PEAR/PackageFile/Generator/v1.phpnu[ * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ /** * needed for PEAR_VALIDATE_* constants */ require_once 'PEAR/Validate.php'; require_once 'System.php'; require_once 'PEAR/PackageFile/v2.php'; /** * This class converts a PEAR_PackageFile_v1 object into any output format. * * Supported output formats include array, XML string, and a PEAR_PackageFile_v2 * object, for converting package.xml 1.0 into package.xml 2.0 with no sweat. * @category pear * @package PEAR * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ class PEAR_PackageFile_Generator_v1 { /** * @var PEAR_PackageFile_v1 */ var $_packagefile; function __construct(&$packagefile) { $this->_packagefile = &$packagefile; } function getPackagerVersion() { return '1.10.16'; } /** * @param PEAR_Packager * @param bool if true, a .tgz is written, otherwise a .tar is written * @param string|null directory in which to save the .tgz * @return string|PEAR_Error location of package or error object */ function toTgz(&$packager, $compress = true, $where = null) { require_once 'Archive/Tar.php'; if ($where === null) { if (!($where = System::mktemp(array('-d')))) { return PEAR::raiseError('PEAR_Packagefile_v1::toTgz: mktemp failed'); } } elseif (!@System::mkDir(array('-p', $where))) { return PEAR::raiseError('PEAR_Packagefile_v1::toTgz: "' . $where . '" could' . ' not be created'); } if (file_exists($where . DIRECTORY_SEPARATOR . 'package.xml') && !is_file($where . DIRECTORY_SEPARATOR . 'package.xml')) { return PEAR::raiseError('PEAR_Packagefile_v1::toTgz: unable to save package.xml as' . ' "' . $where . DIRECTORY_SEPARATOR . 'package.xml"'); } if (!$this->_packagefile->validate(PEAR_VALIDATE_PACKAGING)) { return PEAR::raiseError('PEAR_Packagefile_v1::toTgz: invalid package file'); } $pkginfo = $this->_packagefile->getArray(); $ext = $compress ? '.tgz' : '.tar'; $pkgver = $pkginfo['package'] . '-' . $pkginfo['version']; $dest_package = getcwd() . DIRECTORY_SEPARATOR . $pkgver . $ext; if (file_exists(getcwd() . DIRECTORY_SEPARATOR . $pkgver . $ext) && !is_file(getcwd() . DIRECTORY_SEPARATOR . $pkgver . $ext)) { return PEAR::raiseError('PEAR_Packagefile_v1::toTgz: cannot create tgz file "' . getcwd() . DIRECTORY_SEPARATOR . $pkgver . $ext . '"'); } if ($pkgfile = $this->_packagefile->getPackageFile()) { $pkgdir = dirname(realpath($pkgfile)); $pkgfile = basename($pkgfile); } else { return PEAR::raiseError('PEAR_Packagefile_v1::toTgz: package file object must ' . 'be created from a real file'); } // {{{ Create the package file list $filelist = array(); $i = 0; foreach ($this->_packagefile->getFilelist() as $fname => $atts) { $file = $pkgdir . DIRECTORY_SEPARATOR . $fname; if (!file_exists($file)) { return PEAR::raiseError("File does not exist: $fname"); } else { $filelist[$i++] = $file; if (!isset($atts['md5sum'])) { $this->_packagefile->setFileAttribute($fname, 'md5sum', md5_file($file)); } $packager->log(2, "Adding file $fname"); } } // }}} $packagexml = $this->toPackageFile($where, PEAR_VALIDATE_PACKAGING, 'package.xml', true); if ($packagexml) { $tar = new Archive_Tar($dest_package, $compress); $tar->setErrorHandling(PEAR_ERROR_RETURN); // XXX Don't print errors // ----- Creates with the package.xml file $ok = $tar->createModify(array($packagexml), '', $where); if (PEAR::isError($ok)) { return $ok; } elseif (!$ok) { return PEAR::raiseError('PEAR_Packagefile_v1::toTgz: tarball creation failed'); } // ----- Add the content of the package if (!$tar->addModify($filelist, $pkgver, $pkgdir)) { return PEAR::raiseError('PEAR_Packagefile_v1::toTgz: tarball creation failed'); } return $dest_package; } } /** * @param string|null directory to place the package.xml in, or null for a temporary dir * @param int one of the PEAR_VALIDATE_* constants * @param string name of the generated file * @param bool if true, then no analysis will be performed on role="php" files * @return string|PEAR_Error path to the created file on success */ function toPackageFile($where = null, $state = PEAR_VALIDATE_NORMAL, $name = 'package.xml', $nofilechecking = false) { if (!$this->_packagefile->validate($state, $nofilechecking)) { return PEAR::raiseError('PEAR_Packagefile_v1::toPackageFile: invalid package.xml', null, null, null, $this->_packagefile->getValidationWarnings()); } if ($where === null) { if (!($where = System::mktemp(array('-d')))) { return PEAR::raiseError('PEAR_Packagefile_v1::toPackageFile: mktemp failed'); } } elseif (!@System::mkDir(array('-p', $where))) { return PEAR::raiseError('PEAR_Packagefile_v1::toPackageFile: "' . $where . '" could' . ' not be created'); } $newpkgfile = $where . DIRECTORY_SEPARATOR . $name; $np = @fopen($newpkgfile, 'wb'); if (!$np) { return PEAR::raiseError('PEAR_Packagefile_v1::toPackageFile: unable to save ' . "$name as $newpkgfile"); } fwrite($np, $this->toXml($state, true)); fclose($np); return $newpkgfile; } /** * fix both XML encoding to be UTF8, and replace standard XML entities < > " & ' * * @param string $string * @return string * @access private */ function _fixXmlEncoding($string) { return strtr($string, array( '&' => '&', '>' => '>', '<' => '<', '"' => '"', '\'' => ''' )); } /** * Return an XML document based on the package info (as returned * by the PEAR_Common::infoFrom* methods). * * @return string XML data */ function toXml($state = PEAR_VALIDATE_NORMAL, $nofilevalidation = false) { $this->_packagefile->setDate(date('Y-m-d')); if (!$this->_packagefile->validate($state, $nofilevalidation)) { return false; } $pkginfo = $this->_packagefile->getArray(); static $maint_map = array( "handle" => "user", "name" => "name", "email" => "email", "role" => "role", ); $ret = "\n"; $ret .= "\n"; $ret .= "\n" . " $pkginfo[package]"; if (isset($pkginfo['extends'])) { $ret .= "\n$pkginfo[extends]"; } $ret .= "\n ".$this->_fixXmlEncoding($pkginfo['summary'])."\n" . " ".trim($this->_fixXmlEncoding($pkginfo['description']))."\n \n" . " \n"; foreach ($pkginfo['maintainers'] as $maint) { $ret .= " \n"; foreach ($maint_map as $idx => $elm) { $ret .= " <$elm>"; $ret .= $this->_fixXmlEncoding($maint[$idx]); $ret .= "\n"; } $ret .= " \n"; } $ret .= " \n"; $ret .= $this->_makeReleaseXml($pkginfo, false, $state); if (isset($pkginfo['changelog']) && count($pkginfo['changelog']) > 0) { $ret .= " \n"; foreach ($pkginfo['changelog'] as $oldrelease) { $ret .= $this->_makeReleaseXml($oldrelease, true); } $ret .= " \n"; } $ret .= "\n"; return $ret; } // }}} // {{{ _makeReleaseXml() /** * Generate part of an XML description with release information. * * @param array $pkginfo array with release information * @param bool $changelog whether the result will be in a changelog element * * @return string XML data * * @access private */ function _makeReleaseXml($pkginfo, $changelog = false, $state = PEAR_VALIDATE_NORMAL) { // XXX QUOTE ENTITIES IN PCDATA, OR EMBED IN CDATA BLOCKS!! $indent = $changelog ? " " : ""; $ret = "$indent \n"; if (!empty($pkginfo['version'])) { $ret .= "$indent $pkginfo[version]\n"; } if (!empty($pkginfo['release_date'])) { $ret .= "$indent $pkginfo[release_date]\n"; } if (!empty($pkginfo['release_license'])) { $ret .= "$indent $pkginfo[release_license]\n"; } if (!empty($pkginfo['release_state'])) { $ret .= "$indent $pkginfo[release_state]\n"; } if (!empty($pkginfo['release_notes'])) { $ret .= "$indent ".trim($this->_fixXmlEncoding($pkginfo['release_notes'])) ."\n$indent \n"; } if (!empty($pkginfo['release_warnings'])) { $ret .= "$indent ".$this->_fixXmlEncoding($pkginfo['release_warnings'])."\n"; } if (isset($pkginfo['release_deps']) && sizeof($pkginfo['release_deps']) > 0) { $ret .= "$indent \n"; foreach ($pkginfo['release_deps'] as $dep) { $ret .= "$indent _fixXmlEncoding($c['name']) . "\""; if (isset($c['default'])) { $ret .= " default=\"" . $this->_fixXmlEncoding($c['default']) . "\""; } $ret .= " prompt=\"" . $this->_fixXmlEncoding($c['prompt']) . "\""; $ret .= "/>\n"; } $ret .= "$indent \n"; } if (isset($pkginfo['provides'])) { foreach ($pkginfo['provides'] as $key => $what) { $ret .= "$indent recursiveXmlFilelist($pkginfo['filelist']); } else { foreach ($pkginfo['filelist'] as $file => $fa) { if (!isset($fa['role'])) { $fa['role'] = ''; } $ret .= "$indent _fixXmlEncoding($fa['baseinstalldir']) . '"'; } if (isset($fa['md5sum'])) { $ret .= " md5sum=\"$fa[md5sum]\""; } if (isset($fa['platform'])) { $ret .= " platform=\"$fa[platform]\""; } if (!empty($fa['install-as'])) { $ret .= ' install-as="' . $this->_fixXmlEncoding($fa['install-as']) . '"'; } $ret .= ' name="' . $this->_fixXmlEncoding($file) . '"'; if (empty($fa['replacements'])) { $ret .= "/>\n"; } else { $ret .= ">\n"; foreach ($fa['replacements'] as $r) { $ret .= "$indent $v) { $ret .= " $k=\"" . $this->_fixXmlEncoding($v) .'"'; } $ret .= "/>\n"; } $ret .= "$indent \n"; } } } $ret .= "$indent \n"; } $ret .= "$indent \n"; return $ret; } /** * @param array * @access protected */ function recursiveXmlFilelist($list) { $this->_dirs = array(); foreach ($list as $file => $attributes) { $this->_addDir($this->_dirs, explode('/', dirname($file)), $file, $attributes); } return $this->_formatDir($this->_dirs); } /** * @param array * @param array * @param string|null * @param array|null * @access private */ function _addDir(&$dirs, $dir, $file = null, $attributes = null) { if ($dir == array() || $dir == array('.')) { $dirs['files'][basename($file)] = $attributes; return; } $curdir = array_shift($dir); if (!isset($dirs['dirs'][$curdir])) { $dirs['dirs'][$curdir] = array(); } $this->_addDir($dirs['dirs'][$curdir], $dir, $file, $attributes); } /** * @param array * @param string * @param string * @access private */ function _formatDir($dirs, $indent = '', $curdir = '') { $ret = ''; if (!count($dirs)) { return ''; } if (isset($dirs['dirs'])) { uksort($dirs['dirs'], 'strnatcasecmp'); foreach ($dirs['dirs'] as $dir => $contents) { $usedir = "$curdir/$dir"; $ret .= "$indent \n"; $ret .= $this->_formatDir($contents, "$indent ", $usedir); $ret .= "$indent \n"; } } if (isset($dirs['files'])) { uksort($dirs['files'], 'strnatcasecmp'); foreach ($dirs['files'] as $file => $attribs) { $ret .= $this->_formatFile($file, $attribs, $indent); } } return $ret; } /** * @param string * @param array * @param string * @access private */ function _formatFile($file, $attributes, $indent) { $ret = "$indent _fixXmlEncoding($attributes['baseinstalldir']) . '"'; } if (isset($attributes['md5sum'])) { $ret .= " md5sum=\"$attributes[md5sum]\""; } if (isset($attributes['platform'])) { $ret .= " platform=\"$attributes[platform]\""; } if (!empty($attributes['install-as'])) { $ret .= ' install-as="' . $this->_fixXmlEncoding($attributes['install-as']) . '"'; } $ret .= ' name="' . $this->_fixXmlEncoding($file) . '"'; if (empty($attributes['replacements'])) { $ret .= "/>\n"; } else { $ret .= ">\n"; foreach ($attributes['replacements'] as $r) { $ret .= "$indent $v) { $ret .= " $k=\"" . $this->_fixXmlEncoding($v) .'"'; } $ret .= "/>\n"; } $ret .= "$indent \n"; } return $ret; } // {{{ _unIndent() /** * Unindent given string (?) * * @param string $str The string that has to be unindented. * @return string * @access private */ function _unIndent($str) { // remove leading newlines $str = preg_replace('/^[\r\n]+/', '', $str); // find whitespace at the beginning of the first line $indent_len = strspn($str, " \t"); $indent = substr($str, 0, $indent_len); $data = ''; // remove the same amount of whitespace from following lines foreach (explode("\n", $str) as $line) { if (substr($line, 0, $indent_len) == $indent) { $data .= substr($line, $indent_len) . "\n"; } } return $data; } /** * @return array */ function dependenciesToV2() { $arr = array(); $this->_convertDependencies2_0($arr); return $arr['dependencies']; } /** * Convert a package.xml version 1.0 into version 2.0 * * Note that this does a basic conversion, to allow more advanced * features like bundles and multiple releases * @param string the classname to instantiate and return. This must be * PEAR_PackageFile_v2 or a descendant * @param boolean if true, only valid, deterministic package.xml 1.0 as defined by the * strictest parameters will be converted * @return PEAR_PackageFile_v2|PEAR_Error */ function &toV2($class = 'PEAR_PackageFile_v2', $strict = false) { if ($strict) { if (!$this->_packagefile->validate()) { $a = PEAR::raiseError('invalid package.xml version 1.0 cannot be converted' . ' to version 2.0', null, null, null, $this->_packagefile->getValidationWarnings(true)); return $a; } } $arr = array( 'attribs' => array( 'version' => '2.0', 'xmlns' => 'http://pear.php.net/dtd/package-2.0', 'xmlns:tasks' => 'http://pear.php.net/dtd/tasks-1.0', 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', 'xsi:schemaLocation' => "http://pear.php.net/dtd/tasks-1.0\n" . "http://pear.php.net/dtd/tasks-1.0.xsd\n" . "http://pear.php.net/dtd/package-2.0\n" . 'http://pear.php.net/dtd/package-2.0.xsd', ), 'name' => $this->_packagefile->getPackage(), 'channel' => 'pear.php.net', ); $arr['summary'] = $this->_packagefile->getSummary(); $arr['description'] = $this->_packagefile->getDescription(); $maintainers = $this->_packagefile->getMaintainers(); foreach ($maintainers as $maintainer) { if ($maintainer['role'] != 'lead') { continue; } $new = array( 'name' => $maintainer['name'], 'user' => $maintainer['handle'], 'email' => $maintainer['email'], 'active' => 'yes', ); $arr['lead'][] = $new; } if (!isset($arr['lead'])) { // some people... you know? $arr['lead'] = array( 'name' => 'unknown', 'user' => 'unknown', 'email' => 'noleadmaintainer@example.com', 'active' => 'no', ); } if (count($arr['lead']) == 1) { $arr['lead'] = $arr['lead'][0]; } foreach ($maintainers as $maintainer) { if ($maintainer['role'] == 'lead') { continue; } $new = array( 'name' => $maintainer['name'], 'user' => $maintainer['handle'], 'email' => $maintainer['email'], 'active' => 'yes', ); $arr[$maintainer['role']][] = $new; } if (isset($arr['developer']) && count($arr['developer']) == 1) { $arr['developer'] = $arr['developer'][0]; } if (isset($arr['contributor']) && count($arr['contributor']) == 1) { $arr['contributor'] = $arr['contributor'][0]; } if (isset($arr['helper']) && count($arr['helper']) == 1) { $arr['helper'] = $arr['helper'][0]; } $arr['date'] = $this->_packagefile->getDate(); $arr['version'] = array( 'release' => $this->_packagefile->getVersion(), 'api' => $this->_packagefile->getVersion(), ); $arr['stability'] = array( 'release' => $this->_packagefile->getState(), 'api' => $this->_packagefile->getState(), ); $licensemap = array( 'php' => 'http://www.php.net/license', 'php license' => 'http://www.php.net/license', 'lgpl' => 'http://www.gnu.org/copyleft/lesser.html', 'bsd' => 'http://www.opensource.org/licenses/bsd-license.php', 'bsd style' => 'http://www.opensource.org/licenses/bsd-license.php', 'bsd-style' => 'http://www.opensource.org/licenses/bsd-license.php', 'mit' => 'http://www.opensource.org/licenses/mit-license.php', 'gpl' => 'http://www.gnu.org/copyleft/gpl.html', 'apache' => 'http://www.opensource.org/licenses/apache2.0.php' ); if (isset($licensemap[strtolower($this->_packagefile->getLicense())])) { $arr['license'] = array( 'attribs' => array('uri' => $licensemap[strtolower($this->_packagefile->getLicense())]), '_content' => $this->_packagefile->getLicense() ); } else { // don't use bogus uri $arr['license'] = $this->_packagefile->getLicense(); } $arr['notes'] = $this->_packagefile->getNotes(); $temp = array(); $arr['contents'] = $this->_convertFilelist2_0($temp); $this->_convertDependencies2_0($arr); $release = ($this->_packagefile->getConfigureOptions() || $this->_isExtension) ? 'extsrcrelease' : 'phprelease'; if ($release == 'extsrcrelease') { $arr['channel'] = 'pecl.php.net'; $arr['providesextension'] = $arr['name']; // assumption } $arr[$release] = array(); if ($this->_packagefile->getConfigureOptions()) { $arr[$release]['configureoption'] = $this->_packagefile->getConfigureOptions(); foreach ($arr[$release]['configureoption'] as $i => $opt) { $arr[$release]['configureoption'][$i] = array('attribs' => $opt); } if (count($arr[$release]['configureoption']) == 1) { $arr[$release]['configureoption'] = $arr[$release]['configureoption'][0]; } } $this->_convertRelease2_0($arr[$release], $temp); if ($release == 'extsrcrelease' && count($arr[$release]) > 1) { // multiple extsrcrelease tags added in PEAR 1.4.1 $arr['dependencies']['required']['pearinstaller']['min'] = '1.4.1'; } if ($cl = $this->_packagefile->getChangelog()) { foreach ($cl as $release) { $rel = array(); $rel['version'] = array( 'release' => $release['version'], 'api' => $release['version'], ); if (!isset($release['release_state'])) { $release['release_state'] = 'stable'; } $rel['stability'] = array( 'release' => $release['release_state'], 'api' => $release['release_state'], ); if (isset($release['release_date'])) { $rel['date'] = $release['release_date']; } else { $rel['date'] = date('Y-m-d'); } if (isset($release['release_license'])) { if (isset($licensemap[strtolower($release['release_license'])])) { $uri = $licensemap[strtolower($release['release_license'])]; } else { $uri = 'http://www.example.com'; } $rel['license'] = array( 'attribs' => array('uri' => $uri), '_content' => $release['release_license'] ); } else { $rel['license'] = $arr['license']; } if (!isset($release['release_notes'])) { $release['release_notes'] = 'no release notes'; } $rel['notes'] = $release['release_notes']; $arr['changelog']['release'][] = $rel; } } $ret = new $class; $ret->setConfig($this->_packagefile->_config); if (isset($this->_packagefile->_logger) && is_object($this->_packagefile->_logger)) { $ret->setLogger($this->_packagefile->_logger); } $ret->fromArray($arr); return $ret; } /** * @param array * @param bool * @access private */ function _convertDependencies2_0(&$release, $internal = false) { $peardep = array('pearinstaller' => array('min' => '1.4.0b1')); // this is a lot safer $required = $optional = array(); $release['dependencies'] = array('required' => array()); if ($this->_packagefile->hasDeps()) { foreach ($this->_packagefile->getDeps() as $dep) { if (!isset($dep['optional']) || $dep['optional'] == 'no') { $required[] = $dep; } else { $optional[] = $dep; } } foreach (array('required', 'optional') as $arr) { $deps = array(); foreach ($$arr as $dep) { // organize deps by dependency type and name if (!isset($deps[$dep['type']])) { $deps[$dep['type']] = array(); } if (isset($dep['name'])) { $deps[$dep['type']][$dep['name']][] = $dep; } else { $deps[$dep['type']][] = $dep; } } do { if (isset($deps['php'])) { $php = array(); if (count($deps['php']) > 1) { $php = $this->_processPhpDeps($deps['php']); } else { if (!isset($deps['php'][0])) { // Buggy versions $key = key($deps['php']); $info = current($deps['php']); $deps['php'] = array($info[0]); } $php = $this->_processDep($deps['php'][0]); if (!$php) { break; // poor mans throw } } $release['dependencies'][$arr]['php'] = $php; } } while (false); do { if (isset($deps['pkg'])) { $pkg = array(); $pkg = $this->_processMultipleDepsName($deps['pkg']); if (!$pkg) { break; // poor mans throw } $release['dependencies'][$arr]['package'] = $pkg; } } while (false); do { if (isset($deps['ext'])) { $pkg = array(); $pkg = $this->_processMultipleDepsName($deps['ext']); $release['dependencies'][$arr]['extension'] = $pkg; } } while (false); // skip sapi - it's not supported so nobody will have used it // skip os - it's not supported in 1.0 } } if (isset($release['dependencies']['required'])) { $release['dependencies']['required'] = array_merge($peardep, $release['dependencies']['required']); } else { $release['dependencies']['required'] = $peardep; } if (!isset($release['dependencies']['required']['php'])) { $release['dependencies']['required']['php'] = array('min' => '4.0.0'); } $order = array(); $bewm = $release['dependencies']['required']; $order['php'] = $bewm['php']; $order['pearinstaller'] = $bewm['pearinstaller']; isset($bewm['package']) ? $order['package'] = $bewm['package'] :0; isset($bewm['extension']) ? $order['extension'] = $bewm['extension'] :0; $release['dependencies']['required'] = $order; } /** * @param array * @access private */ function _convertFilelist2_0(&$package) { $ret = array('dir' => array( 'attribs' => array('name' => '/'), 'file' => array() ) ); $package['platform'] = $package['install-as'] = array(); $this->_isExtension = false; foreach ($this->_packagefile->getFilelist() as $name => $file) { $file['name'] = $name; if (isset($file['role']) && $file['role'] == 'src') { $this->_isExtension = true; } if (isset($file['replacements'])) { $repl = $file['replacements']; unset($file['replacements']); } else { unset($repl); } if (isset($file['install-as'])) { $package['install-as'][$name] = $file['install-as']; unset($file['install-as']); } if (isset($file['platform'])) { $package['platform'][$name] = $file['platform']; unset($file['platform']); } $file = array('attribs' => $file); if (isset($repl)) { foreach ($repl as $replace ) { $file['tasks:replace'][] = array('attribs' => $replace); } if (count($repl) == 1) { $file['tasks:replace'] = $file['tasks:replace'][0]; } } $ret['dir']['file'][] = $file; } return $ret; } /** * Post-process special files with install-as/platform attributes and * make the release tag. * * This complex method follows this work-flow to create the release tags: * *
     * - if any install-as/platform exist, create a generic release and fill it with
     *   o  tags for 
     *   o  tags for 
     *   o  tags for 
     *   o  tags for 
     * - create a release for each platform encountered and fill with
     *   o  tags for 
     *   o  tags for 
     *   o  tags for 
     *   o  tags for 
     *   o  tags for 
     *   o  tags for 
     *   o  tags for 
     * 
* * It does this by accessing the $package parameter, which contains an array with * indices: * * - platform: mapping of file => OS the file should be installed on * - install-as: mapping of file => installed name * - osmap: mapping of OS => list of files that should be installed * on that OS * - notosmap: mapping of OS => list of files that should not be * installed on that OS * * @param array * @param array * @access private */ function _convertRelease2_0(&$release, $package) { //- if any install-as/platform exist, create a generic release and fill it with if (count($package['platform']) || count($package['install-as'])) { $generic = array(); $genericIgnore = array(); foreach ($package['install-as'] as $file => $as) { //o tags for if (!isset($package['platform'][$file])) { $generic[] = $file; continue; } //o tags for if (isset($package['platform'][$file]) && $package['platform'][$file][0] == '!') { $generic[] = $file; continue; } //o tags for if (isset($package['platform'][$file]) && $package['platform'][$file][0] != '!') { $genericIgnore[] = $file; continue; } } foreach ($package['platform'] as $file => $platform) { if (isset($package['install-as'][$file])) { continue; } if ($platform[0] != '!') { //o tags for $genericIgnore[] = $file; } } if (count($package['platform'])) { $oses = $notplatform = $platform = array(); foreach ($package['platform'] as $file => $os) { // get a list of oses if ($os[0] == '!') { if (isset($oses[substr($os, 1)])) { continue; } $oses[substr($os, 1)] = count($oses); } else { if (isset($oses[$os])) { continue; } $oses[$os] = count($oses); } } //- create a release for each platform encountered and fill with foreach ($oses as $os => $releaseNum) { $release[$releaseNum]['installconditions']['os']['name'] = $os; $release[$releaseNum]['filelist'] = array('install' => array(), 'ignore' => array()); foreach ($package['install-as'] as $file => $as) { //o tags for if (!isset($package['platform'][$file])) { $release[$releaseNum]['filelist']['install'][] = array( 'attribs' => array( 'name' => $file, 'as' => $as, ), ); continue; } //o tags for // if (isset($package['platform'][$file]) && $package['platform'][$file] == $os) { $release[$releaseNum]['filelist']['install'][] = array( 'attribs' => array( 'name' => $file, 'as' => $as, ), ); continue; } //o tags for // if (isset($package['platform'][$file]) && $package['platform'][$file] != "!$os" && $package['platform'][$file][0] == '!') { $release[$releaseNum]['filelist']['install'][] = array( 'attribs' => array( 'name' => $file, 'as' => $as, ), ); continue; } //o tags for // if (isset($package['platform'][$file]) && $package['platform'][$file] == "!$os") { $release[$releaseNum]['filelist']['ignore'][] = array( 'attribs' => array( 'name' => $file, ), ); continue; } //o tags for // if (isset($package['platform'][$file]) && $package['platform'][$file][0] != '!' && $package['platform'][$file] != $os) { $release[$releaseNum]['filelist']['ignore'][] = array( 'attribs' => array( 'name' => $file, ), ); continue; } } foreach ($package['platform'] as $file => $platform) { if (isset($package['install-as'][$file])) { continue; } //o tags for if ($platform == "!$os") { $release[$releaseNum]['filelist']['ignore'][] = array( 'attribs' => array( 'name' => $file, ), ); continue; } //o tags for if ($platform[0] != '!' && $platform != $os) { $release[$releaseNum]['filelist']['ignore'][] = array( 'attribs' => array( 'name' => $file, ), ); } } if (!count($release[$releaseNum]['filelist']['install'])) { unset($release[$releaseNum]['filelist']['install']); } if (!count($release[$releaseNum]['filelist']['ignore'])) { unset($release[$releaseNum]['filelist']['ignore']); } } if (count($generic) || count($genericIgnore)) { $release[count($oses)] = array(); if (count($generic)) { foreach ($generic as $file) { if (isset($package['install-as'][$file])) { $installas = $package['install-as'][$file]; } else { $installas = $file; } $release[count($oses)]['filelist']['install'][] = array( 'attribs' => array( 'name' => $file, 'as' => $installas, ) ); } } if (count($genericIgnore)) { foreach ($genericIgnore as $file) { $release[count($oses)]['filelist']['ignore'][] = array( 'attribs' => array( 'name' => $file, ) ); } } } // cleanup foreach ($release as $i => $rel) { if (isset($rel['filelist']['install']) && count($rel['filelist']['install']) == 1) { $release[$i]['filelist']['install'] = $release[$i]['filelist']['install'][0]; } if (isset($rel['filelist']['ignore']) && count($rel['filelist']['ignore']) == 1) { $release[$i]['filelist']['ignore'] = $release[$i]['filelist']['ignore'][0]; } } if (count($release) == 1) { $release = $release[0]; } } else { // no platform atts, but some install-as atts foreach ($package['install-as'] as $file => $value) { $release['filelist']['install'][] = array( 'attribs' => array( 'name' => $file, 'as' => $value ) ); } if (count($release['filelist']['install']) == 1) { $release['filelist']['install'] = $release['filelist']['install'][0]; } } } } /** * @param array * @return array * @access private */ function _processDep($dep) { if ($dep['type'] == 'php') { if ($dep['rel'] == 'has') { // come on - everyone has php! return false; } } $php = array(); if ($dep['type'] != 'php') { $php['name'] = $dep['name']; if ($dep['type'] == 'pkg') { $php['channel'] = 'pear.php.net'; } } switch ($dep['rel']) { case 'gt' : $php['min'] = $dep['version']; $php['exclude'] = $dep['version']; break; case 'ge' : if (!isset($dep['version'])) { if ($dep['type'] == 'php') { if (isset($dep['name'])) { $dep['version'] = $dep['name']; } } } $php['min'] = $dep['version']; break; case 'lt' : $php['max'] = $dep['version']; $php['exclude'] = $dep['version']; break; case 'le' : $php['max'] = $dep['version']; break; case 'eq' : $php['min'] = $dep['version']; $php['max'] = $dep['version']; break; case 'ne' : $php['exclude'] = $dep['version']; break; case 'not' : $php['conflicts'] = 'yes'; break; } return $php; } /** * @param array * @return array */ function _processPhpDeps($deps) { $test = array(); foreach ($deps as $dep) { $test[] = $this->_processDep($dep); } $min = array(); $max = array(); foreach ($test as $dep) { if (!$dep) { continue; } if (isset($dep['min'])) { $min[$dep['min']] = count($min); } if (isset($dep['max'])) { $max[$dep['max']] = count($max); } } if (count($min) > 0) { uksort($min, 'version_compare'); } if (count($max) > 0) { uksort($max, 'version_compare'); } if (count($min)) { // get the highest minimum $a = array_flip($min); $min = array_pop($a); } else { $min = false; } if (count($max)) { // get the lowest maximum $a = array_flip($max); $max = array_shift($a); } else { $max = false; } if ($min) { $php['min'] = $min; } if ($max) { $php['max'] = $max; } $exclude = array(); foreach ($test as $dep) { if (!isset($dep['exclude'])) { continue; } $exclude[] = $dep['exclude']; } if (count($exclude)) { $php['exclude'] = $exclude; } return $php; } /** * process multiple dependencies that have a name, like package deps * @param array * @return array * @access private */ function _processMultipleDepsName($deps) { $ret = $tests = array(); foreach ($deps as $name => $dep) { foreach ($dep as $d) { $tests[$name][] = $this->_processDep($d); } } foreach ($tests as $name => $test) { $max = $min = $php = array(); $php['name'] = $name; foreach ($test as $dep) { if (!$dep) { continue; } if (isset($dep['channel'])) { $php['channel'] = 'pear.php.net'; } if (isset($dep['conflicts']) && $dep['conflicts'] == 'yes') { $php['conflicts'] = 'yes'; } if (isset($dep['min'])) { $min[$dep['min']] = count($min); } if (isset($dep['max'])) { $max[$dep['max']] = count($max); } } if (count($min) > 0) { uksort($min, 'version_compare'); } if (count($max) > 0) { uksort($max, 'version_compare'); } if (count($min)) { // get the highest minimum $a = array_flip($min); $min = array_pop($a); } else { $min = false; } if (count($max)) { // get the lowest maximum $a = array_flip($max); $max = array_shift($a); } else { $max = false; } if ($min) { $php['min'] = $min; } if ($max) { $php['max'] = $max; } $exclude = array(); foreach ($test as $dep) { if (!isset($dep['exclude'])) { continue; } $exclude[] = $dep['exclude']; } if (count($exclude)) { $php['exclude'] = $exclude; } $ret[] = $php; } return $ret; } } ?> PKu]5PEAR/PackageFile/v1.phpnu[ * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ /** * For error handling */ require_once 'PEAR/ErrorStack.php'; /** * Error code if parsing is attempted with no xml extension */ define('PEAR_PACKAGEFILE_ERROR_NO_XML_EXT', 3); /** * Error code if creating the xml parser resource fails */ define('PEAR_PACKAGEFILE_ERROR_CANT_MAKE_PARSER', 4); /** * Error code used for all sax xml parsing errors */ define('PEAR_PACKAGEFILE_ERROR_PARSER_ERROR', 5); /** * Error code used when there is no name */ define('PEAR_PACKAGEFILE_ERROR_NO_NAME', 6); /** * Error code when a package name is not valid */ define('PEAR_PACKAGEFILE_ERROR_INVALID_NAME', 7); /** * Error code used when no summary is parsed */ define('PEAR_PACKAGEFILE_ERROR_NO_SUMMARY', 8); /** * Error code for summaries that are more than 1 line */ define('PEAR_PACKAGEFILE_ERROR_MULTILINE_SUMMARY', 9); /** * Error code used when no description is present */ define('PEAR_PACKAGEFILE_ERROR_NO_DESCRIPTION', 10); /** * Error code used when no license is present */ define('PEAR_PACKAGEFILE_ERROR_NO_LICENSE', 11); /** * Error code used when a version number is not present */ define('PEAR_PACKAGEFILE_ERROR_NO_VERSION', 12); /** * Error code used when a version number is invalid */ define('PEAR_PACKAGEFILE_ERROR_INVALID_VERSION', 13); /** * Error code when release state is missing */ define('PEAR_PACKAGEFILE_ERROR_NO_STATE', 14); /** * Error code when release state is invalid */ define('PEAR_PACKAGEFILE_ERROR_INVALID_STATE', 15); /** * Error code when release state is missing */ define('PEAR_PACKAGEFILE_ERROR_NO_DATE', 16); /** * Error code when release state is invalid */ define('PEAR_PACKAGEFILE_ERROR_INVALID_DATE', 17); /** * Error code when no release notes are found */ define('PEAR_PACKAGEFILE_ERROR_NO_NOTES', 18); /** * Error code when no maintainers are found */ define('PEAR_PACKAGEFILE_ERROR_NO_MAINTAINERS', 19); /** * Error code when a maintainer has no handle */ define('PEAR_PACKAGEFILE_ERROR_NO_MAINTHANDLE', 20); /** * Error code when a maintainer has no handle */ define('PEAR_PACKAGEFILE_ERROR_NO_MAINTROLE', 21); /** * Error code when a maintainer has no name */ define('PEAR_PACKAGEFILE_ERROR_NO_MAINTNAME', 22); /** * Error code when a maintainer has no email */ define('PEAR_PACKAGEFILE_ERROR_NO_MAINTEMAIL', 23); /** * Error code when a maintainer has no handle */ define('PEAR_PACKAGEFILE_ERROR_INVALID_MAINTROLE', 24); /** * Error code when a dependency is not a PHP dependency, but has no name */ define('PEAR_PACKAGEFILE_ERROR_NO_DEPNAME', 25); /** * Error code when a dependency has no type (pkg, php, etc.) */ define('PEAR_PACKAGEFILE_ERROR_NO_DEPTYPE', 26); /** * Error code when a dependency has no relation (lt, ge, has, etc.) */ define('PEAR_PACKAGEFILE_ERROR_NO_DEPREL', 27); /** * Error code when a dependency is not a 'has' relation, but has no version */ define('PEAR_PACKAGEFILE_ERROR_NO_DEPVERSION', 28); /** * Error code when a dependency has an invalid relation */ define('PEAR_PACKAGEFILE_ERROR_INVALID_DEPREL', 29); /** * Error code when a dependency has an invalid type */ define('PEAR_PACKAGEFILE_ERROR_INVALID_DEPTYPE', 30); /** * Error code when a dependency has an invalid optional option */ define('PEAR_PACKAGEFILE_ERROR_INVALID_DEPOPTIONAL', 31); /** * Error code when a dependency is a pkg dependency, and has an invalid package name */ define('PEAR_PACKAGEFILE_ERROR_INVALID_DEPNAME', 32); /** * Error code when a dependency has a channel="foo" attribute, and foo is not a registered channel */ define('PEAR_PACKAGEFILE_ERROR_UNKNOWN_DEPCHANNEL', 33); /** * Error code when rel="has" and version attribute is present. */ define('PEAR_PACKAGEFILE_ERROR_DEPVERSION_IGNORED', 34); /** * Error code when type="php" and dependency name is present */ define('PEAR_PACKAGEFILE_ERROR_DEPNAME_IGNORED', 35); /** * Error code when a configure option has no name */ define('PEAR_PACKAGEFILE_ERROR_NO_CONFNAME', 36); /** * Error code when a configure option has no name */ define('PEAR_PACKAGEFILE_ERROR_NO_CONFPROMPT', 37); /** * Error code when a file in the filelist has an invalid role */ define('PEAR_PACKAGEFILE_ERROR_INVALID_FILEROLE', 38); /** * Error code when a file in the filelist has no role */ define('PEAR_PACKAGEFILE_ERROR_NO_FILEROLE', 39); /** * Error code when analyzing a php source file that has parse errors */ define('PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE', 40); /** * Error code when analyzing a php source file reveals a source element * without a package name prefix */ define('PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX', 41); /** * Error code when an unknown channel is specified */ define('PEAR_PACKAGEFILE_ERROR_UNKNOWN_CHANNEL', 42); /** * Error code when no files are found in the filelist */ define('PEAR_PACKAGEFILE_ERROR_NO_FILES', 43); /** * Error code when a file is not valid php according to _analyzeSourceCode() */ define('PEAR_PACKAGEFILE_ERROR_INVALID_FILE', 44); /** * Error code when the channel validator returns an error or warning */ define('PEAR_PACKAGEFILE_ERROR_CHANNELVAL', 45); /** * Error code when a php5 package is packaged in php4 (analysis doesn't work) */ define('PEAR_PACKAGEFILE_ERROR_PHP5', 46); /** * Error code when a file is listed in package.xml but does not exist */ define('PEAR_PACKAGEFILE_ERROR_FILE_NOTFOUND', 47); /** * Error code when a * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ class PEAR_PackageFile_v1 { /** * @access private * @var PEAR_ErrorStack * @access private */ var $_stack; /** * A registry object, used to access the package name validation regex for non-standard channels * @var PEAR_Registry * @access private */ var $_registry; /** * An object that contains a log method that matches PEAR_Common::log's signature * @var object * @access private */ var $_logger; /** * Parsed package information * @var array * @access private */ var $_packageInfo; /** * path to package.xml * @var string * @access private */ var $_packageFile; /** * path to package .tgz or false if this is a local/extracted package.xml * @var string * @access private */ var $_archiveFile; /** * @var int * @access private */ var $_isValid = 0; /** * Determines whether this packagefile was initialized only with partial package info * * If this package file was constructed via parsing REST, it will only contain * * - package name * - channel name * - dependencies * @var boolean * @access private */ var $_incomplete = true; /** * @param bool determines whether to return a PEAR_Error object, or use the PEAR_ErrorStack * @param string Name of Error Stack class to use. */ function __construct() { $this->_stack = new PEAR_ErrorStack('PEAR_PackageFile_v1'); $this->_stack->setErrorMessageTemplate($this->_getErrorMessage()); $this->_isValid = 0; } function installBinary($installer) { return false; } function isExtension($name) { return false; } function setConfig(&$config) { $this->_config = &$config; $this->_registry = &$config->getRegistry(); } function setRequestedGroup() { // placeholder } /** * For saving in the registry. * * Set the last version that was installed * @param string */ function setLastInstalledVersion($version) { $this->_packageInfo['_lastversion'] = $version; } /** * @return string|false */ function getLastInstalledVersion() { if (isset($this->_packageInfo['_lastversion'])) { return $this->_packageInfo['_lastversion']; } return false; } function getInstalledBinary() { return false; } function listPostinstallScripts() { return false; } function initPostinstallScripts() { return false; } function setLogger(&$logger) { if ($logger && (!is_object($logger) || !method_exists($logger, 'log'))) { return PEAR::raiseError('Logger must be compatible with PEAR_Common::log'); } $this->_logger = &$logger; } function setPackagefile($file, $archive = false) { $this->_packageFile = $file; $this->_archiveFile = $archive ? $archive : $file; } function getPackageFile() { return isset($this->_packageFile) ? $this->_packageFile : false; } function getPackageType() { return 'php'; } function getArchiveFile() { return $this->_archiveFile; } function packageInfo($field) { if (!is_string($field) || empty($field) || !isset($this->_packageInfo[$field])) { return false; } return $this->_packageInfo[$field]; } function setDirtree($path) { if (!isset($this->_packageInfo['dirtree'])) { $this->_packageInfo['dirtree'] = array(); } $this->_packageInfo['dirtree'][$path] = true; } function getDirtree() { if (isset($this->_packageInfo['dirtree']) && count($this->_packageInfo['dirtree'])) { return $this->_packageInfo['dirtree']; } return false; } function resetDirtree() { unset($this->_packageInfo['dirtree']); } function fromArray($pinfo) { $this->_incomplete = false; $this->_packageInfo = $pinfo; } function isIncomplete() { return $this->_incomplete; } function getChannel() { return 'pear.php.net'; } function getUri() { return false; } function getTime() { return false; } function getExtends() { if (isset($this->_packageInfo['extends'])) { return $this->_packageInfo['extends']; } return false; } /** * @return array */ function toArray() { if (!$this->validate(PEAR_VALIDATE_NORMAL)) { return false; } return $this->getArray(); } function getArray() { return $this->_packageInfo; } function getName() { return $this->getPackage(); } function getPackage() { if (isset($this->_packageInfo['package'])) { return $this->_packageInfo['package']; } return false; } /** * WARNING - don't use this unless you know what you are doing */ function setRawPackage($package) { $this->_packageInfo['package'] = $package; } function setPackage($package) { $this->_packageInfo['package'] = $package; $this->_isValid = false; } function getVersion() { if (isset($this->_packageInfo['version'])) { return $this->_packageInfo['version']; } return false; } function setVersion($version) { $this->_packageInfo['version'] = $version; $this->_isValid = false; } function clearMaintainers() { unset($this->_packageInfo['maintainers']); } function getMaintainers() { if (isset($this->_packageInfo['maintainers'])) { return $this->_packageInfo['maintainers']; } return false; } /** * Adds a new maintainer - no checking of duplicates is performed, use * updatemaintainer for that purpose. */ function addMaintainer($role, $handle, $name, $email) { $this->_packageInfo['maintainers'][] = array('handle' => $handle, 'role' => $role, 'email' => $email, 'name' => $name); $this->_isValid = false; } function updateMaintainer($role, $handle, $name, $email) { $found = false; if (!isset($this->_packageInfo['maintainers']) || !is_array($this->_packageInfo['maintainers'])) { return $this->addMaintainer($role, $handle, $name, $email); } foreach ($this->_packageInfo['maintainers'] as $i => $maintainer) { if ($maintainer['handle'] == $handle) { $found = $i; break; } } if ($found !== false) { unset($this->_packageInfo['maintainers'][$found]); $this->_packageInfo['maintainers'] = array_values($this->_packageInfo['maintainers']); } $this->addMaintainer($role, $handle, $name, $email); } function deleteMaintainer($handle) { $found = false; foreach ($this->_packageInfo['maintainers'] as $i => $maintainer) { if ($maintainer['handle'] == $handle) { $found = $i; break; } } if ($found !== false) { unset($this->_packageInfo['maintainers'][$found]); $this->_packageInfo['maintainers'] = array_values($this->_packageInfo['maintainers']); return true; } return false; } function getState() { if (isset($this->_packageInfo['release_state'])) { return $this->_packageInfo['release_state']; } return false; } function setRawState($state) { $this->_packageInfo['release_state'] = $state; } function setState($state) { $this->_packageInfo['release_state'] = $state; $this->_isValid = false; } function getDate() { if (isset($this->_packageInfo['release_date'])) { return $this->_packageInfo['release_date']; } return false; } function setDate($date) { $this->_packageInfo['release_date'] = $date; $this->_isValid = false; } function getLicense() { if (isset($this->_packageInfo['release_license'])) { return $this->_packageInfo['release_license']; } return false; } function setLicense($date) { $this->_packageInfo['release_license'] = $date; $this->_isValid = false; } function getSummary() { if (isset($this->_packageInfo['summary'])) { return $this->_packageInfo['summary']; } return false; } function setSummary($summary) { $this->_packageInfo['summary'] = $summary; $this->_isValid = false; } function getDescription() { if (isset($this->_packageInfo['description'])) { return $this->_packageInfo['description']; } return false; } function setDescription($desc) { $this->_packageInfo['description'] = $desc; $this->_isValid = false; } function getNotes() { if (isset($this->_packageInfo['release_notes'])) { return $this->_packageInfo['release_notes']; } return false; } function setNotes($notes) { $this->_packageInfo['release_notes'] = $notes; $this->_isValid = false; } function getDeps() { if (isset($this->_packageInfo['release_deps'])) { return $this->_packageInfo['release_deps']; } return false; } /** * Reset dependencies prior to adding new ones */ function clearDeps() { unset($this->_packageInfo['release_deps']); } function addPhpDep($version, $rel) { $this->_isValid = false; $this->_packageInfo['release_deps'][] = array('type' => 'php', 'rel' => $rel, 'version' => $version); } function addPackageDep($name, $version, $rel, $optional = 'no') { $this->_isValid = false; $dep = array('type' => 'pkg', 'name' => $name, 'rel' => $rel, 'optional' => $optional); if ($rel != 'has' && $rel != 'not') { $dep['version'] = $version; } $this->_packageInfo['release_deps'][] = $dep; } function addExtensionDep($name, $version, $rel, $optional = 'no') { $this->_isValid = false; $this->_packageInfo['release_deps'][] = array('type' => 'ext', 'name' => $name, 'rel' => $rel, 'version' => $version, 'optional' => $optional); } /** * WARNING - do not use this function directly unless you know what you're doing */ function setDeps($deps) { $this->_packageInfo['release_deps'] = $deps; } function hasDeps() { return isset($this->_packageInfo['release_deps']) && count($this->_packageInfo['release_deps']); } function getDependencyGroup($group) { return false; } function isCompatible($pf) { return false; } function isSubpackageOf($p) { return $p->isSubpackage($this); } function isSubpackage($p) { return false; } function dependsOn($package, $channel) { if (strtolower($channel) != 'pear.php.net') { return false; } if (!($deps = $this->getDeps())) { return false; } foreach ($deps as $dep) { if ($dep['type'] != 'pkg') { continue; } if (strtolower($dep['name']) == strtolower($package)) { return true; } } return false; } function getConfigureOptions() { if (isset($this->_packageInfo['configure_options'])) { return $this->_packageInfo['configure_options']; } return false; } function hasConfigureOptions() { return isset($this->_packageInfo['configure_options']) && count($this->_packageInfo['configure_options']); } function addConfigureOption($name, $prompt, $default = false) { $o = array('name' => $name, 'prompt' => $prompt); if ($default !== false) { $o['default'] = $default; } if (!isset($this->_packageInfo['configure_options'])) { $this->_packageInfo['configure_options'] = array(); } $this->_packageInfo['configure_options'][] = $o; } function clearConfigureOptions() { unset($this->_packageInfo['configure_options']); } function getProvides() { if (isset($this->_packageInfo['provides'])) { return $this->_packageInfo['provides']; } return false; } function getProvidesExtension() { return false; } function addFile($dir, $file, $attrs) { $dir = preg_replace(array('!\\\\+!', '!/+!'), array('/', '/'), $dir); if ($dir == '/' || $dir == '') { $dir = ''; } else { $dir .= '/'; } $file = $dir . $file; $file = preg_replace('![\\/]+!', '/', $file); $this->_packageInfo['filelist'][$file] = $attrs; } function getInstallationFilelist() { return $this->getFilelist(); } function getFilelist() { if (isset($this->_packageInfo['filelist'])) { return $this->_packageInfo['filelist']; } return false; } function setFileAttribute($file, $attr, $value) { $this->_packageInfo['filelist'][$file][$attr] = $value; } function resetFilelist() { $this->_packageInfo['filelist'] = array(); } function setInstalledAs($file, $path) { if ($path) { return $this->_packageInfo['filelist'][$file]['installed_as'] = $path; } unset($this->_packageInfo['filelist'][$file]['installed_as']); } function installedFile($file, $atts) { if (isset($this->_packageInfo['filelist'][$file])) { $this->_packageInfo['filelist'][$file] = array_merge($this->_packageInfo['filelist'][$file], $atts); } else { $this->_packageInfo['filelist'][$file] = $atts; } } function getChangelog() { if (isset($this->_packageInfo['changelog'])) { return $this->_packageInfo['changelog']; } return false; } function getPackagexmlVersion() { return '1.0'; } /** * Wrapper to {@link PEAR_ErrorStack::getErrors()} * @param boolean determines whether to purge the error stack after retrieving * @return array */ function getValidationWarnings($purge = true) { return $this->_stack->getErrors($purge); } // }}} /** * Validation error. Also marks the object contents as invalid * @param error code * @param array error information * @access private */ function _validateError($code, $params = array()) { $this->_stack->push($code, 'error', $params, false, false, debug_backtrace()); $this->_isValid = false; } /** * Validation warning. Does not mark the object contents invalid. * @param error code * @param array error information * @access private */ function _validateWarning($code, $params = array()) { $this->_stack->push($code, 'warning', $params, false, false, debug_backtrace()); } /** * @param integer error code * @access protected */ function _getErrorMessage() { return array( PEAR_PACKAGEFILE_ERROR_NO_NAME => 'Missing Package Name', PEAR_PACKAGEFILE_ERROR_NO_SUMMARY => 'No summary found', PEAR_PACKAGEFILE_ERROR_MULTILINE_SUMMARY => 'Summary should be on one line', PEAR_PACKAGEFILE_ERROR_NO_DESCRIPTION => 'Missing description', PEAR_PACKAGEFILE_ERROR_NO_LICENSE => 'Missing license', PEAR_PACKAGEFILE_ERROR_NO_VERSION => 'No release version found', PEAR_PACKAGEFILE_ERROR_NO_STATE => 'No release state found', PEAR_PACKAGEFILE_ERROR_NO_DATE => 'No release date found', PEAR_PACKAGEFILE_ERROR_NO_NOTES => 'No release notes found', PEAR_PACKAGEFILE_ERROR_NO_LEAD => 'Package must have at least one lead maintainer', PEAR_PACKAGEFILE_ERROR_NO_MAINTAINERS => 'No maintainers found, at least one must be defined', PEAR_PACKAGEFILE_ERROR_NO_MAINTHANDLE => 'Maintainer %index% has no handle (user ID at channel server)', PEAR_PACKAGEFILE_ERROR_NO_MAINTROLE => 'Maintainer %index% has no role', PEAR_PACKAGEFILE_ERROR_NO_MAINTNAME => 'Maintainer %index% has no name', PEAR_PACKAGEFILE_ERROR_NO_MAINTEMAIL => 'Maintainer %index% has no email', PEAR_PACKAGEFILE_ERROR_NO_DEPNAME => 'Dependency %index% is not a php dependency, and has no name', PEAR_PACKAGEFILE_ERROR_NO_DEPREL => 'Dependency %index% has no relation (rel)', PEAR_PACKAGEFILE_ERROR_NO_DEPTYPE => 'Dependency %index% has no type', PEAR_PACKAGEFILE_ERROR_DEPNAME_IGNORED => 'PHP Dependency %index% has a name attribute of "%name%" which will be' . ' ignored!', PEAR_PACKAGEFILE_ERROR_NO_DEPVERSION => 'Dependency %index% is not a rel="has" or rel="not" dependency, ' . 'and has no version', PEAR_PACKAGEFILE_ERROR_NO_DEPPHPVERSION => 'Dependency %index% is a type="php" dependency, ' . 'and has no version', PEAR_PACKAGEFILE_ERROR_DEPVERSION_IGNORED => 'Dependency %index% is a rel="%rel%" dependency, versioning is ignored', PEAR_PACKAGEFILE_ERROR_INVALID_DEPOPTIONAL => 'Dependency %index% has invalid optional value "%opt%", should be yes or no', PEAR_PACKAGEFILE_PHP_NO_NOT => 'Dependency %index%: php dependencies cannot use "not" rel, use "ne"' . ' to exclude specific versions', PEAR_PACKAGEFILE_ERROR_NO_CONFNAME => 'Configure Option %index% has no name', PEAR_PACKAGEFILE_ERROR_NO_CONFPROMPT => 'Configure Option %index% has no prompt', PEAR_PACKAGEFILE_ERROR_NO_FILES => 'No files in section of package.xml', PEAR_PACKAGEFILE_ERROR_NO_FILEROLE => 'File "%file%" has no role, expecting one of "%roles%"', PEAR_PACKAGEFILE_ERROR_INVALID_FILEROLE => 'File "%file%" has invalid role "%role%", expecting one of "%roles%"', PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME => 'File "%file%" cannot start with ".", cannot package or install', PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE => 'Parser error: invalid PHP found in file "%file%"', PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX => 'in %file%: %type% "%name%" not prefixed with package name "%package%"', PEAR_PACKAGEFILE_ERROR_INVALID_FILE => 'Parser error: invalid PHP file "%file%"', PEAR_PACKAGEFILE_ERROR_CHANNELVAL => 'Channel validator error: field "%field%" - %reason%', PEAR_PACKAGEFILE_ERROR_PHP5 => 'Error, PHP5 token encountered in %file%, analysis should be in PHP5', PEAR_PACKAGEFILE_ERROR_FILE_NOTFOUND => 'File "%file%" in package.xml does not exist', PEAR_PACKAGEFILE_ERROR_NON_ISO_CHARS => 'Package.xml contains non-ISO-8859-1 characters, and may not validate', ); } /** * Validate XML package definition file. * * @access public * @return boolean */ function validate($state = PEAR_VALIDATE_NORMAL, $nofilechecking = false) { if (($this->_isValid & $state) == $state) { return true; } $this->_isValid = true; $info = $this->_packageInfo; if (empty($info['package'])) { $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_NAME); $this->_packageName = $pn = 'unknown'; } else { $this->_packageName = $pn = $info['package']; } if (empty($info['summary'])) { $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_SUMMARY); } elseif (strpos(trim($info['summary']), "\n") !== false) { $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_MULTILINE_SUMMARY, array('summary' => $info['summary'])); } if (empty($info['description'])) { $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DESCRIPTION); } if (empty($info['release_license'])) { $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_LICENSE); } if (empty($info['version'])) { $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_VERSION); } if (empty($info['release_state'])) { $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_STATE); } if (empty($info['release_date'])) { $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DATE); } if (empty($info['release_notes'])) { $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_NOTES); } if (empty($info['maintainers'])) { $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTAINERS); } else { $haslead = false; $i = 1; foreach ($info['maintainers'] as $m) { if (empty($m['handle'])) { $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTHANDLE, array('index' => $i)); } if (empty($m['role'])) { $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTROLE, array('index' => $i, 'roles' => PEAR_Common::getUserRoles())); } elseif ($m['role'] == 'lead') { $haslead = true; } if (empty($m['name'])) { $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTNAME, array('index' => $i)); } if (empty($m['email'])) { $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTEMAIL, array('index' => $i)); } $i++; } if (!$haslead) { $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_LEAD); } } if (!empty($info['release_deps'])) { $i = 1; foreach ($info['release_deps'] as $d) { if (!isset($d['type']) || empty($d['type'])) { $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPTYPE, array('index' => $i, 'types' => PEAR_Common::getDependencyTypes())); continue; } if (!isset($d['rel']) || empty($d['rel'])) { $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPREL, array('index' => $i, 'rels' => PEAR_Common::getDependencyRelations())); continue; } if (!empty($d['optional'])) { if (!in_array($d['optional'], array('yes', 'no'))) { $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_DEPOPTIONAL, array('index' => $i, 'opt' => $d['optional'])); } } if ($d['rel'] != 'has' && $d['rel'] != 'not' && empty($d['version'])) { $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPVERSION, array('index' => $i)); } elseif (($d['rel'] == 'has' || $d['rel'] == 'not') && !empty($d['version'])) { $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_DEPVERSION_IGNORED, array('index' => $i, 'rel' => $d['rel'])); } if ($d['type'] == 'php' && !empty($d['name'])) { $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_DEPNAME_IGNORED, array('index' => $i, 'name' => $d['name'])); } elseif ($d['type'] != 'php' && empty($d['name'])) { $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPNAME, array('index' => $i)); } if ($d['type'] == 'php' && empty($d['version'])) { $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPPHPVERSION, array('index' => $i)); } if (($d['rel'] == 'not') && ($d['type'] == 'php')) { $this->_validateError(PEAR_PACKAGEFILE_PHP_NO_NOT, array('index' => $i)); } $i++; } } if (!empty($info['configure_options'])) { $i = 1; foreach ($info['configure_options'] as $c) { if (empty($c['name'])) { $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_CONFNAME, array('index' => $i)); } if (empty($c['prompt'])) { $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_CONFPROMPT, array('index' => $i)); } $i++; } } if (empty($info['filelist'])) { $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_FILES); $errors[] = 'no files'; } else { foreach ($info['filelist'] as $file => $fa) { if (empty($fa['role'])) { $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_FILEROLE, array('file' => $file, 'roles' => PEAR_Common::getFileRoles())); continue; } elseif (!in_array($fa['role'], PEAR_Common::getFileRoles())) { $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILEROLE, array('file' => $file, 'role' => $fa['role'], 'roles' => PEAR_Common::getFileRoles())); } if (preg_match('~/\.\.?(/|\\z)|^\.\.?/~', str_replace('\\', '/', $file))) { // file contains .. parent directory or . cur directory references $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME, array('file' => $file)); } if (isset($fa['install-as']) && preg_match('~/\.\.?(/|\\z)|^\.\.?/~', str_replace('\\', '/', $fa['install-as']))) { // install-as contains .. parent directory or . cur directory references $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME, array('file' => $file . ' [installed as ' . $fa['install-as'] . ']')); } if (isset($fa['baseinstalldir']) && preg_match('~/\.\.?(/|\\z)|^\.\.?/~', str_replace('\\', '/', $fa['baseinstalldir']))) { // install-as contains .. parent directory or . cur directory references $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME, array('file' => $file . ' [baseinstalldir ' . $fa['baseinstalldir'] . ']')); } } } if (isset($this->_registry) && $this->_isValid) { $chan = $this->_registry->getChannel('pear.php.net'); if (PEAR::isError($chan)) { $this->_validateError(PEAR_PACKAGEFILE_ERROR_CHANNELVAL, $chan->getMessage()); return $this->_isValid = 0; } $validator = $chan->getValidationObject(); $validator->setPackageFile($this); $validator->validate($state); $failures = $validator->getFailures(); foreach ($failures['errors'] as $error) { $this->_validateError(PEAR_PACKAGEFILE_ERROR_CHANNELVAL, $error); } foreach ($failures['warnings'] as $warning) { $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_CHANNELVAL, $warning); } } if ($this->_isValid && $state == PEAR_VALIDATE_PACKAGING && !$nofilechecking) { if ($this->_analyzePhpFiles()) { $this->_isValid = true; } } if ($this->_isValid) { return $this->_isValid = $state; } return $this->_isValid = 0; } function _analyzePhpFiles() { if (!$this->_isValid) { return false; } if (!isset($this->_packageFile)) { return false; } $dir_prefix = dirname($this->_packageFile); $common = new PEAR_Common; $log = isset($this->_logger) ? array(&$this->_logger, 'log') : array($common, 'log'); $info = $this->getFilelist(); foreach ($info as $file => $fa) { if (!file_exists($dir_prefix . DIRECTORY_SEPARATOR . $file)) { $this->_validateError(PEAR_PACKAGEFILE_ERROR_FILE_NOTFOUND, array('file' => realpath($dir_prefix) . DIRECTORY_SEPARATOR . $file)); continue; } if ($fa['role'] == 'php' && $dir_prefix) { call_user_func_array($log, array(1, "Analyzing $file")); $srcinfo = $this->_analyzeSourceCode($dir_prefix . DIRECTORY_SEPARATOR . $file); if ($srcinfo) { $this->_buildProvidesArray($srcinfo); } } } $this->_packageName = $pn = $this->getPackage(); $pnl = strlen($pn); if (isset($this->_packageInfo['provides'])) { foreach ((array) $this->_packageInfo['provides'] as $key => $what) { if (isset($what['explicit'])) { // skip conformance checks if the provides entry is // specified in the package.xml file continue; } extract($what); if ($type == 'class') { if (!strncasecmp($name, $pn, $pnl)) { continue; } $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX, array('file' => $file, 'type' => $type, 'name' => $name, 'package' => $pn)); } elseif ($type == 'function') { if (strstr($name, '::') || !strncasecmp($name, $pn, $pnl)) { continue; } $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX, array('file' => $file, 'type' => $type, 'name' => $name, 'package' => $pn)); } } } return $this->_isValid; } /** * Get the default xml generator object * * @return PEAR_PackageFile_Generator_v1 */ function &getDefaultGenerator() { if (!class_exists('PEAR_PackageFile_Generator_v1')) { require_once 'PEAR/PackageFile/Generator/v1.php'; } $a = new PEAR_PackageFile_Generator_v1($this); return $a; } /** * Get the contents of a file listed within the package.xml * @param string * @return string */ function getFileContents($file) { if ($this->_archiveFile == $this->_packageFile) { // unpacked $dir = dirname($this->_packageFile); $file = $dir . DIRECTORY_SEPARATOR . $file; $file = str_replace(array('/', '\\'), array(DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR), $file); if (file_exists($file) && is_readable($file)) { return implode('', file($file)); } } else { // tgz if (!class_exists('Archive_Tar')) { require_once 'Archive/Tar.php'; } $tar = new Archive_Tar($this->_archiveFile); $tar->pushErrorHandling(PEAR_ERROR_RETURN); if ($file != 'package.xml' && $file != 'package2.xml') { $file = $this->getPackage() . '-' . $this->getVersion() . '/' . $file; } $file = $tar->extractInString($file); $tar->popErrorHandling(); if (PEAR::isError($file)) { return PEAR::raiseError("Cannot locate file '$file' in archive"); } return $file; } } // {{{ analyzeSourceCode() /** * Analyze the source code of the given PHP file * * @param string Filename of the PHP file * @return mixed * @access private */ function _analyzeSourceCode($file) { if (!function_exists("token_get_all")) { return false; } if (!defined('T_DOC_COMMENT')) { define('T_DOC_COMMENT', T_COMMENT); } if (!defined('T_INTERFACE')) { define('T_INTERFACE', -1); } if (!defined('T_IMPLEMENTS')) { define('T_IMPLEMENTS', -1); } if (!$fp = @fopen($file, "r")) { return false; } fclose($fp); $contents = file_get_contents($file); $tokens = token_get_all($contents); /* for ($i = 0; $i < sizeof($tokens); $i++) { @list($token, $data) = $tokens[$i]; if (is_string($token)) { var_dump($token); } else { print token_name($token) . ' '; var_dump(rtrim($data)); } } */ $look_for = 0; $paren_level = 0; $bracket_level = 0; $brace_level = 0; $lastphpdoc = ''; $current_class = ''; $current_interface = ''; $current_class_level = -1; $current_function = ''; $current_function_level = -1; $declared_classes = array(); $declared_interfaces = array(); $declared_functions = array(); $declared_methods = array(); $used_classes = array(); $used_functions = array(); $extends = array(); $implements = array(); $nodeps = array(); $inquote = false; $interface = false; for ($i = 0; $i < sizeof($tokens); $i++) { if (is_array($tokens[$i])) { list($token, $data) = $tokens[$i]; } else { $token = $tokens[$i]; $data = ''; } if ($inquote) { if ($token != '"' && $token != T_END_HEREDOC) { continue; } else { $inquote = false; continue; } } switch ($token) { case T_WHITESPACE: break; case ';': if ($interface) { $current_function = ''; $current_function_level = -1; } break; case '"': case T_START_HEREDOC: $inquote = true; break; case T_CURLY_OPEN: case T_DOLLAR_OPEN_CURLY_BRACES: case '{': $brace_level++; continue 2; case '}': $brace_level--; if ($current_class_level == $brace_level) { $current_class = ''; $current_class_level = -1; } if ($current_function_level == $brace_level) { $current_function = ''; $current_function_level = -1; } continue 2; case '[': $bracket_level++; continue 2; case ']': $bracket_level--; continue 2; case '(': $paren_level++; continue 2; case ')': $paren_level--; continue 2; case T_INTERFACE: $interface = true; case T_CLASS: if (($current_class_level != -1) || ($current_function_level != -1)) { $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE, array('file' => $file)); return false; } case T_FUNCTION: case T_NEW: case T_EXTENDS: case T_IMPLEMENTS: $look_for = $token; continue 2; case T_STRING: if ($look_for == T_CLASS) { $current_class = $data; $current_class_level = $brace_level; $declared_classes[] = $current_class; } elseif ($look_for == T_INTERFACE) { $current_interface = $data; $current_class_level = $brace_level; $declared_interfaces[] = $current_interface; } elseif ($look_for == T_IMPLEMENTS) { $implements[$current_class] = $data; } elseif ($look_for == T_EXTENDS) { $extends[$current_class] = $data; } elseif ($look_for == T_FUNCTION) { if ($current_class) { $current_function = "$current_class::$data"; $declared_methods[$current_class][] = $data; } elseif ($current_interface) { $current_function = "$current_interface::$data"; $declared_methods[$current_interface][] = $data; } else { $current_function = $data; $declared_functions[] = $current_function; } $current_function_level = $brace_level; $m = array(); } elseif ($look_for == T_NEW) { $used_classes[$data] = true; } $look_for = 0; continue 2; case T_VARIABLE: $look_for = 0; continue 2; case T_DOC_COMMENT: case T_COMMENT: if (preg_match('!^/\*\*\s!', $data)) { $lastphpdoc = $data; if (preg_match_all('/@nodep\s+(\S+)/', $lastphpdoc, $m)) { $nodeps = array_merge($nodeps, $m[1]); } } continue 2; case T_DOUBLE_COLON: if (!($tokens[$i - 1][0] == T_WHITESPACE || $tokens[$i - 1][0] == T_STRING)) { $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE, array('file' => $file)); return false; } $class = $tokens[$i - 1][1]; if (strtolower($class) != 'parent') { $used_classes[$class] = true; } continue 2; } } return array( "source_file" => $file, "declared_classes" => $declared_classes, "declared_interfaces" => $declared_interfaces, "declared_methods" => $declared_methods, "declared_functions" => $declared_functions, "used_classes" => array_diff(array_keys($used_classes), $nodeps), "inheritance" => $extends, "implements" => $implements, ); } /** * Build a "provides" array from data returned by * analyzeSourceCode(). The format of the built array is like * this: * * array( * 'class;MyClass' => 'array('type' => 'class', 'name' => 'MyClass'), * ... * ) * * * @param array $srcinfo array with information about a source file * as returned by the analyzeSourceCode() method. * * @return void * * @access private * */ function _buildProvidesArray($srcinfo) { if (!$this->_isValid) { return false; } $file = basename($srcinfo['source_file']); $pn = $this->getPackage(); $pnl = strlen($pn); foreach ($srcinfo['declared_classes'] as $class) { $key = "class;$class"; if (isset($this->_packageInfo['provides'][$key])) { continue; } $this->_packageInfo['provides'][$key] = array('file'=> $file, 'type' => 'class', 'name' => $class); if (isset($srcinfo['inheritance'][$class])) { $this->_packageInfo['provides'][$key]['extends'] = $srcinfo['inheritance'][$class]; } } foreach ($srcinfo['declared_methods'] as $class => $methods) { foreach ($methods as $method) { $function = "$class::$method"; $key = "function;$function"; if ($method[0] == '_' || !strcasecmp($method, $class) || isset($this->_packageInfo['provides'][$key])) { continue; } $this->_packageInfo['provides'][$key] = array('file'=> $file, 'type' => 'function', 'name' => $function); } } foreach ($srcinfo['declared_functions'] as $function) { $key = "function;$function"; if ($function[0] == '_' || isset($this->_packageInfo['provides'][$key])) { continue; } if (!strstr($function, '::') && strncasecmp($function, $pn, $pnl)) { $warnings[] = "in1 " . $file . ": function \"$function\" not prefixed with package name \"$pn\""; } $this->_packageInfo['provides'][$key] = array('file'=> $file, 'type' => 'function', 'name' => $function); } } // }}} } ?> PKu]C8LL!PEAR/PackageFile/v2/Validator.phpnu[ * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a8 */ /** * Private validation class used by PEAR_PackageFile_v2 - do not use directly, its * sole purpose is to split up the PEAR/PackageFile/v2.php file to make it smaller * @category pear * @package PEAR * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a8 * @access private */ class PEAR_PackageFile_v2_Validator { /** * @var array */ var $_packageInfo; /** * @var PEAR_PackageFile_v2 */ var $_pf; /** * @var PEAR_ErrorStack */ var $_stack; /** * @var int */ var $_isValid = 0; /** * @var int */ var $_filesValid = 0; /** * @var int */ var $_curState = 0; /** * @param PEAR_PackageFile_v2 * @param int */ function validate(&$pf, $state = PEAR_VALIDATE_NORMAL) { $this->_pf = &$pf; $this->_curState = $state; $this->_packageInfo = $this->_pf->getArray(); $this->_isValid = $this->_pf->_isValid; $this->_filesValid = $this->_pf->_filesValid; $this->_stack = &$pf->_stack; $this->_stack->getErrors(true); if (($this->_isValid & $state) == $state) { return true; } if (!isset($this->_packageInfo) || !is_array($this->_packageInfo)) { return false; } if (!isset($this->_packageInfo['attribs']['version']) || ($this->_packageInfo['attribs']['version'] != '2.0' && $this->_packageInfo['attribs']['version'] != '2.1') ) { $this->_noPackageVersion(); } $structure = array( 'name', 'channel|uri', '*extends', // can't be multiple, but this works fine 'summary', 'description', '+lead', // these all need content checks '*developer', '*contributor', '*helper', 'date', '*time', 'version', 'stability', 'license->?uri->?filesource', 'notes', 'contents', //special validation needed '*compatible', 'dependencies', //special validation needed '*usesrole', '*usestask', // reserve these for 1.4.0a1 to implement // this will allow a package.xml to gracefully say it // needs a certain package installed in order to implement a role or task '*providesextension', '*srcpackage|*srcuri', '+phprelease|+extsrcrelease|+extbinrelease|' . '+zendextsrcrelease|+zendextbinrelease|bundle', //special validation needed '*changelog', ); $test = $this->_packageInfo; if (isset($test['dependencies']) && isset($test['dependencies']['required']) && isset($test['dependencies']['required']['pearinstaller']) && isset($test['dependencies']['required']['pearinstaller']['min']) && '1.10.16' != '@package' . '_version@' && version_compare('1.10.16', $test['dependencies']['required']['pearinstaller']['min'], '<') ) { $this->_pearVersionTooLow($test['dependencies']['required']['pearinstaller']['min']); return false; } // ignore post-installation array fields if (array_key_exists('filelist', $test)) { unset($test['filelist']); } if (array_key_exists('_lastmodified', $test)) { unset($test['_lastmodified']); } if (array_key_exists('#binarypackage', $test)) { unset($test['#binarypackage']); } if (array_key_exists('old', $test)) { unset($test['old']); } if (array_key_exists('_lastversion', $test)) { unset($test['_lastversion']); } if (!$this->_stupidSchemaValidate($structure, $test, '')) { return false; } if (empty($this->_packageInfo['name'])) { $this->_tagCannotBeEmpty('name'); } $test = isset($this->_packageInfo['uri']) ? 'uri' :'channel'; if (empty($this->_packageInfo[$test])) { $this->_tagCannotBeEmpty($test); } if (is_array($this->_packageInfo['license']) && (!isset($this->_packageInfo['license']['_content']) || empty($this->_packageInfo['license']['_content']))) { $this->_tagCannotBeEmpty('license'); } elseif (empty($this->_packageInfo['license'])) { $this->_tagCannotBeEmpty('license'); } if (empty($this->_packageInfo['summary'])) { $this->_tagCannotBeEmpty('summary'); } if (empty($this->_packageInfo['description'])) { $this->_tagCannotBeEmpty('description'); } if (empty($this->_packageInfo['date'])) { $this->_tagCannotBeEmpty('date'); } if (empty($this->_packageInfo['notes'])) { $this->_tagCannotBeEmpty('notes'); } if (isset($this->_packageInfo['time']) && empty($this->_packageInfo['time'])) { $this->_tagCannotBeEmpty('time'); } if (isset($this->_packageInfo['dependencies'])) { $this->_validateDependencies(); } if (isset($this->_packageInfo['compatible'])) { $this->_validateCompatible(); } if (!isset($this->_packageInfo['bundle'])) { if (empty($this->_packageInfo['contents'])) { $this->_tagCannotBeEmpty('contents'); } if (!isset($this->_packageInfo['contents']['dir'])) { $this->_filelistMustContainDir('contents'); return false; } if (isset($this->_packageInfo['contents']['file'])) { $this->_filelistCannotContainFile('contents'); return false; } } $this->_validateMaintainers(); $this->_validateStabilityVersion(); $fail = false; if (array_key_exists('usesrole', $this->_packageInfo)) { $roles = $this->_packageInfo['usesrole']; if (!is_array($roles) || !isset($roles[0])) { $roles = array($roles); } foreach ($roles as $role) { if (!isset($role['role'])) { $this->_usesroletaskMustHaveRoleTask('usesrole', 'role'); $fail = true; } else { if (!isset($role['channel'])) { if (!isset($role['uri'])) { $this->_usesroletaskMustHaveChannelOrUri($role['role'], 'usesrole'); $fail = true; } } elseif (!isset($role['package'])) { $this->_usesroletaskMustHavePackage($role['role'], 'usesrole'); $fail = true; } } } } if (array_key_exists('usestask', $this->_packageInfo)) { $roles = $this->_packageInfo['usestask']; if (!is_array($roles) || !isset($roles[0])) { $roles = array($roles); } foreach ($roles as $role) { if (!isset($role['task'])) { $this->_usesroletaskMustHaveRoleTask('usestask', 'task'); $fail = true; } else { if (!isset($role['channel'])) { if (!isset($role['uri'])) { $this->_usesroletaskMustHaveChannelOrUri($role['task'], 'usestask'); $fail = true; } } elseif (!isset($role['package'])) { $this->_usesroletaskMustHavePackage($role['task'], 'usestask'); $fail = true; } } } } if ($fail) { return false; } $list = $this->_packageInfo['contents']; if (isset($list['dir']) && is_array($list['dir']) && isset($list['dir'][0])) { $this->_multipleToplevelDirNotAllowed(); return $this->_isValid = 0; } $this->_validateFilelist(); $this->_validateRelease(); if (!$this->_stack->hasErrors()) { $chan = $this->_pf->_registry->getChannel($this->_pf->getChannel(), true); if (PEAR::isError($chan)) { $this->_unknownChannel($this->_pf->getChannel()); } else { $valpack = $chan->getValidationPackage(); // for channel validator packages, always use the default PEAR validator. // otherwise, they can't be installed or packaged $validator = $chan->getValidationObject($this->_pf->getPackage()); if (!$validator) { $this->_stack->push(__FUNCTION__, 'error', array('channel' => $chan->getName(), 'package' => $this->_pf->getPackage(), 'name' => $valpack['_content'], 'version' => $valpack['attribs']['version']), 'package "%channel%/%package%" cannot be properly validated without ' . 'validation package "%channel%/%name%-%version%"'); return $this->_isValid = 0; } $validator->setPackageFile($this->_pf); $validator->validate($state); $failures = $validator->getFailures(); foreach ($failures['errors'] as $error) { $this->_stack->push(__FUNCTION__, 'error', $error, 'Channel validator error: field "%field%" - %reason%'); } foreach ($failures['warnings'] as $warning) { $this->_stack->push(__FUNCTION__, 'warning', $warning, 'Channel validator warning: field "%field%" - %reason%'); } } } $this->_pf->_isValid = $this->_isValid = !$this->_stack->hasErrors('error'); if ($this->_isValid && $state == PEAR_VALIDATE_PACKAGING && !$this->_filesValid) { if ($this->_pf->getPackageType() == 'bundle') { if ($this->_analyzeBundledPackages()) { $this->_filesValid = $this->_pf->_filesValid = true; } else { $this->_pf->_isValid = $this->_isValid = 0; } } else { if (!$this->_analyzePhpFiles()) { $this->_pf->_isValid = $this->_isValid = 0; } else { $this->_filesValid = $this->_pf->_filesValid = true; } } } if ($this->_isValid) { return $this->_pf->_isValid = $this->_isValid = $state; } return $this->_pf->_isValid = $this->_isValid = 0; } function _stupidSchemaValidate($structure, $xml, $root) { if (!is_array($xml)) { $xml = array(); } $keys = array_keys($xml); reset($keys); $key = current($keys); while ($key == 'attribs' || $key == '_contents') { $key = next($keys); } $unfoundtags = $optionaltags = array(); $ret = true; $mismatch = false; foreach ($structure as $struc) { if ($key) { $tag = $xml[$key]; } $test = $this->_processStructure($struc); if (isset($test['choices'])) { $loose = true; foreach ($test['choices'] as $choice) { if ($key == $choice['tag']) { $key = next($keys); while ($key == 'attribs' || $key == '_contents') { $key = next($keys); } $unfoundtags = $optionaltags = array(); $mismatch = false; if ($key && $key != $choice['tag'] && isset($choice['multiple'])) { $unfoundtags[] = $choice['tag']; $optionaltags[] = $choice['tag']; if ($key) { $mismatch = true; } } $ret &= $this->_processAttribs($choice, $tag, $root); continue 2; } else { $unfoundtags[] = $choice['tag']; $mismatch = true; } if (!isset($choice['multiple']) || $choice['multiple'] != '*') { $loose = false; } else { $optionaltags[] = $choice['tag']; } } if (!$loose) { $this->_invalidTagOrder($unfoundtags, $key, $root); return false; } } else { if ($key != $test['tag']) { if (isset($test['multiple']) && $test['multiple'] != '*') { $unfoundtags[] = $test['tag']; $this->_invalidTagOrder($unfoundtags, $key, $root); return false; } else { if ($key) { $mismatch = true; } $unfoundtags[] = $test['tag']; $optionaltags[] = $test['tag']; } if (!isset($test['multiple'])) { $this->_invalidTagOrder($unfoundtags, $key, $root); return false; } continue; } else { $unfoundtags = $optionaltags = array(); $mismatch = false; } $key = next($keys); while ($key == 'attribs' || $key == '_contents') { $key = next($keys); } if ($key && $key != $test['tag'] && isset($test['multiple'])) { $unfoundtags[] = $test['tag']; $optionaltags[] = $test['tag']; $mismatch = true; } $ret &= $this->_processAttribs($test, $tag, $root); continue; } } if (!$mismatch && count($optionaltags)) { // don't error out on any optional tags $unfoundtags = array_diff($unfoundtags, $optionaltags); } if (count($unfoundtags)) { $this->_invalidTagOrder($unfoundtags, $key, $root); } elseif ($key) { // unknown tags $this->_invalidTagOrder('*no tags allowed here*', $key, $root); while ($key = next($keys)) { $this->_invalidTagOrder('*no tags allowed here*', $key, $root); } } return $ret; } function _processAttribs($choice, $tag, $context) { if (isset($choice['attribs'])) { if (!is_array($tag)) { $tag = array($tag); } $tags = $tag; if (!isset($tags[0])) { $tags = array($tags); } $ret = true; foreach ($tags as $i => $tag) { if (!is_array($tag) || !isset($tag['attribs'])) { foreach ($choice['attribs'] as $attrib) { if ($attrib[0] != '?') { $ret &= $this->_tagHasNoAttribs($choice['tag'], $context); continue 2; } } } foreach ($choice['attribs'] as $attrib) { if ($attrib[0] != '?') { if (!isset($tag['attribs'][$attrib])) { $ret &= $this->_tagMissingAttribute($choice['tag'], $attrib, $context); } } } } return $ret; } return true; } function _processStructure($key) { $ret = array(); if (count($pieces = explode('|', $key)) > 1) { $ret['choices'] = array(); foreach ($pieces as $piece) { $ret['choices'][] = $this->_processStructure($piece); } return $ret; } $multi = $key[0]; if ($multi == '+' || $multi == '*') { $ret['multiple'] = $key[0]; $key = substr($key, 1); } if (count($attrs = explode('->', $key)) > 1) { $ret['tag'] = array_shift($attrs); $ret['attribs'] = $attrs; } else { $ret['tag'] = $key; } return $ret; } function _validateStabilityVersion() { $structure = array('release', 'api'); $a = $this->_stupidSchemaValidate($structure, $this->_packageInfo['version'], ''); $a &= $this->_stupidSchemaValidate($structure, $this->_packageInfo['stability'], ''); if ($a) { if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/', $this->_packageInfo['version']['release'])) { $this->_invalidVersion('release', $this->_packageInfo['version']['release']); } if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/', $this->_packageInfo['version']['api'])) { $this->_invalidVersion('api', $this->_packageInfo['version']['api']); } if (!in_array($this->_packageInfo['stability']['release'], array('snapshot', 'devel', 'alpha', 'beta', 'stable'))) { $this->_invalidState('release', $this->_packageInfo['stability']['release']); } if (!in_array($this->_packageInfo['stability']['api'], array('devel', 'alpha', 'beta', 'stable'))) { $this->_invalidState('api', $this->_packageInfo['stability']['api']); } } } function _validateMaintainers() { $structure = array( 'name', 'user', 'email', 'active', ); foreach (array('lead', 'developer', 'contributor', 'helper') as $type) { if (!isset($this->_packageInfo[$type])) { continue; } if (isset($this->_packageInfo[$type][0])) { foreach ($this->_packageInfo[$type] as $lead) { $this->_stupidSchemaValidate($structure, $lead, '<' . $type . '>'); } } else { $this->_stupidSchemaValidate($structure, $this->_packageInfo[$type], '<' . $type . '>'); } } } function _validatePhpDep($dep, $installcondition = false) { $structure = array( 'min', '*max', '*exclude', ); $type = $installcondition ? '' : ''; $this->_stupidSchemaValidate($structure, $dep, $type); if (isset($dep['min'])) { if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?(?:-[a-zA-Z0-9]+)?\\z/', $dep['min'])) { $this->_invalidVersion($type . '', $dep['min']); } } if (isset($dep['max'])) { if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?(?:-[a-zA-Z0-9]+)?\\z/', $dep['max'])) { $this->_invalidVersion($type . '', $dep['max']); } } if (isset($dep['exclude'])) { if (!is_array($dep['exclude'])) { $dep['exclude'] = array($dep['exclude']); } foreach ($dep['exclude'] as $exclude) { if (!preg_match( '/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?(?:-[a-zA-Z0-9]+)?\\z/', $exclude)) { $this->_invalidVersion($type . '', $exclude); } } } } function _validatePearinstallerDep($dep) { $structure = array( 'min', '*max', '*recommended', '*exclude', ); $this->_stupidSchemaValidate($structure, $dep, ''); if (isset($dep['min'])) { if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/', $dep['min'])) { $this->_invalidVersion('', $dep['min']); } } if (isset($dep['max'])) { if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/', $dep['max'])) { $this->_invalidVersion('', $dep['max']); } } if (isset($dep['recommended'])) { if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/', $dep['recommended'])) { $this->_invalidVersion('', $dep['recommended']); } } if (isset($dep['exclude'])) { if (!is_array($dep['exclude'])) { $dep['exclude'] = array($dep['exclude']); } foreach ($dep['exclude'] as $exclude) { if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/', $exclude)) { $this->_invalidVersion('', $exclude); } } } } function _validatePackageDep($dep, $group, $type = '') { if (isset($dep['uri'])) { if (isset($dep['conflicts'])) { $structure = array( 'name', 'uri', 'conflicts', '*providesextension', ); } else { $structure = array( 'name', 'uri', '*providesextension', ); } } else { if (isset($dep['conflicts'])) { $structure = array( 'name', 'channel', '*min', '*max', '*exclude', 'conflicts', '*providesextension', ); } else { $structure = array( 'name', 'channel', '*min', '*max', '*recommended', '*exclude', '*nodefault', '*providesextension', ); } } if (isset($dep['name'])) { $type .= '' . $dep['name'] . ''; } $this->_stupidSchemaValidate($structure, $dep, '' . $group . $type); if (isset($dep['uri']) && (isset($dep['min']) || isset($dep['max']) || isset($dep['recommended']) || isset($dep['exclude']))) { $this->_uriDepsCannotHaveVersioning('' . $group . $type); } if (isset($dep['channel']) && strtolower($dep['channel']) == '__uri') { $this->_DepchannelCannotBeUri('' . $group . $type); } if (isset($dep['min'])) { if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/', $dep['min'])) { $this->_invalidVersion('' . $group . $type . '', $dep['min']); } } if (isset($dep['max'])) { if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/', $dep['max'])) { $this->_invalidVersion('' . $group . $type . '', $dep['max']); } } if (isset($dep['recommended'])) { if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/', $dep['recommended'])) { $this->_invalidVersion('' . $group . $type . '', $dep['recommended']); } } if (isset($dep['exclude'])) { if (!is_array($dep['exclude'])) { $dep['exclude'] = array($dep['exclude']); } foreach ($dep['exclude'] as $exclude) { if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/', $exclude)) { $this->_invalidVersion('' . $group . $type . '', $exclude); } } } } function _validateSubpackageDep($dep, $group) { $this->_validatePackageDep($dep, $group, ''); if (isset($dep['providesextension'])) { $this->_subpackageCannotProvideExtension(isset($dep['name']) ? $dep['name'] : ''); } if (isset($dep['conflicts'])) { $this->_subpackagesCannotConflict(isset($dep['name']) ? $dep['name'] : ''); } } function _validateExtensionDep($dep, $group = false, $installcondition = false) { if (isset($dep['conflicts'])) { $structure = array( 'name', '*min', '*max', '*exclude', 'conflicts', ); } else { $structure = array( 'name', '*min', '*max', '*recommended', '*exclude', ); } if ($installcondition) { $type = ''; } else { $type = '' . $group . ''; } if (isset($dep['name'])) { $type .= '' . $dep['name'] . ''; } $this->_stupidSchemaValidate($structure, $dep, $type); if (isset($dep['min'])) { if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/', $dep['min'])) { $this->_invalidVersion(substr($type, 1) . '_invalidVersion(substr($type, 1) . '_invalidVersion(substr($type, 1) . '_invalidVersion(substr($type, 1) . '' : ''; if ($this->_stupidSchemaValidate($structure, $dep, $type)) { if ($dep['name'] == '*') { if (array_key_exists('conflicts', $dep)) { $this->_cannotConflictWithAllOs($type); } } } } function _validateArchDep($dep, $installcondition = false) { $structure = array( 'pattern', '*conflicts', ); $type = $installcondition ? '' : ''; $this->_stupidSchemaValidate($structure, $dep, $type); } function _validateInstallConditions($cond, $release) { $structure = array( '*php', '*extension', '*os', '*arch', ); if (!$this->_stupidSchemaValidate($structure, $cond, $release)) { return false; } foreach (array('php', 'extension', 'os', 'arch') as $type) { if (isset($cond[$type])) { $iter = $cond[$type]; if (!is_array($iter) || !isset($iter[0])) { $iter = array($iter); } foreach ($iter as $package) { if ($type == 'extension') { $this->{"_validate{$type}Dep"}($package, false, true); } else { $this->{"_validate{$type}Dep"}($package, true); } } } } } function _validateDependencies() { $structure = array( 'required', '*optional', '*group->name->hint' ); if (!$this->_stupidSchemaValidate($structure, $this->_packageInfo['dependencies'], '')) { return false; } foreach (array('required', 'optional') as $simpledep) { if (isset($this->_packageInfo['dependencies'][$simpledep])) { if ($simpledep == 'optional') { $structure = array( '*package', '*subpackage', '*extension', ); } else { $structure = array( 'php', 'pearinstaller', '*package', '*subpackage', '*extension', '*os', '*arch', ); } if ($this->_stupidSchemaValidate($structure, $this->_packageInfo['dependencies'][$simpledep], "<$simpledep>")) { foreach (array('package', 'subpackage', 'extension') as $type) { if (isset($this->_packageInfo['dependencies'][$simpledep][$type])) { $iter = $this->_packageInfo['dependencies'][$simpledep][$type]; if (!isset($iter[0])) { $iter = array($iter); } foreach ($iter as $package) { if ($type != 'extension') { if (isset($package['uri'])) { if (isset($package['channel'])) { $this->_UrlOrChannel($type, $package['name']); } } else { if (!isset($package['channel'])) { $this->_NoChannel($type, $package['name']); } } } $this->{"_validate{$type}Dep"}($package, "<$simpledep>"); } } } if ($simpledep == 'optional') { continue; } foreach (array('php', 'pearinstaller', 'os', 'arch') as $type) { if (isset($this->_packageInfo['dependencies'][$simpledep][$type])) { $iter = $this->_packageInfo['dependencies'][$simpledep][$type]; if (!isset($iter[0])) { $iter = array($iter); } foreach ($iter as $package) { $this->{"_validate{$type}Dep"}($package); } } } } } } if (isset($this->_packageInfo['dependencies']['group'])) { $groups = $this->_packageInfo['dependencies']['group']; if (!isset($groups[0])) { $groups = array($groups); } $structure = array( '*package', '*subpackage', '*extension', ); foreach ($groups as $group) { if ($this->_stupidSchemaValidate($structure, $group, '')) { if (!PEAR_Validate::validGroupName($group['attribs']['name'])) { $this->_invalidDepGroupName($group['attribs']['name']); } foreach (array('package', 'subpackage', 'extension') as $type) { if (isset($group[$type])) { $iter = $group[$type]; if (!isset($iter[0])) { $iter = array($iter); } foreach ($iter as $package) { if ($type != 'extension') { if (isset($package['uri'])) { if (isset($package['channel'])) { $this->_UrlOrChannelGroup($type, $package['name'], $group['name']); } } else { if (!isset($package['channel'])) { $this->_NoChannelGroup($type, $package['name'], $group['name']); } } } $this->{"_validate{$type}Dep"}($package, ''); } } } } } } } function _validateCompatible() { $compat = $this->_packageInfo['compatible']; if (!isset($compat[0])) { $compat = array($compat); } $required = array('name', 'channel', 'min', 'max', '*exclude'); foreach ($compat as $package) { $type = ''; if (is_array($package) && array_key_exists('name', $package)) { $type .= '' . $package['name'] . ''; } $this->_stupidSchemaValidate($required, $package, $type); if (is_array($package) && array_key_exists('min', $package)) { if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/', $package['min'])) { $this->_invalidVersion(substr($type, 1) . '_invalidVersion(substr($type, 1) . '_invalidVersion(substr($type, 1) . '_NoBundledPackages(); } if (!is_array($list['bundledpackage']) || !isset($list['bundledpackage'][0])) { return $this->_AtLeast2BundledPackages(); } foreach ($list['bundledpackage'] as $package) { if (!is_string($package)) { $this->_bundledPackagesMustBeFilename(); } } } function _validateFilelist($list = false, $allowignore = false, $dirs = '') { $iscontents = false; if (!$list) { $iscontents = true; $list = $this->_packageInfo['contents']; if (isset($this->_packageInfo['bundle'])) { return $this->_validateBundle($list); } } if ($allowignore) { $struc = array( '*install->name->as', '*ignore->name' ); } else { $struc = array( '*dir->name->?baseinstalldir', '*file->name->role->?baseinstalldir->?md5sum' ); if (isset($list['dir']) && isset($list['file'])) { // stave off validation errors without requiring a set order. $_old = $list; if (isset($list['attribs'])) { $list = array('attribs' => $_old['attribs']); } $list['dir'] = $_old['dir']; $list['file'] = $_old['file']; } } if (!isset($list['attribs']) || !isset($list['attribs']['name'])) { $unknown = $allowignore ? '' : ''; $dirname = $iscontents ? '' : $unknown; } else { $dirname = ''; if (preg_match('~/\.\.?(/|\\z)|^\.\.?/~', str_replace('\\', '/', $list['attribs']['name']))) { // file contains .. parent directory or . cur directory $this->_invalidDirName($list['attribs']['name']); } } $res = $this->_stupidSchemaValidate($struc, $list, $dirname); if ($allowignore && $res) { $ignored_or_installed = array(); $this->_pf->getFilelist(); $fcontents = $this->_pf->getContents(); $filelist = array(); if (!isset($fcontents['dir']['file'][0])) { $fcontents['dir']['file'] = array($fcontents['dir']['file']); } foreach ($fcontents['dir']['file'] as $file) { $filelist[$file['attribs']['name']] = true; } if (isset($list['install'])) { if (!isset($list['install'][0])) { $list['install'] = array($list['install']); } foreach ($list['install'] as $file) { if (!isset($filelist[$file['attribs']['name']])) { $this->_notInContents($file['attribs']['name'], 'install'); continue; } if (array_key_exists($file['attribs']['name'], $ignored_or_installed)) { $this->_multipleInstallAs($file['attribs']['name']); } if (!isset($ignored_or_installed[$file['attribs']['name']])) { $ignored_or_installed[$file['attribs']['name']] = array(); } $ignored_or_installed[$file['attribs']['name']][] = 1; if (preg_match('~/\.\.?(/|\\z)|^\.\.?/~', str_replace('\\', '/', $file['attribs']['as']))) { // file contains .. parent directory or . cur directory references $this->_invalidFileInstallAs($file['attribs']['name'], $file['attribs']['as']); } } } if (isset($list['ignore'])) { if (!isset($list['ignore'][0])) { $list['ignore'] = array($list['ignore']); } foreach ($list['ignore'] as $file) { if (!isset($filelist[$file['attribs']['name']])) { $this->_notInContents($file['attribs']['name'], 'ignore'); continue; } if (array_key_exists($file['attribs']['name'], $ignored_or_installed)) { $this->_ignoreAndInstallAs($file['attribs']['name']); } } } } if (!$allowignore && isset($list['file'])) { if (is_string($list['file'])) { $this->_oldStyleFileNotAllowed(); return false; } if (!isset($list['file'][0])) { // single file $list['file'] = array($list['file']); } foreach ($list['file'] as $i => $file) { if (isset($file['attribs']) && isset($file['attribs']['name'])) { if ($file['attribs']['name'][0] == '.' && $file['attribs']['name'][1] == '/') { // name is something like "./doc/whatever.txt" $this->_invalidFileName($file['attribs']['name'], $dirname); } if (preg_match('~/\.\.?(/|\\z)|^\.\.?/~', str_replace('\\', '/', $file['attribs']['name']))) { // file contains .. parent directory or . cur directory $this->_invalidFileName($file['attribs']['name'], $dirname); } } if (isset($file['attribs']) && isset($file['attribs']['role'])) { if (!$this->_validateRole($file['attribs']['role'])) { if (isset($this->_packageInfo['usesrole'])) { $roles = $this->_packageInfo['usesrole']; if (!isset($roles[0])) { $roles = array($roles); } foreach ($roles as $role) { if ($role['role'] = $file['attribs']['role']) { $msg = 'This package contains role "%role%" and requires ' . 'package "%package%" to be used'; if (isset($role['uri'])) { $params = array('role' => $role['role'], 'package' => $role['uri']); } else { $params = array('role' => $role['role'], 'package' => $this->_pf->_registry-> parsedPackageNameToString(array('package' => $role['package'], 'channel' => $role['channel']), true)); } $this->_stack->push('_mustInstallRole', 'error', $params, $msg); } } } $this->_invalidFileRole($file['attribs']['name'], $dirname, $file['attribs']['role']); } } if (!isset($file['attribs'])) { continue; } $save = $file['attribs']; if ($dirs) { $save['name'] = $dirs . '/' . $save['name']; } unset($file['attribs']); if (count($file) && $this->_curState != PEAR_VALIDATE_DOWNLOADING) { // has tasks foreach ($file as $task => $value) { if ($tagClass = $this->_pf->getTask($task)) { if (!is_array($value) || !isset($value[0])) { $value = array($value); } foreach ($value as $v) { $ret = call_user_func(array($tagClass, 'validateXml'), $this->_pf, $v, $this->_pf->_config, $save); if (is_array($ret)) { $this->_invalidTask($task, $ret, isset($save['name']) ? $save['name'] : ''); } } } else { if (isset($this->_packageInfo['usestask'])) { $roles = $this->_packageInfo['usestask']; if (!isset($roles[0])) { $roles = array($roles); } foreach ($roles as $role) { if ($role['task'] = $task) { $msg = 'This package contains task "%task%" and requires ' . 'package "%package%" to be used'; if (isset($role['uri'])) { $params = array('task' => $role['task'], 'package' => $role['uri']); } else { $params = array('task' => $role['task'], 'package' => $this->_pf->_registry-> parsedPackageNameToString(array('package' => $role['package'], 'channel' => $role['channel']), true)); } $this->_stack->push('_mustInstallTask', 'error', $params, $msg); } } } $this->_unknownTask($task, $save['name']); } } } } } if (isset($list['ignore'])) { if (!$allowignore) { $this->_ignoreNotAllowed('ignore'); } } if (isset($list['install'])) { if (!$allowignore) { $this->_ignoreNotAllowed('install'); } } if (isset($list['file'])) { if ($allowignore) { $this->_fileNotAllowed('file'); } } if (isset($list['dir'])) { if ($allowignore) { $this->_fileNotAllowed('dir'); } else { if (!isset($list['dir'][0])) { $list['dir'] = array($list['dir']); } foreach ($list['dir'] as $dir) { if (isset($dir['attribs']) && isset($dir['attribs']['name'])) { if ($dir['attribs']['name'] == '/' || !isset($this->_packageInfo['contents']['dir']['dir'])) { // always use nothing if the filelist has already been flattened $newdirs = ''; } elseif ($dirs == '') { $newdirs = $dir['attribs']['name']; } else { $newdirs = $dirs . '/' . $dir['attribs']['name']; } } else { $newdirs = $dirs; } $this->_validateFilelist($dir, $allowignore, $newdirs); } } } } function _validateRelease() { if (isset($this->_packageInfo['phprelease'])) { $release = 'phprelease'; if (isset($this->_packageInfo['providesextension'])) { $this->_cannotProvideExtension($release); } if (isset($this->_packageInfo['srcpackage']) || isset($this->_packageInfo['srcuri'])) { $this->_cannotHaveSrcpackage($release); } $releases = $this->_packageInfo['phprelease']; if (!is_array($releases)) { return true; } if (!isset($releases[0])) { $releases = array($releases); } foreach ($releases as $rel) { $this->_stupidSchemaValidate(array( '*installconditions', '*filelist', ), $rel, ''); } } foreach (array('', 'zend') as $prefix) { $releasetype = $prefix . 'extsrcrelease'; if (isset($this->_packageInfo[$releasetype])) { $release = $releasetype; if (!isset($this->_packageInfo['providesextension'])) { $this->_mustProvideExtension($release); } if (isset($this->_packageInfo['srcpackage']) || isset($this->_packageInfo['srcuri'])) { $this->_cannotHaveSrcpackage($release); } $releases = $this->_packageInfo[$releasetype]; if (!is_array($releases)) { return true; } if (!isset($releases[0])) { $releases = array($releases); } foreach ($releases as $rel) { $this->_stupidSchemaValidate(array( '*installconditions', '*configureoption->name->prompt->?default', '*binarypackage', '*filelist', ), $rel, '<' . $releasetype . '>'); if (isset($rel['binarypackage'])) { if (!is_array($rel['binarypackage']) || !isset($rel['binarypackage'][0])) { $rel['binarypackage'] = array($rel['binarypackage']); } foreach ($rel['binarypackage'] as $bin) { if (!is_string($bin)) { $this->_binaryPackageMustBePackagename(); } } } } } $releasetype = 'extbinrelease'; if (isset($this->_packageInfo[$releasetype])) { $release = $releasetype; if (!isset($this->_packageInfo['providesextension'])) { $this->_mustProvideExtension($release); } if (isset($this->_packageInfo['channel']) && !isset($this->_packageInfo['srcpackage'])) { $this->_mustSrcPackage($release); } if (isset($this->_packageInfo['uri']) && !isset($this->_packageInfo['srcuri'])) { $this->_mustSrcuri($release); } $releases = $this->_packageInfo[$releasetype]; if (!is_array($releases)) { return true; } if (!isset($releases[0])) { $releases = array($releases); } foreach ($releases as $rel) { $this->_stupidSchemaValidate(array( '*installconditions', '*filelist', ), $rel, '<' . $releasetype . '>'); } } } if (isset($this->_packageInfo['bundle'])) { $release = 'bundle'; if (isset($this->_packageInfo['providesextension'])) { $this->_cannotProvideExtension($release); } if (isset($this->_packageInfo['srcpackage']) || isset($this->_packageInfo['srcuri'])) { $this->_cannotHaveSrcpackage($release); } $releases = $this->_packageInfo['bundle']; if (!is_array($releases) || !isset($releases[0])) { $releases = array($releases); } foreach ($releases as $rel) { $this->_stupidSchemaValidate(array( '*installconditions', '*filelist', ), $rel, ''); } } foreach ($releases as $rel) { if (is_array($rel) && array_key_exists('installconditions', $rel)) { $this->_validateInstallConditions($rel['installconditions'], "<$release>"); } if (is_array($rel) && array_key_exists('filelist', $rel)) { if ($rel['filelist']) { $this->_validateFilelist($rel['filelist'], true); } } } } /** * This is here to allow role extension through plugins * @param string */ function _validateRole($role) { return in_array($role, PEAR_Installer_Role::getValidRoles($this->_pf->getPackageType())); } function _pearVersionTooLow($version) { $this->_stack->push(__FUNCTION__, 'error', array('version' => $version), 'This package.xml requires PEAR version %version% to parse properly, we are ' . 'version 1.10.16'); } function _invalidTagOrder($oktags, $actual, $root) { $this->_stack->push(__FUNCTION__, 'error', array('oktags' => $oktags, 'actual' => $actual, 'root' => $root), 'Invalid tag order in %root%, found <%actual%> expected one of "%oktags%"'); } function _ignoreNotAllowed($type) { $this->_stack->push(__FUNCTION__, 'error', array('type' => $type), '<%type%> is not allowed inside global , only inside ' . '//, use and only'); } function _fileNotAllowed($type) { $this->_stack->push(__FUNCTION__, 'error', array('type' => $type), '<%type%> is not allowed inside release , only inside ' . ', use and only'); } function _oldStyleFileNotAllowed() { $this->_stack->push(__FUNCTION__, 'error', array(), 'Old-style name is not allowed. Use' . ''); } function _tagMissingAttribute($tag, $attr, $context) { $this->_stack->push(__FUNCTION__, 'error', array('tag' => $tag, 'attribute' => $attr, 'context' => $context), 'tag <%tag%> in context "%context%" has no attribute "%attribute%"'); } function _tagHasNoAttribs($tag, $context) { $this->_stack->push(__FUNCTION__, 'error', array('tag' => $tag, 'context' => $context), 'tag <%tag%> has no attributes in context "%context%"'); } function _invalidInternalStructure() { $this->_stack->push(__FUNCTION__, 'exception', array(), 'internal array was not generated by compatible parser, or extreme parser error, cannot continue'); } function _invalidFileRole($file, $dir, $role) { $this->_stack->push(__FUNCTION__, 'error', array( 'file' => $file, 'dir' => $dir, 'role' => $role, 'roles' => PEAR_Installer_Role::getValidRoles($this->_pf->getPackageType())), 'File "%file%" in directory "%dir%" has invalid role "%role%", should be one of %roles%'); } function _invalidFileName($file, $dir) { $this->_stack->push(__FUNCTION__, 'error', array( 'file' => $file), 'File "%file%" in directory "%dir%" cannot begin with "./" or contain ".."'); } function _invalidFileInstallAs($file, $as) { $this->_stack->push(__FUNCTION__, 'error', array( 'file' => $file, 'as' => $as), 'File "%file%" cannot contain "./" or contain ".."'); } function _invalidDirName($dir) { $this->_stack->push(__FUNCTION__, 'error', array( 'dir' => $file), 'Directory "%dir%" cannot begin with "./" or contain ".."'); } function _filelistCannotContainFile($filelist) { $this->_stack->push(__FUNCTION__, 'error', array('tag' => $filelist), '<%tag%> can only contain , contains . Use ' . ' as the first dir element'); } function _filelistMustContainDir($filelist) { $this->_stack->push(__FUNCTION__, 'error', array('tag' => $filelist), '<%tag%> must contain . Use as the ' . 'first dir element'); } function _tagCannotBeEmpty($tag) { $this->_stack->push(__FUNCTION__, 'error', array('tag' => $tag), '<%tag%> cannot be empty (<%tag%/>)'); } function _UrlOrChannel($type, $name) { $this->_stack->push(__FUNCTION__, 'error', array('type' => $type, 'name' => $name), 'Required dependency <%type%> "%name%" can have either url OR ' . 'channel attributes, and not both'); } function _NoChannel($type, $name) { $this->_stack->push(__FUNCTION__, 'error', array('type' => $type, 'name' => $name), 'Required dependency <%type%> "%name%" must have either url OR ' . 'channel attributes'); } function _UrlOrChannelGroup($type, $name, $group) { $this->_stack->push(__FUNCTION__, 'error', array('type' => $type, 'name' => $name, 'group' => $group), 'Group "%group%" dependency <%type%> "%name%" can have either url OR ' . 'channel attributes, and not both'); } function _NoChannelGroup($type, $name, $group) { $this->_stack->push(__FUNCTION__, 'error', array('type' => $type, 'name' => $name, 'group' => $group), 'Group "%group%" dependency <%type%> "%name%" must have either url OR ' . 'channel attributes'); } function _unknownChannel($channel) { $this->_stack->push(__FUNCTION__, 'error', array('channel' => $channel), 'Unknown channel "%channel%"'); } function _noPackageVersion() { $this->_stack->push(__FUNCTION__, 'error', array(), 'package.xml tag has no version attribute, or version is not 2.0'); } function _NoBundledPackages() { $this->_stack->push(__FUNCTION__, 'error', array(), 'No tag was found in , required for bundle packages'); } function _AtLeast2BundledPackages() { $this->_stack->push(__FUNCTION__, 'error', array(), 'At least 2 packages must be bundled in a bundle package'); } function _ChannelOrUri($name) { $this->_stack->push(__FUNCTION__, 'error', array('name' => $name), 'Bundled package "%name%" can have either a uri or a channel, not both'); } function _noChildTag($child, $tag) { $this->_stack->push(__FUNCTION__, 'error', array('child' => $child, 'tag' => $tag), 'Tag <%tag%> is missing child tag <%child%>'); } function _invalidVersion($type, $value) { $this->_stack->push(__FUNCTION__, 'error', array('type' => $type, 'value' => $value), 'Version type <%type%> is not a valid version (%value%)'); } function _invalidState($type, $value) { $states = array('stable', 'beta', 'alpha', 'devel'); if ($type != 'api') { $states[] = 'snapshot'; } if (strtolower($value) == 'rc') { $this->_stack->push(__FUNCTION__, 'error', array('version' => $this->_packageInfo['version']['release']), 'RC is not a state, it is a version postfix, try %version%RC1, stability beta'); } $this->_stack->push(__FUNCTION__, 'error', array('type' => $type, 'value' => $value, 'types' => $states), 'Stability type <%type%> is not a valid stability (%value%), must be one of ' . '%types%'); } function _invalidTask($task, $ret, $file) { switch ($ret[0]) { case PEAR_TASK_ERROR_MISSING_ATTRIB : $info = array('attrib' => $ret[1], 'task' => $task, 'file' => $file); $msg = 'task <%task%> is missing attribute "%attrib%" in file %file%'; break; case PEAR_TASK_ERROR_NOATTRIBS : $info = array('task' => $task, 'file' => $file); $msg = 'task <%task%> has no attributes in file %file%'; break; case PEAR_TASK_ERROR_WRONG_ATTRIB_VALUE : $info = array('attrib' => $ret[1], 'values' => $ret[3], 'was' => $ret[2], 'task' => $task, 'file' => $file); $msg = 'task <%task%> attribute "%attrib%" has the wrong value "%was%" '. 'in file %file%, expecting one of "%values%"'; break; case PEAR_TASK_ERROR_INVALID : $info = array('reason' => $ret[1], 'task' => $task, 'file' => $file); $msg = 'task <%task%> in file %file% is invalid because of "%reason%"'; break; } $this->_stack->push(__FUNCTION__, 'error', $info, $msg); } function _unknownTask($task, $file) { $this->_stack->push(__FUNCTION__, 'error', array('task' => $task, 'file' => $file), 'Unknown task "%task%" passed in file '); } function _subpackageCannotProvideExtension($name) { $this->_stack->push(__FUNCTION__, 'error', array('name' => $name), 'Subpackage dependency "%name%" cannot use , ' . 'only package dependencies can use this tag'); } function _subpackagesCannotConflict($name) { $this->_stack->push(__FUNCTION__, 'error', array('name' => $name), 'Subpackage dependency "%name%" cannot use , ' . 'only package dependencies can use this tag'); } function _cannotProvideExtension($release) { $this->_stack->push(__FUNCTION__, 'error', array('release' => $release), '<%release%> packages cannot use , only extbinrelease, extsrcrelease, zendextsrcrelease, and zendextbinrelease can provide a PHP extension'); } function _mustProvideExtension($release) { $this->_stack->push(__FUNCTION__, 'error', array('release' => $release), '<%release%> packages must use to indicate which PHP extension is provided'); } function _cannotHaveSrcpackage($release) { $this->_stack->push(__FUNCTION__, 'error', array('release' => $release), '<%release%> packages cannot specify a source code package, only extension binaries may use the tag'); } function _mustSrcPackage($release) { $this->_stack->push(__FUNCTION__, 'error', array('release' => $release), '/ packages must specify a source code package with '); } function _mustSrcuri($release) { $this->_stack->push(__FUNCTION__, 'error', array('release' => $release), '/ packages must specify a source code package with '); } function _uriDepsCannotHaveVersioning($type) { $this->_stack->push(__FUNCTION__, 'error', array('type' => $type), '%type%: dependencies with a tag cannot have any versioning information'); } function _conflictingDepsCannotHaveVersioning($type) { $this->_stack->push(__FUNCTION__, 'error', array('type' => $type), '%type%: conflicting dependencies cannot have versioning info, use to ' . 'exclude specific versions of a dependency'); } function _DepchannelCannotBeUri($type) { $this->_stack->push(__FUNCTION__, 'error', array('type' => $type), '%type%: channel cannot be __uri, this is a pseudo-channel reserved for uri ' . 'dependencies only'); } function _bundledPackagesMustBeFilename() { $this->_stack->push(__FUNCTION__, 'error', array(), ' tags must contain only the filename of a package release ' . 'in the bundle'); } function _binaryPackageMustBePackagename() { $this->_stack->push(__FUNCTION__, 'error', array(), ' tags must contain the name of a package that is ' . 'a compiled version of this extsrc/zendextsrc package'); } function _fileNotFound($file) { $this->_stack->push(__FUNCTION__, 'error', array('file' => $file), 'File "%file%" in package.xml does not exist'); } function _notInContents($file, $tag) { $this->_stack->push(__FUNCTION__, 'error', array('file' => $file, 'tag' => $tag), '<%tag% name="%file%"> is invalid, file is not in '); } function _cannotValidateNoPathSet() { $this->_stack->push(__FUNCTION__, 'error', array(), 'Cannot validate files, no path to package file is set (use setPackageFile())'); } function _usesroletaskMustHaveChannelOrUri($role, $tag) { $this->_stack->push(__FUNCTION__, 'error', array('role' => $role, 'tag' => $tag), '<%tag%> for role "%role%" must contain either , or and '); } function _usesroletaskMustHavePackage($role, $tag) { $this->_stack->push(__FUNCTION__, 'error', array('role' => $role, 'tag' => $tag), '<%tag%> for role "%role%" must contain '); } function _usesroletaskMustHaveRoleTask($tag, $type) { $this->_stack->push(__FUNCTION__, 'error', array('tag' => $tag, 'type' => $type), '<%tag%> must contain <%type%> defining the %type% to be used'); } function _cannotConflictWithAllOs($type) { $this->_stack->push(__FUNCTION__, 'error', array('tag' => $tag), '%tag% cannot conflict with all OSes'); } function _invalidDepGroupName($name) { $this->_stack->push(__FUNCTION__, 'error', array('name' => $name), 'Invalid dependency group name "%name%"'); } function _multipleToplevelDirNotAllowed() { $this->_stack->push(__FUNCTION__, 'error', array(), 'Multiple top-level tags are not allowed. Enclose them ' . 'in a '); } function _multipleInstallAs($file) { $this->_stack->push(__FUNCTION__, 'error', array('file' => $file), 'Only one tag is allowed for file "%file%"'); } function _ignoreAndInstallAs($file) { $this->_stack->push(__FUNCTION__, 'error', array('file' => $file), 'Cannot have both and tags for file "%file%"'); } function _analyzeBundledPackages() { if (!$this->_isValid) { return false; } if (!$this->_pf->getPackageType() == 'bundle') { return false; } if (!isset($this->_pf->_packageFile)) { return false; } $dir_prefix = dirname($this->_pf->_packageFile); $common = new PEAR_Common; $log = isset($this->_pf->_logger) ? array(&$this->_pf->_logger, 'log') : array($common, 'log'); $info = $this->_pf->getContents(); $info = $info['bundledpackage']; if (!is_array($info)) { $info = array($info); } $pkg = new PEAR_PackageFile($this->_pf->_config); foreach ($info as $package) { if (!file_exists($dir_prefix . DIRECTORY_SEPARATOR . $package)) { $this->_fileNotFound($dir_prefix . DIRECTORY_SEPARATOR . $package); $this->_isValid = 0; continue; } call_user_func_array($log, array(1, "Analyzing bundled package $package")); PEAR::pushErrorHandling(PEAR_ERROR_RETURN); $ret = $pkg->fromAnyFile($dir_prefix . DIRECTORY_SEPARATOR . $package, PEAR_VALIDATE_NORMAL); PEAR::popErrorHandling(); if (PEAR::isError($ret)) { call_user_func_array($log, array(0, "ERROR: package $package is not a valid " . 'package')); $inf = $ret->getUserInfo(); if (is_array($inf)) { foreach ($inf as $err) { call_user_func_array($log, array(1, $err['message'])); } } return false; } } return true; } function _analyzePhpFiles() { if (!$this->_isValid) { return false; } if (!isset($this->_pf->_packageFile)) { $this->_cannotValidateNoPathSet(); return false; } $dir_prefix = dirname($this->_pf->_packageFile); $common = new PEAR_Common; $log = isset($this->_pf->_logger) ? array(&$this->_pf->_logger, 'log') : array(&$common, 'log'); $info = $this->_pf->getContents(); if (!$info || !isset($info['dir']['file'])) { $this->_tagCannotBeEmpty('contents>_fileNotFound($dir_prefix . DIRECTORY_SEPARATOR . $file); $this->_isValid = 0; continue; } if (in_array($fa['role'], PEAR_Installer_Role::getPhpRoles()) && $dir_prefix) { call_user_func_array($log, array(1, "Analyzing $file")); $srcinfo = $this->analyzeSourceCode($dir_prefix . DIRECTORY_SEPARATOR . $file); if ($srcinfo) { $provides = array_merge($provides, $this->_buildProvidesArray($srcinfo)); } } } $this->_packageName = $pn = $this->_pf->getPackage(); $pnl = strlen($pn); foreach ($provides as $key => $what) { if (isset($what['explicit']) || !$what) { // skip conformance checks if the provides entry is // specified in the package.xml file continue; } extract($what); if ($type == 'class') { if (!strncasecmp($name, $pn, $pnl)) { continue; } $this->_stack->push(__FUNCTION__, 'warning', array('file' => $file, 'type' => $type, 'name' => $name, 'package' => $pn), 'in %file%: %type% "%name%" not prefixed with package name "%package%"'); } elseif ($type == 'function') { if (strstr($name, '::') || !strncasecmp($name, $pn, $pnl)) { continue; } $this->_stack->push(__FUNCTION__, 'warning', array('file' => $file, 'type' => $type, 'name' => $name, 'package' => $pn), 'in %file%: %type% "%name%" not prefixed with package name "%package%"'); } } return $this->_isValid; } /** * Analyze the source code of the given PHP file * * @param string Filename of the PHP file * @param boolean whether to analyze $file as the file contents * @return mixed */ function analyzeSourceCode($file, $string = false) { if (!function_exists("token_get_all")) { $this->_stack->push(__FUNCTION__, 'error', array('file' => $file), 'Parser error: token_get_all() function must exist to analyze source code, PHP may have been compiled with --disable-tokenizer'); return false; } if (!defined('T_DOC_COMMENT')) { define('T_DOC_COMMENT', T_COMMENT); } if (!defined('T_INTERFACE')) { define('T_INTERFACE', -1); } if (!defined('T_IMPLEMENTS')) { define('T_IMPLEMENTS', -1); } if ($string) { $contents = $file; } else { if (!$fp = @fopen($file, "r")) { return false; } fclose($fp); $contents = file_get_contents($file); } // Silence this function so we can catch PHP Warnings and show our own custom message $tokens = @token_get_all($contents); if (isset($php_errormsg)) { if (isset($this->_stack)) { $pn = $this->_pf->getPackage(); $this->_stack->push(__FUNCTION__, 'warning', array('file' => $file, 'package' => $pn), 'in %file%: Could not process file for unknown reasons,' . ' possibly a PHP parse error in %file% from %package%'); } } /* for ($i = 0; $i < sizeof($tokens); $i++) { @list($token, $data) = $tokens[$i]; if (is_string($token)) { var_dump($token); } else { print token_name($token) . ' '; var_dump(rtrim($data)); } } */ $look_for = 0; $paren_level = 0; $bracket_level = 0; $brace_level = 0; $lastphpdoc = ''; $current_class = ''; $current_interface = ''; $current_class_level = -1; $current_function = ''; $current_function_level = -1; $declared_classes = array(); $declared_interfaces = array(); $declared_functions = array(); $declared_methods = array(); $used_classes = array(); $used_functions = array(); $extends = array(); $implements = array(); $nodeps = array(); $inquote = false; $interface = false; for ($i = 0; $i < sizeof($tokens); $i++) { if (is_array($tokens[$i])) { list($token, $data) = $tokens[$i]; } else { $token = $tokens[$i]; $data = ''; } if ($inquote) { if ($token != '"' && $token != T_END_HEREDOC) { continue; } else { $inquote = false; continue; } } switch ($token) { case T_WHITESPACE : continue 2; case ';': if ($interface) { $current_function = ''; $current_function_level = -1; } break; case '"': case T_START_HEREDOC: $inquote = true; break; case T_CURLY_OPEN: case T_DOLLAR_OPEN_CURLY_BRACES: case '{': $brace_level++; continue 2; case '}': $brace_level--; if ($current_class_level == $brace_level) { $current_class = ''; $current_class_level = -1; } if ($current_function_level == $brace_level) { $current_function = ''; $current_function_level = -1; } continue 2; case '[': $bracket_level++; continue 2; case ']': $bracket_level--; continue 2; case '(': $paren_level++; continue 2; case ')': $paren_level--; continue 2; case T_INTERFACE: $interface = true; case T_CLASS: if (($current_class_level != -1) || ($current_function_level != -1)) { if (isset($this->_stack)) { $this->_stack->push(__FUNCTION__, 'error', array('file' => $file), 'Parser error: invalid PHP found in file "%file%"'); } else { PEAR::raiseError("Parser error: invalid PHP found in file \"$file\"", PEAR_COMMON_ERROR_INVALIDPHP); } return false; } case T_FUNCTION: case T_NEW: case T_EXTENDS: case T_IMPLEMENTS: $look_for = $token; continue 2; case T_STRING: if ($look_for == T_CLASS) { $current_class = $data; $current_class_level = $brace_level; $declared_classes[] = $current_class; } elseif ($look_for == T_INTERFACE) { $current_interface = $data; $current_class_level = $brace_level; $declared_interfaces[] = $current_interface; } elseif ($look_for == T_IMPLEMENTS) { $implements[$current_class] = $data; } elseif ($look_for == T_EXTENDS) { $extends[$current_class] = $data; } elseif ($look_for == T_FUNCTION) { if ($current_class) { $current_function = "$current_class::$data"; $declared_methods[$current_class][] = $data; } elseif ($current_interface) { $current_function = "$current_interface::$data"; $declared_methods[$current_interface][] = $data; } else { $current_function = $data; $declared_functions[] = $current_function; } $current_function_level = $brace_level; $m = array(); } elseif ($look_for == T_NEW) { $used_classes[$data] = true; } $look_for = 0; continue 2; case T_VARIABLE: $look_for = 0; continue 2; case T_DOC_COMMENT: case T_COMMENT: if (preg_match('!^/\*\*\s!', $data)) { $lastphpdoc = $data; if (preg_match_all('/@nodep\s+(\S+)/', $lastphpdoc, $m)) { $nodeps = array_merge($nodeps, $m[1]); } } continue 2; case T_DOUBLE_COLON: $token = $tokens[$i - 1][0]; if (!($token == T_WHITESPACE || $token == T_STRING || $token == T_STATIC || $token == T_VARIABLE)) { if (isset($this->_stack)) { $this->_stack->push(__FUNCTION__, 'warning', array('file' => $file), 'Parser error: invalid PHP found in file "%file%"'); } else { PEAR::raiseError("Parser error: invalid PHP found in file \"$file\"", PEAR_COMMON_ERROR_INVALIDPHP); } return false; } $class = $tokens[$i - 1][1]; if (strtolower($class) != 'parent') { $used_classes[$class] = true; } continue 2; } } return array( "source_file" => $file, "declared_classes" => $declared_classes, "declared_interfaces" => $declared_interfaces, "declared_methods" => $declared_methods, "declared_functions" => $declared_functions, "used_classes" => array_diff(array_keys($used_classes), $nodeps), "inheritance" => $extends, "implements" => $implements, ); } /** * Build a "provides" array from data returned by * analyzeSourceCode(). The format of the built array is like * this: * * array( * 'class;MyClass' => 'array('type' => 'class', 'name' => 'MyClass'), * ... * ) * * * @param array $srcinfo array with information about a source file * as returned by the analyzeSourceCode() method. * * @return void * * @access private * */ function _buildProvidesArray($srcinfo) { if (!$this->_isValid) { return array(); } $providesret = array(); $file = basename($srcinfo['source_file']); $pn = isset($this->_pf) ? $this->_pf->getPackage() : ''; $pnl = strlen($pn); foreach ($srcinfo['declared_classes'] as $class) { $key = "class;$class"; if (isset($providesret[$key])) { continue; } $providesret[$key] = array('file'=> $file, 'type' => 'class', 'name' => $class); if (isset($srcinfo['inheritance'][$class])) { $providesret[$key]['extends'] = $srcinfo['inheritance'][$class]; } } foreach ($srcinfo['declared_methods'] as $class => $methods) { foreach ($methods as $method) { $function = "$class::$method"; $key = "function;$function"; if ($method[0] == '_' || !strcasecmp($method, $class) || isset($providesret[$key])) { continue; } $providesret[$key] = array('file'=> $file, 'type' => 'function', 'name' => $function); } } foreach ($srcinfo['declared_functions'] as $function) { $key = "function;$function"; if ($function[0] == '_' || isset($providesret[$key])) { continue; } if (!strstr($function, '::') && strncasecmp($function, $pn, $pnl)) { $warnings[] = "in1 " . $file . ": function \"$function\" not prefixed with package name \"$pn\""; } $providesret[$key] = array('file'=> $file, 'type' => 'function', 'name' => $function); } return $providesret; } } PKu]=__PEAR/PackageFile/v2/rw.phpnu[ * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a8 */ /** * For base class */ require_once 'PEAR/PackageFile/v2.php'; /** * @category pear * @package PEAR * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a8 */ class PEAR_PackageFile_v2_rw extends PEAR_PackageFile_v2 { /** * @param string Extension name * @return bool success of operation */ function setProvidesExtension($extension) { if (in_array($this->getPackageType(), array('extsrc', 'extbin', 'zendextsrc', 'zendextbin'))) { if (!isset($this->_packageInfo['providesextension'])) { // ensure that the channel tag is set up in the right location $this->_packageInfo = $this->_insertBefore($this->_packageInfo, array('usesrole', 'usestask', 'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'), $extension, 'providesextension'); } $this->_packageInfo['providesextension'] = $extension; return true; } return false; } function setPackage($package) { $this->_isValid = 0; if (!isset($this->_packageInfo['attribs'])) { $this->_packageInfo = array_merge(array('attribs' => array( 'version' => '2.0', 'xmlns' => 'http://pear.php.net/dtd/package-2.0', 'xmlns:tasks' => 'http://pear.php.net/dtd/tasks-1.0', 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', 'xsi:schemaLocation' => 'http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd', )), $this->_packageInfo); } if (!isset($this->_packageInfo['name'])) { return $this->_packageInfo = array_merge(array('name' => $package), $this->_packageInfo); } $this->_packageInfo['name'] = $package; } /** * set this as a package.xml version 2.1 * @access private */ function _setPackageVersion2_1() { $info = array( 'version' => '2.1', 'xmlns' => 'http://pear.php.net/dtd/package-2.1', 'xmlns:tasks' => 'http://pear.php.net/dtd/tasks-1.0', 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', 'xsi:schemaLocation' => 'http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.1 http://pear.php.net/dtd/package-2.1.xsd', ); if (!isset($this->_packageInfo['attribs'])) { $this->_packageInfo = array_merge(array('attribs' => $info), $this->_packageInfo); } else { $this->_packageInfo['attribs'] = $info; } } function setUri($uri) { unset($this->_packageInfo['channel']); $this->_isValid = 0; if (!isset($this->_packageInfo['uri'])) { // ensure that the uri tag is set up in the right location $this->_packageInfo = $this->_insertBefore($this->_packageInfo, array('extends', 'summary', 'description', 'lead', 'developer', 'contributor', 'helper', 'date', 'time', 'version', 'stability', 'license', 'notes', 'contents', 'compatible', 'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease', 'extbinrelease', 'bundle', 'changelog'), $uri, 'uri'); } $this->_packageInfo['uri'] = $uri; } function setChannel($channel) { unset($this->_packageInfo['uri']); $this->_isValid = 0; if (!isset($this->_packageInfo['channel'])) { // ensure that the channel tag is set up in the right location $this->_packageInfo = $this->_insertBefore($this->_packageInfo, array('extends', 'summary', 'description', 'lead', 'developer', 'contributor', 'helper', 'date', 'time', 'version', 'stability', 'license', 'notes', 'contents', 'compatible', 'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease', 'extbinrelease', 'bundle', 'changelog'), $channel, 'channel'); } $this->_packageInfo['channel'] = $channel; } function setExtends($extends) { $this->_isValid = 0; if (!isset($this->_packageInfo['extends'])) { // ensure that the extends tag is set up in the right location $this->_packageInfo = $this->_insertBefore($this->_packageInfo, array('summary', 'description', 'lead', 'developer', 'contributor', 'helper', 'date', 'time', 'version', 'stability', 'license', 'notes', 'contents', 'compatible', 'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease', 'extbinrelease', 'bundle', 'changelog'), $extends, 'extends'); } $this->_packageInfo['extends'] = $extends; } function setSummary($summary) { $this->_isValid = 0; if (!isset($this->_packageInfo['summary'])) { // ensure that the summary tag is set up in the right location $this->_packageInfo = $this->_insertBefore($this->_packageInfo, array('description', 'lead', 'developer', 'contributor', 'helper', 'date', 'time', 'version', 'stability', 'license', 'notes', 'contents', 'compatible', 'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease', 'extbinrelease', 'bundle', 'changelog'), $summary, 'summary'); } $this->_packageInfo['summary'] = $summary; } function setDescription($desc) { $this->_isValid = 0; if (!isset($this->_packageInfo['description'])) { // ensure that the description tag is set up in the right location $this->_packageInfo = $this->_insertBefore($this->_packageInfo, array('lead', 'developer', 'contributor', 'helper', 'date', 'time', 'version', 'stability', 'license', 'notes', 'contents', 'compatible', 'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease', 'extbinrelease', 'bundle', 'changelog'), $desc, 'description'); } $this->_packageInfo['description'] = $desc; } /** * Adds a new maintainer - no checking of duplicates is performed, use * updatemaintainer for that purpose. */ function addMaintainer($role, $handle, $name, $email, $active = 'yes') { if (!in_array($role, array('lead', 'developer', 'contributor', 'helper'))) { return false; } if (isset($this->_packageInfo[$role])) { if (!isset($this->_packageInfo[$role][0])) { $this->_packageInfo[$role] = array($this->_packageInfo[$role]); } $this->_packageInfo[$role][] = array( 'name' => $name, 'user' => $handle, 'email' => $email, 'active' => $active, ); } else { $testarr = array('lead', 'developer', 'contributor', 'helper', 'date', 'time', 'version', 'stability', 'license', 'notes', 'contents', 'compatible', 'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'); foreach (array('lead', 'developer', 'contributor', 'helper') as $testrole) { array_shift($testarr); if ($role == $testrole) { break; } } if (!isset($this->_packageInfo[$role])) { // ensure that the extends tag is set up in the right location $this->_packageInfo = $this->_insertBefore($this->_packageInfo, $testarr, array(), $role); } $this->_packageInfo[$role] = array( 'name' => $name, 'user' => $handle, 'email' => $email, 'active' => $active, ); } $this->_isValid = 0; } function updateMaintainer($newrole, $handle, $name, $email, $active = 'yes') { $found = false; foreach (array('lead', 'developer', 'contributor', 'helper') as $role) { if (!isset($this->_packageInfo[$role])) { continue; } $info = $this->_packageInfo[$role]; if (!isset($info[0])) { if ($info['user'] == $handle) { $found = true; break; } } foreach ($info as $i => $maintainer) { if (is_array($maintainer) && $maintainer['user'] == $handle) { $found = $i; break 2; } } } if ($found === false) { return $this->addMaintainer($newrole, $handle, $name, $email, $active); } if ($found !== false) { if ($found === true) { unset($this->_packageInfo[$role]); } else { unset($this->_packageInfo[$role][$found]); $this->_packageInfo[$role] = array_values($this->_packageInfo[$role]); } } $this->addMaintainer($newrole, $handle, $name, $email, $active); $this->_isValid = 0; } function deleteMaintainer($handle) { $found = false; foreach (array('lead', 'developer', 'contributor', 'helper') as $role) { if (!isset($this->_packageInfo[$role])) { continue; } if (!isset($this->_packageInfo[$role][0])) { $this->_packageInfo[$role] = array($this->_packageInfo[$role]); } foreach ($this->_packageInfo[$role] as $i => $maintainer) { if ($maintainer['user'] == $handle) { $found = $i; break; } } if ($found !== false) { unset($this->_packageInfo[$role][$found]); if (!count($this->_packageInfo[$role]) && $role == 'lead') { $this->_isValid = 0; } if (!count($this->_packageInfo[$role])) { unset($this->_packageInfo[$role]); return true; } $this->_packageInfo[$role] = array_values($this->_packageInfo[$role]); if (count($this->_packageInfo[$role]) == 1) { $this->_packageInfo[$role] = $this->_packageInfo[$role][0]; } return true; } if (count($this->_packageInfo[$role]) == 1) { $this->_packageInfo[$role] = $this->_packageInfo[$role][0]; } } return false; } function setReleaseVersion($version) { if (isset($this->_packageInfo['version']) && isset($this->_packageInfo['version']['release'])) { unset($this->_packageInfo['version']['release']); } $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $version, array( 'version' => array('stability', 'license', 'notes', 'contents', 'compatible', 'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease', 'extbinrelease', 'bundle', 'changelog'), 'release' => array('api'))); $this->_isValid = 0; } function setAPIVersion($version) { if (isset($this->_packageInfo['version']) && isset($this->_packageInfo['version']['api'])) { unset($this->_packageInfo['version']['api']); } $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $version, array( 'version' => array('stability', 'license', 'notes', 'contents', 'compatible', 'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease', 'extbinrelease', 'bundle', 'changelog'), 'api' => array())); $this->_isValid = 0; } /** * snapshot|devel|alpha|beta|stable */ function setReleaseStability($state) { if (isset($this->_packageInfo['stability']) && isset($this->_packageInfo['stability']['release'])) { unset($this->_packageInfo['stability']['release']); } $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $state, array( 'stability' => array('license', 'notes', 'contents', 'compatible', 'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease', 'extbinrelease', 'bundle', 'changelog'), 'release' => array('api'))); $this->_isValid = 0; } /** * @param devel|alpha|beta|stable */ function setAPIStability($state) { if (isset($this->_packageInfo['stability']) && isset($this->_packageInfo['stability']['api'])) { unset($this->_packageInfo['stability']['api']); } $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $state, array( 'stability' => array('license', 'notes', 'contents', 'compatible', 'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease', 'extbinrelease', 'bundle', 'changelog'), 'api' => array())); $this->_isValid = 0; } function setLicense($license, $uri = false, $filesource = false) { if (!isset($this->_packageInfo['license'])) { // ensure that the license tag is set up in the right location $this->_packageInfo = $this->_insertBefore($this->_packageInfo, array('notes', 'contents', 'compatible', 'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease', 'extbinrelease', 'bundle', 'changelog'), 0, 'license'); } if ($uri || $filesource) { $attribs = array(); if ($uri) { $attribs['uri'] = $uri; } $uri = true; // for test below if ($filesource) { $attribs['filesource'] = $filesource; } } $license = $uri ? array('attribs' => $attribs, '_content' => $license) : $license; $this->_packageInfo['license'] = $license; $this->_isValid = 0; } function setNotes($notes) { $this->_isValid = 0; if (!isset($this->_packageInfo['notes'])) { // ensure that the notes tag is set up in the right location $this->_packageInfo = $this->_insertBefore($this->_packageInfo, array('contents', 'compatible', 'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease', 'extbinrelease', 'bundle', 'changelog'), $notes, 'notes'); } $this->_packageInfo['notes'] = $notes; } /** * This is only used at install-time, after all serialization * is over. * @param string file name * @param string installed path */ function setInstalledAs($file, $path) { if ($path) { return $this->_packageInfo['filelist'][$file]['installed_as'] = $path; } unset($this->_packageInfo['filelist'][$file]['installed_as']); } /** * This is only used at install-time, after all serialization * is over. */ function installedFile($file, $atts) { if (isset($this->_packageInfo['filelist'][$file])) { $this->_packageInfo['filelist'][$file] = array_merge($this->_packageInfo['filelist'][$file], $atts['attribs']); } else { $this->_packageInfo['filelist'][$file] = $atts['attribs']; } } /** * Reset the listing of package contents * @param string base installation dir for the whole package, if any */ function clearContents($baseinstall = false) { $this->_filesValid = false; $this->_isValid = 0; if (!isset($this->_packageInfo['contents'])) { $this->_packageInfo = $this->_insertBefore($this->_packageInfo, array('compatible', 'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'), array(), 'contents'); } if ($this->getPackageType() != 'bundle') { $this->_packageInfo['contents'] = array('dir' => array('attribs' => array('name' => '/'))); if ($baseinstall) { $this->_packageInfo['contents']['dir']['attribs']['baseinstalldir'] = $baseinstall; } } else { $this->_packageInfo['contents'] = array('bundledpackage' => array()); } } /** * @param string relative path of the bundled package. */ function addBundledPackage($path) { if ($this->getPackageType() != 'bundle') { return false; } $this->_filesValid = false; $this->_isValid = 0; $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $path, array( 'contents' => array('compatible', 'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'), 'bundledpackage' => array())); } /** * @param string file name * @param PEAR_Task_Common a read/write task */ function addTaskToFile($filename, $task) { if (!method_exists($task, 'getXml')) { return false; } if (!method_exists($task, 'getName')) { return false; } if (!method_exists($task, 'validate')) { return false; } if (!$task->validate()) { return false; } if (!isset($this->_packageInfo['contents']['dir']['file'])) { return false; } $this->getTasksNs(); // discover the tasks namespace if not done already $files = $this->_packageInfo['contents']['dir']['file']; if (!isset($files[0])) { $files = array($files); $ind = false; } else { $ind = true; } foreach ($files as $i => $file) { if (isset($file['attribs'])) { if ($file['attribs']['name'] == $filename) { if ($ind) { $t = isset($this->_packageInfo['contents']['dir']['file'][$i] ['attribs'][$this->_tasksNs . ':' . $task->getName()]) ? $this->_packageInfo['contents']['dir']['file'][$i] ['attribs'][$this->_tasksNs . ':' . $task->getName()] : false; if ($t && !isset($t[0])) { $this->_packageInfo['contents']['dir']['file'][$i] [$this->_tasksNs . ':' . $task->getName()] = array($t); } $this->_packageInfo['contents']['dir']['file'][$i][$this->_tasksNs . ':' . $task->getName()][] = $task->getXml(); } else { $t = isset($this->_packageInfo['contents']['dir']['file'] ['attribs'][$this->_tasksNs . ':' . $task->getName()]) ? $this->_packageInfo['contents']['dir']['file'] ['attribs'][$this->_tasksNs . ':' . $task->getName()] : false; if ($t && !isset($t[0])) { $this->_packageInfo['contents']['dir']['file'] [$this->_tasksNs . ':' . $task->getName()] = array($t); } $this->_packageInfo['contents']['dir']['file'][$this->_tasksNs . ':' . $task->getName()][] = $task->getXml(); } return true; } } } return false; } /** * @param string path to the file * @param string filename * @param array extra attributes */ function addFile($dir, $file, $attrs) { if ($this->getPackageType() == 'bundle') { return false; } $this->_filesValid = false; $this->_isValid = 0; $dir = preg_replace(array('!\\\\+!', '!/+!'), array('/', '/'), $dir); if ($dir == '/' || $dir == '') { $dir = ''; } else { $dir .= '/'; } $attrs['name'] = $dir . $file; if (!isset($this->_packageInfo['contents'])) { // ensure that the contents tag is set up $this->_packageInfo = $this->_insertBefore($this->_packageInfo, array('compatible', 'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'), array(), 'contents'); } if (isset($this->_packageInfo['contents']['dir']['file'])) { if (!isset($this->_packageInfo['contents']['dir']['file'][0])) { $this->_packageInfo['contents']['dir']['file'] = array($this->_packageInfo['contents']['dir']['file']); } $this->_packageInfo['contents']['dir']['file'][]['attribs'] = $attrs; } else { $this->_packageInfo['contents']['dir']['file']['attribs'] = $attrs; } } /** * @param string Dependent package name * @param string Dependent package's channel name * @param string minimum version of specified package that this release is guaranteed to be * compatible with * @param string maximum version of specified package that this release is guaranteed to be * compatible with * @param string versions of specified package that this release is not compatible with */ function addCompatiblePackage($name, $channel, $min, $max, $exclude = false) { $this->_isValid = 0; $set = array( 'name' => $name, 'channel' => $channel, 'min' => $min, 'max' => $max, ); if ($exclude) { $set['exclude'] = $exclude; } $this->_isValid = 0; $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $set, array( 'compatible' => array('dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog') )); } /** * Removes the tag entirely */ function resetUsesrole() { if (isset($this->_packageInfo['usesrole'])) { unset($this->_packageInfo['usesrole']); } } /** * @param string * @param string package name or uri * @param string channel name if non-uri */ function addUsesrole($role, $packageOrUri, $channel = false) { $set = array('role' => $role); if ($channel) { $set['package'] = $packageOrUri; $set['channel'] = $channel; } else { $set['uri'] = $packageOrUri; } $this->_isValid = 0; $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $set, array( 'usesrole' => array('usestask', 'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog') )); } /** * Removes the tag entirely */ function resetUsestask() { if (isset($this->_packageInfo['usestask'])) { unset($this->_packageInfo['usestask']); } } /** * @param string * @param string package name or uri * @param string channel name if non-uri */ function addUsestask($task, $packageOrUri, $channel = false) { $set = array('task' => $task); if ($channel) { $set['package'] = $packageOrUri; $set['channel'] = $channel; } else { $set['uri'] = $packageOrUri; } $this->_isValid = 0; $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $set, array( 'usestask' => array('srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog') )); } /** * Remove all compatible tags */ function clearCompatible() { unset($this->_packageInfo['compatible']); } /** * Reset dependencies prior to adding new ones */ function clearDeps() { if (!isset($this->_packageInfo['dependencies'])) { $this->_packageInfo = $this->_mergeTag($this->_packageInfo, array(), array( 'dependencies' => array('providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'))); } $this->_packageInfo['dependencies'] = array(); } /** * @param string minimum PHP version allowed * @param string maximum PHP version allowed * @param array $exclude incompatible PHP versions */ function setPhpDep($min, $max = false, $exclude = false) { $this->_isValid = 0; $dep = array( 'min' => $min, ); if ($max) { $dep['max'] = $max; } if ($exclude) { if (count($exclude) == 1) { $exclude = $exclude[0]; } $dep['exclude'] = $exclude; } if (isset($this->_packageInfo['dependencies']['required']['php'])) { $this->_stack->push(__FUNCTION__, 'warning', array('dep' => $this->_packageInfo['dependencies']['required']['php']), 'warning: PHP dependency already exists, overwriting'); unset($this->_packageInfo['dependencies']['required']['php']); } $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep, array( 'dependencies' => array('providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'), 'required' => array('optional', 'group'), 'php' => array('pearinstaller', 'package', 'subpackage', 'extension', 'os', 'arch') )); return true; } /** * @param string minimum allowed PEAR installer version * @param string maximum allowed PEAR installer version * @param string recommended PEAR installer version * @param array incompatible version of the PEAR installer */ function setPearinstallerDep($min, $max = false, $recommended = false, $exclude = false) { $this->_isValid = 0; $dep = array( 'min' => $min, ); if ($max) { $dep['max'] = $max; } if ($recommended) { $dep['recommended'] = $recommended; } if ($exclude) { if (count($exclude) == 1) { $exclude = $exclude[0]; } $dep['exclude'] = $exclude; } if (isset($this->_packageInfo['dependencies']['required']['pearinstaller'])) { $this->_stack->push(__FUNCTION__, 'warning', array('dep' => $this->_packageInfo['dependencies']['required']['pearinstaller']), 'warning: PEAR Installer dependency already exists, overwriting'); unset($this->_packageInfo['dependencies']['required']['pearinstaller']); } $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep, array( 'dependencies' => array('providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'), 'required' => array('optional', 'group'), 'pearinstaller' => array('package', 'subpackage', 'extension', 'os', 'arch') )); } /** * Mark a package as conflicting with this package * @param string package name * @param string package channel * @param string extension this package provides, if any * @param string|false minimum version required * @param string|false maximum version allowed * @param array|false versions to exclude from installation */ function addConflictingPackageDepWithChannel($name, $channel, $providesextension = false, $min = false, $max = false, $exclude = false) { $this->_isValid = 0; $dep = $this->_constructDep($name, $channel, false, $min, $max, false, $exclude, $providesextension, false, true); $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep, array( 'dependencies' => array('providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'), 'required' => array('optional', 'group'), 'package' => array('subpackage', 'extension', 'os', 'arch') )); } /** * Mark a package as conflicting with this package * @param string package name * @param string package channel * @param string extension this package provides, if any */ function addConflictingPackageDepWithUri($name, $uri, $providesextension = false) { $this->_isValid = 0; $dep = array( 'name' => $name, 'uri' => $uri, 'conflicts' => '', ); if ($providesextension) { $dep['providesextension'] = $providesextension; } $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep, array( 'dependencies' => array('providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'), 'required' => array('optional', 'group'), 'package' => array('subpackage', 'extension', 'os', 'arch') )); } function addDependencyGroup($name, $hint) { $this->_isValid = 0; $this->_packageInfo = $this->_mergeTag($this->_packageInfo, array('attribs' => array('name' => $name, 'hint' => $hint)), array( 'dependencies' => array('providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'), 'group' => array(), )); } /** * @param string package name * @param string|false channel name, false if this is a uri * @param string|false uri name, false if this is a channel * @param string|false minimum version required * @param string|false maximum version allowed * @param string|false recommended installation version * @param array|false versions to exclude from installation * @param string extension this package provides, if any * @param bool if true, tells the installer to ignore the default optional dependency group * when installing this package * @param bool if true, tells the installer to negate this dependency (conflicts) * @return array * @access private */ function _constructDep($name, $channel, $uri, $min, $max, $recommended, $exclude, $providesextension = false, $nodefault = false, $conflicts = false) { $dep = array( 'name' => $name, ); if ($channel) { $dep['channel'] = $channel; } elseif ($uri) { $dep['uri'] = $uri; } if ($min) { $dep['min'] = $min; } if ($max) { $dep['max'] = $max; } if ($recommended) { $dep['recommended'] = $recommended; } if ($exclude) { if (is_array($exclude) && count($exclude) == 1) { $exclude = $exclude[0]; } $dep['exclude'] = $exclude; } if ($conflicts) { $dep['conflicts'] = ''; } if ($nodefault) { $dep['nodefault'] = ''; } if ($providesextension) { $dep['providesextension'] = $providesextension; } return $dep; } /** * @param package|subpackage * @param string group name * @param string package name * @param string package channel * @param string minimum version * @param string maximum version * @param string recommended version * @param array|false optional excluded versions * @param string extension this package provides, if any * @param bool if true, tells the installer to ignore the default optional dependency group * when installing this package * @return bool false if the dependency group has not been initialized with * {@link addDependencyGroup()}, or a subpackage is added with * a providesextension */ function addGroupPackageDepWithChannel($type, $groupname, $name, $channel, $min = false, $max = false, $recommended = false, $exclude = false, $providesextension = false, $nodefault = false) { if ($type == 'subpackage' && $providesextension) { return false; // subpackages must be php packages } $dep = $this->_constructDep($name, $channel, false, $min, $max, $recommended, $exclude, $providesextension, $nodefault); return $this->_addGroupDependency($type, $dep, $groupname); } /** * @param package|subpackage * @param string group name * @param string package name * @param string package uri * @param string extension this package provides, if any * @param bool if true, tells the installer to ignore the default optional dependency group * when installing this package * @return bool false if the dependency group has not been initialized with * {@link addDependencyGroup()} */ function addGroupPackageDepWithURI($type, $groupname, $name, $uri, $providesextension = false, $nodefault = false) { if ($type == 'subpackage' && $providesextension) { return false; // subpackages must be php packages } $dep = $this->_constructDep($name, false, $uri, false, false, false, false, $providesextension, $nodefault); return $this->_addGroupDependency($type, $dep, $groupname); } /** * @param string group name (must be pre-existing) * @param string extension name * @param string minimum version allowed * @param string maximum version allowed * @param string recommended version * @param array incompatible versions */ function addGroupExtensionDep($groupname, $name, $min = false, $max = false, $recommended = false, $exclude = false) { $this->_isValid = 0; $dep = $this->_constructDep($name, false, false, $min, $max, $recommended, $exclude); return $this->_addGroupDependency('extension', $dep, $groupname); } /** * @param package|subpackage|extension * @param array dependency contents * @param string name of the dependency group to add this to * @return boolean * @access private */ function _addGroupDependency($type, $dep, $groupname) { $arr = array('subpackage', 'extension'); if ($type != 'package') { array_shift($arr); } if ($type == 'extension') { array_shift($arr); } if (!isset($this->_packageInfo['dependencies']['group'])) { return false; } else { if (!isset($this->_packageInfo['dependencies']['group'][0])) { if ($this->_packageInfo['dependencies']['group']['attribs']['name'] == $groupname) { $this->_packageInfo['dependencies']['group'] = $this->_mergeTag( $this->_packageInfo['dependencies']['group'], $dep, array( $type => $arr )); $this->_isValid = 0; return true; } else { return false; } } else { foreach ($this->_packageInfo['dependencies']['group'] as $i => $group) { if ($group['attribs']['name'] == $groupname) { $this->_packageInfo['dependencies']['group'][$i] = $this->_mergeTag( $this->_packageInfo['dependencies']['group'][$i], $dep, array( $type => $arr )); $this->_isValid = 0; return true; } } return false; } } } /** * @param optional|required * @param string package name * @param string package channel * @param string minimum version * @param string maximum version * @param string recommended version * @param string extension this package provides, if any * @param bool if true, tells the installer to ignore the default optional dependency group * when installing this package * @param array|false optional excluded versions */ function addPackageDepWithChannel($type, $name, $channel, $min = false, $max = false, $recommended = false, $exclude = false, $providesextension = false, $nodefault = false) { if (!in_array($type, array('optional', 'required'), true)) { $type = 'required'; } $this->_isValid = 0; $arr = array('optional', 'group'); if ($type != 'required') { array_shift($arr); } $dep = $this->_constructDep($name, $channel, false, $min, $max, $recommended, $exclude, $providesextension, $nodefault); $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep, array( 'dependencies' => array('providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'), $type => $arr, 'package' => array('subpackage', 'extension', 'os', 'arch') )); } /** * @param optional|required * @param string name of the package * @param string uri of the package * @param string extension this package provides, if any * @param bool if true, tells the installer to ignore the default optional dependency group * when installing this package */ function addPackageDepWithUri($type, $name, $uri, $providesextension = false, $nodefault = false) { $this->_isValid = 0; $arr = array('optional', 'group'); if ($type != 'required') { array_shift($arr); } $dep = $this->_constructDep($name, false, $uri, false, false, false, false, $providesextension, $nodefault); $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep, array( 'dependencies' => array('providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'), $type => $arr, 'package' => array('subpackage', 'extension', 'os', 'arch') )); } /** * @param optional|required optional, required * @param string package name * @param string package channel * @param string minimum version * @param string maximum version * @param string recommended version * @param array incompatible versions * @param bool if true, tells the installer to ignore the default optional dependency group * when installing this package */ function addSubpackageDepWithChannel($type, $name, $channel, $min = false, $max = false, $recommended = false, $exclude = false, $nodefault = false) { $this->_isValid = 0; $arr = array('optional', 'group'); if ($type != 'required') { array_shift($arr); } $dep = $this->_constructDep($name, $channel, false, $min, $max, $recommended, $exclude, $nodefault); $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep, array( 'dependencies' => array('providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'), $type => $arr, 'subpackage' => array('extension', 'os', 'arch') )); } /** * @param optional|required optional, required * @param string package name * @param string package uri for download * @param bool if true, tells the installer to ignore the default optional dependency group * when installing this package */ function addSubpackageDepWithUri($type, $name, $uri, $nodefault = false) { $this->_isValid = 0; $arr = array('optional', 'group'); if ($type != 'required') { array_shift($arr); } $dep = $this->_constructDep($name, false, $uri, false, false, false, false, $nodefault); $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep, array( 'dependencies' => array('providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'), $type => $arr, 'subpackage' => array('extension', 'os', 'arch') )); } /** * @param optional|required optional, required * @param string extension name * @param string minimum version * @param string maximum version * @param string recommended version * @param array incompatible versions */ function addExtensionDep($type, $name, $min = false, $max = false, $recommended = false, $exclude = false) { $this->_isValid = 0; $arr = array('optional', 'group'); if ($type != 'required') { array_shift($arr); } $dep = $this->_constructDep($name, false, false, $min, $max, $recommended, $exclude); $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep, array( 'dependencies' => array('providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'), $type => $arr, 'extension' => array('os', 'arch') )); } /** * @param string Operating system name * @param boolean true if this package cannot be installed on this OS */ function addOsDep($name, $conflicts = false) { $this->_isValid = 0; $dep = array('name' => $name); if ($conflicts) { $dep['conflicts'] = ''; } $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep, array( 'dependencies' => array('providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'), 'required' => array('optional', 'group'), 'os' => array('arch') )); } /** * @param string Architecture matching pattern * @param boolean true if this package cannot be installed on this architecture */ function addArchDep($pattern, $conflicts = false) { $this->_isValid = 0; $dep = array('pattern' => $pattern); if ($conflicts) { $dep['conflicts'] = ''; } $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep, array( 'dependencies' => array('providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'), 'required' => array('optional', 'group'), 'arch' => array() )); } /** * Set the kind of package, and erase all release tags * * - a php package is a PEAR-style package * - an extbin package is a PECL-style extension binary * - an extsrc package is a PECL-style source for a binary * - an zendextbin package is a PECL-style zend extension binary * - an zendextsrc package is a PECL-style source for a zend extension binary * - a bundle package is a collection of other pre-packaged packages * @param php|extbin|extsrc|zendextsrc|zendextbin|bundle * @return bool success */ function setPackageType($type) { $this->_isValid = 0; if (!in_array($type, array('php', 'extbin', 'extsrc', 'zendextsrc', 'zendextbin', 'bundle'))) { return false; } if (in_array($type, array('zendextsrc', 'zendextbin'))) { $this->_setPackageVersion2_1(); } if ($type != 'bundle') { $type .= 'release'; } foreach (array('phprelease', 'extbinrelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease', 'bundle') as $test) { unset($this->_packageInfo[$test]); } if (!isset($this->_packageInfo[$type])) { // ensure that the release tag is set up $this->_packageInfo = $this->_insertBefore($this->_packageInfo, array('changelog'), array(), $type); } $this->_packageInfo[$type] = array(); return true; } /** * @return bool true if package type is set up */ function addRelease() { if ($type = $this->getPackageType()) { if ($type != 'bundle') { $type .= 'release'; } $this->_packageInfo = $this->_mergeTag($this->_packageInfo, array(), array($type => array('changelog'))); return true; } return false; } /** * Get the current release tag in order to add to it * @param bool returns only releases that have installcondition if true * @return array|null */ function &_getCurrentRelease($strict = true) { if ($p = $this->getPackageType()) { if ($strict) { if ($p == 'extsrc' || $p == 'zendextsrc') { $a = null; return $a; } } if ($p != 'bundle') { $p .= 'release'; } if (isset($this->_packageInfo[$p][0])) { return $this->_packageInfo[$p][count($this->_packageInfo[$p]) - 1]; } else { return $this->_packageInfo[$p]; } } else { $a = null; return $a; } } /** * Add a file to the current release that should be installed under a different name * @param string path to file * @param string name the file should be installed as */ function addInstallAs($path, $as) { $r = &$this->_getCurrentRelease(); if ($r === null) { return false; } $this->_isValid = 0; $r = $this->_mergeTag($r, array('attribs' => array('name' => $path, 'as' => $as)), array( 'filelist' => array(), 'install' => array('ignore') )); } /** * Add a file to the current release that should be ignored * @param string path to file * @return bool success of operation */ function addIgnore($path) { $r = &$this->_getCurrentRelease(); if ($r === null) { return false; } $this->_isValid = 0; $r = $this->_mergeTag($r, array('attribs' => array('name' => $path)), array( 'filelist' => array(), 'ignore' => array() )); } /** * Add an extension binary package for this extension source code release * * Note that the package must be from the same channel as the extension source package * @param string */ function addBinarypackage($package) { if ($this->getPackageType() != 'extsrc' && $this->getPackageType() != 'zendextsrc') { return false; } $r = &$this->_getCurrentRelease(false); if ($r === null) { return false; } $this->_isValid = 0; $r = $this->_mergeTag($r, $package, array( 'binarypackage' => array('filelist'), )); } /** * Add a configureoption to an extension source package * @param string * @param string * @param string */ function addConfigureOption($name, $prompt, $default = null) { if ($this->getPackageType() != 'extsrc' && $this->getPackageType() != 'zendextsrc') { return false; } $r = &$this->_getCurrentRelease(false); if ($r === null) { return false; } $opt = array('attribs' => array('name' => $name, 'prompt' => $prompt)); if ($default !== null) { $opt['attribs']['default'] = $default; } $this->_isValid = 0; $r = $this->_mergeTag($r, $opt, array( 'configureoption' => array('binarypackage', 'filelist'), )); } /** * Set an installation condition based on php version for the current release set * @param string minimum version * @param string maximum version * @param false|array incompatible versions of PHP */ function setPhpInstallCondition($min, $max, $exclude = false) { $r = &$this->_getCurrentRelease(); if ($r === null) { return false; } $this->_isValid = 0; if (isset($r['installconditions']['php'])) { unset($r['installconditions']['php']); } $dep = array('min' => $min, 'max' => $max); if ($exclude) { if (is_array($exclude) && count($exclude) == 1) { $exclude = $exclude[0]; } $dep['exclude'] = $exclude; } if ($this->getPackageType() == 'extsrc' || $this->getPackageType() == 'zendextsrc') { $r = $this->_mergeTag($r, $dep, array( 'installconditions' => array('configureoption', 'binarypackage', 'filelist'), 'php' => array('extension', 'os', 'arch') )); } else { $r = $this->_mergeTag($r, $dep, array( 'installconditions' => array('filelist'), 'php' => array('extension', 'os', 'arch') )); } } /** * @param optional|required optional, required * @param string extension name * @param string minimum version * @param string maximum version * @param string recommended version * @param array incompatible versions */ function addExtensionInstallCondition($name, $min = false, $max = false, $recommended = false, $exclude = false) { $r = &$this->_getCurrentRelease(); if ($r === null) { return false; } $this->_isValid = 0; $dep = $this->_constructDep($name, false, false, $min, $max, $recommended, $exclude); if ($this->getPackageType() == 'extsrc' || $this->getPackageType() == 'zendextsrc') { $r = $this->_mergeTag($r, $dep, array( 'installconditions' => array('configureoption', 'binarypackage', 'filelist'), 'extension' => array('os', 'arch') )); } else { $r = $this->_mergeTag($r, $dep, array( 'installconditions' => array('filelist'), 'extension' => array('os', 'arch') )); } } /** * Set an installation condition based on operating system for the current release set * @param string OS name * @param bool whether this OS is incompatible with the current release */ function setOsInstallCondition($name, $conflicts = false) { $r = &$this->_getCurrentRelease(); if ($r === null) { return false; } $this->_isValid = 0; if (isset($r['installconditions']['os'])) { unset($r['installconditions']['os']); } $dep = array('name' => $name); if ($conflicts) { $dep['conflicts'] = ''; } if ($this->getPackageType() == 'extsrc' || $this->getPackageType() == 'zendextsrc') { $r = $this->_mergeTag($r, $dep, array( 'installconditions' => array('configureoption', 'binarypackage', 'filelist'), 'os' => array('arch') )); } else { $r = $this->_mergeTag($r, $dep, array( 'installconditions' => array('filelist'), 'os' => array('arch') )); } } /** * Set an installation condition based on architecture for the current release set * @param string architecture pattern * @param bool whether this arch is incompatible with the current release */ function setArchInstallCondition($pattern, $conflicts = false) { $r = &$this->_getCurrentRelease(); if ($r === null) { return false; } $this->_isValid = 0; if (isset($r['installconditions']['arch'])) { unset($r['installconditions']['arch']); } $dep = array('pattern' => $pattern); if ($conflicts) { $dep['conflicts'] = ''; } if ($this->getPackageType() == 'extsrc' || $this->getPackageType() == 'zendextsrc') { $r = $this->_mergeTag($r, $dep, array( 'installconditions' => array('configureoption', 'binarypackage', 'filelist'), 'arch' => array() )); } else { $r = $this->_mergeTag($r, $dep, array( 'installconditions' => array('filelist'), 'arch' => array() )); } } /** * For extension binary releases, this is used to specify either the * static URI to a source package, or the package name and channel of the extsrc/zendextsrc * package it is based on. * @param string Package name, or full URI to source package (extsrc/zendextsrc type) */ function setSourcePackage($packageOrUri) { $this->_isValid = 0; if (isset($this->_packageInfo['channel'])) { $this->_packageInfo = $this->_insertBefore($this->_packageInfo, array('phprelease', 'extsrcrelease', 'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'), $packageOrUri, 'srcpackage'); } else { $this->_packageInfo = $this->_insertBefore($this->_packageInfo, array('phprelease', 'extsrcrelease', 'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'), $packageOrUri, 'srcuri'); } } /** * Generate a valid change log entry from the current package.xml * @param string|false */ function generateChangeLogEntry($notes = false) { return array( 'version' => array( 'release' => $this->getVersion('release'), 'api' => $this->getVersion('api'), ), 'stability' => $this->getStability(), 'date' => $this->getDate(), 'license' => $this->getLicense(true), 'notes' => $notes ? $notes : $this->getNotes() ); } /** * @param string release version to set change log notes for * @param array output of {@link generateChangeLogEntry()} */ function setChangelogEntry($releaseversion, $contents) { if (!isset($this->_packageInfo['changelog'])) { $this->_packageInfo['changelog']['release'] = $contents; return; } if (!isset($this->_packageInfo['changelog']['release'][0])) { if ($this->_packageInfo['changelog']['release']['version']['release'] == $releaseversion) { $this->_packageInfo['changelog']['release'] = array( $this->_packageInfo['changelog']['release']); } else { $this->_packageInfo['changelog']['release'] = array( $this->_packageInfo['changelog']['release']); return $this->_packageInfo['changelog']['release'][] = $contents; } } foreach($this->_packageInfo['changelog']['release'] as $index => $changelog) { if (isset($changelog['version']) && strnatcasecmp($changelog['version']['release'], $releaseversion) == 0) { $curlog = $index; } } if (isset($curlog)) { $this->_packageInfo['changelog']['release'][$curlog] = $contents; } else { $this->_packageInfo['changelog']['release'][] = $contents; } } /** * Remove the changelog entirely */ function clearChangeLog() { unset($this->_packageInfo['changelog']); } }PKu],#y++PEAR/REST/11.phpnu[ * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.3 */ /** * For downloading REST xml/txt files */ require_once 'PEAR/REST.php'; /** * Implement REST 1.1 * * @category pear * @package PEAR * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.3 */ class PEAR_REST_11 { /** * @var PEAR_REST */ var $_rest; function __construct($config, $options = array()) { $this->_rest = new PEAR_REST($config, $options); } function listAll($base, $dostable, $basic = true, $searchpackage = false, $searchsummary = false, $channel = false) { $categorylist = $this->_rest->retrieveData($base . 'c/categories.xml', false, false, $channel); if (PEAR::isError($categorylist)) { return $categorylist; } $ret = array(); if (!is_array($categorylist['c']) || !isset($categorylist['c'][0])) { $categorylist['c'] = array($categorylist['c']); } PEAR::pushErrorHandling(PEAR_ERROR_RETURN); foreach ($categorylist['c'] as $progress => $category) { $category = $category['_content']; $packagesinfo = $this->_rest->retrieveData($base . 'c/' . urlencode($category) . '/packagesinfo.xml', false, false, $channel); if (PEAR::isError($packagesinfo)) { continue; } if (!is_array($packagesinfo) || !isset($packagesinfo['pi'])) { continue; } if (!is_array($packagesinfo['pi']) || !isset($packagesinfo['pi'][0])) { $packagesinfo['pi'] = array($packagesinfo['pi']); } foreach ($packagesinfo['pi'] as $packageinfo) { if (empty($packageinfo)) { continue; } $info = $packageinfo['p']; $package = $info['n']; $releases = isset($packageinfo['a']) ? $packageinfo['a'] : false; unset($latest); unset($unstable); unset($stable); unset($state); if ($releases) { if (!isset($releases['r'][0])) { $releases['r'] = array($releases['r']); } foreach ($releases['r'] as $release) { if (!isset($latest)) { if ($dostable && $release['s'] == 'stable') { $latest = $release['v']; $state = 'stable'; } if (!$dostable) { $latest = $release['v']; $state = $release['s']; } } if (!isset($stable) && $release['s'] == 'stable') { $stable = $release['v']; if (!isset($unstable)) { $unstable = $stable; } } if (!isset($unstable) && $release['s'] != 'stable') { $unstable = $release['v']; $state = $release['s']; } if (isset($latest) && !isset($state)) { $state = $release['s']; } if (isset($latest) && isset($stable) && isset($unstable)) { break; } } } if ($basic) { // remote-list command if (!isset($latest)) { $latest = false; } if ($dostable) { // $state is not set if there are no releases if (isset($state) && $state == 'stable') { $ret[$package] = array('stable' => $latest); } else { $ret[$package] = array('stable' => '-n/a-'); } } else { $ret[$package] = array('stable' => $latest); } continue; } // list-all command if (!isset($unstable)) { $unstable = false; $state = 'stable'; if (isset($stable)) { $latest = $unstable = $stable; } } else { $latest = $unstable; } if (!isset($latest)) { $latest = false; } $deps = array(); if ($latest && isset($packageinfo['deps'])) { if (!is_array($packageinfo['deps']) || !isset($packageinfo['deps'][0]) ) { $packageinfo['deps'] = array($packageinfo['deps']); } $d = false; foreach ($packageinfo['deps'] as $dep) { if ($dep['v'] == $latest) { $d = unserialize($dep['d']); } } if ($d) { if (isset($d['required'])) { if (!class_exists('PEAR_PackageFile_v2')) { require_once 'PEAR/PackageFile/v2.php'; } if (!isset($pf)) { $pf = new PEAR_PackageFile_v2; } $pf->setDeps($d); $tdeps = $pf->getDeps(); } else { $tdeps = $d; } foreach ($tdeps as $dep) { if ($dep['type'] !== 'pkg') { continue; } $deps[] = $dep; } } } $info = array( 'stable' => $latest, 'summary' => $info['s'], 'description' => $info['d'], 'deps' => $deps, 'category' => $info['ca']['_content'], 'unstable' => $unstable, 'state' => $state ); $ret[$package] = $info; } } PEAR::popErrorHandling(); return $ret; } /** * List all categories of a REST server * * @param string $base base URL of the server * @return array of categorynames */ function listCategories($base, $channel = false) { $categorylist = $this->_rest->retrieveData($base . 'c/categories.xml', false, false, $channel); if (PEAR::isError($categorylist)) { return $categorylist; } if (!is_array($categorylist) || !isset($categorylist['c'])) { return array(); } if (isset($categorylist['c']['_content'])) { // only 1 category $categorylist['c'] = array($categorylist['c']); } return $categorylist['c']; } /** * List packages in a category of a REST server * * @param string $base base URL of the server * @param string $category name of the category * @param boolean $info also download full package info * @return array of packagenames */ function listCategory($base, $category, $info = false, $channel = false) { if ($info == false) { $url = '%s'.'c/%s/packages.xml'; } else { $url = '%s'.'c/%s/packagesinfo.xml'; } $url = sprintf($url, $base, urlencode($category)); // gives '404 Not Found' error when category doesn't exist $packagelist = $this->_rest->retrieveData($url, false, false, $channel); if (PEAR::isError($packagelist)) { return $packagelist; } if (!is_array($packagelist)) { return array(); } if ($info == false) { if (!isset($packagelist['p'])) { return array(); } if (!is_array($packagelist['p']) || !isset($packagelist['p'][0])) { // only 1 pkg $packagelist = array($packagelist['p']); } else { $packagelist = $packagelist['p']; } return $packagelist; } // info == true if (!isset($packagelist['pi'])) { return array(); } if (!is_array($packagelist['pi']) || !isset($packagelist['pi'][0])) { // only 1 pkg $packagelist_pre = array($packagelist['pi']); } else { $packagelist_pre = $packagelist['pi']; } $packagelist = array(); foreach ($packagelist_pre as $i => $item) { // compatibility with r/.xml if (isset($item['a']['r'][0])) { // multiple releases $item['p']['v'] = $item['a']['r'][0]['v']; $item['p']['st'] = $item['a']['r'][0]['s']; } elseif (isset($item['a'])) { // first and only release $item['p']['v'] = $item['a']['r']['v']; $item['p']['st'] = $item['a']['r']['s']; } $packagelist[$i] = array('attribs' => $item['p']['r'], '_content' => $item['p']['n'], 'info' => $item['p']); } return $packagelist; } /** * Return an array containing all of the states that are more stable than * or equal to the passed in state * * @param string Release state * @param boolean Determines whether to include $state in the list * @return false|array False if $state is not a valid release state */ function betterStates($state, $include = false) { static $states = array('snapshot', 'devel', 'alpha', 'beta', 'stable'); $i = array_search($state, $states); if ($i === false) { return false; } if ($include) { $i--; } return array_slice($states, $i + 1); } } ?> PKu]Y;;PEAR/REST/13.phpnu[ * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a12 */ /** * For downloading REST xml/txt files */ require_once 'PEAR/REST.php'; require_once 'PEAR/REST/10.php'; /** * Implement REST 1.3 * * @category pear * @package PEAR * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a12 */ class PEAR_REST_13 extends PEAR_REST_10 { /** * Retrieve information about a remote package to be downloaded from a REST server * * This is smart enough to resolve the minimum PHP version dependency prior to download * @param string $base The uri to prepend to all REST calls * @param array $packageinfo an array of format: *
     *  array(
     *   'package' => 'packagename',
     *   'channel' => 'channelname',
     *  ['state' => 'alpha' (or valid state),]
     *  -or-
     *  ['version' => '1.whatever']
     * 
* @param string $prefstate Current preferred_state config variable value * @param bool $installed the installed version of this package to compare against * @return array|false|PEAR_Error see {@link _returnDownloadURL()} */ function getDownloadURL($base, $packageinfo, $prefstate, $installed, $channel = false) { $states = $this->betterStates($prefstate, true); if (!$states) { return PEAR::raiseError('"' . $prefstate . '" is not a valid state'); } $channel = $packageinfo['channel']; $package = $packageinfo['package']; $state = isset($packageinfo['state']) ? $packageinfo['state'] : null; $version = isset($packageinfo['version']) ? $packageinfo['version'] : null; $restFile = $base . 'r/' . strtolower($package) . '/allreleases2.xml'; $info = $this->_rest->retrieveData($restFile, false, false, $channel); if (PEAR::isError($info)) { return PEAR::raiseError('No releases available for package "' . $channel . '/' . $package . '"'); } if (!isset($info['r'])) { return false; } $release = $found = false; if (!is_array($info['r']) || !isset($info['r'][0])) { $info['r'] = array($info['r']); } $skippedphp = false; foreach ($info['r'] as $release) { if (!isset($this->_rest->_options['force']) && ($installed && version_compare($release['v'], $installed, '<'))) { continue; } if (isset($state)) { // try our preferred state first if ($release['s'] == $state) { if (!isset($version) && version_compare($release['m'], phpversion(), '>')) { // skip releases that require a PHP version newer than our PHP version $skippedphp = $release; continue; } $found = true; break; } // see if there is something newer and more stable // bug #7221 if (in_array($release['s'], $this->betterStates($state), true)) { if (!isset($version) && version_compare($release['m'], phpversion(), '>')) { // skip releases that require a PHP version newer than our PHP version $skippedphp = $release; continue; } $found = true; break; } } elseif (isset($version)) { if ($release['v'] == $version) { if (!isset($this->_rest->_options['force']) && !isset($version) && version_compare($release['m'], phpversion(), '>')) { // skip releases that require a PHP version newer than our PHP version $skippedphp = $release; continue; } $found = true; break; } } else { if (in_array($release['s'], $states)) { if (version_compare($release['m'], phpversion(), '>')) { // skip releases that require a PHP version newer than our PHP version $skippedphp = $release; continue; } $found = true; break; } } } if (!$found && $skippedphp) { $found = null; } return $this->_returnDownloadURL($base, $package, $release, $info, $found, $skippedphp, $channel); } function getDepDownloadURL($base, $xsdversion, $dependency, $deppackage, $prefstate = 'stable', $installed = false, $channel = false) { $states = $this->betterStates($prefstate, true); if (!$states) { return PEAR::raiseError('"' . $prefstate . '" is not a valid state'); } $channel = $dependency['channel']; $package = $dependency['name']; $state = isset($dependency['state']) ? $dependency['state'] : null; $version = isset($dependency['version']) ? $dependency['version'] : null; $restFile = $base . 'r/' . strtolower($package) .'/allreleases2.xml'; $info = $this->_rest->retrieveData($restFile, false, false, $channel); if (PEAR::isError($info)) { return PEAR::raiseError('Package "' . $deppackage['channel'] . '/' . $deppackage['package'] . '" dependency "' . $channel . '/' . $package . '" has no releases'); } if (!is_array($info) || !isset($info['r'])) { return false; } $exclude = array(); $min = $max = $recommended = false; if ($xsdversion == '1.0') { $pinfo['package'] = $dependency['name']; $pinfo['channel'] = 'pear.php.net'; // this is always true - don't change this switch ($dependency['rel']) { case 'ge' : $min = $dependency['version']; break; case 'gt' : $min = $dependency['version']; $exclude = array($dependency['version']); break; case 'eq' : $recommended = $dependency['version']; break; case 'lt' : $max = $dependency['version']; $exclude = array($dependency['version']); break; case 'le' : $max = $dependency['version']; break; case 'ne' : $exclude = array($dependency['version']); break; } } else { $pinfo['package'] = $dependency['name']; $min = isset($dependency['min']) ? $dependency['min'] : false; $max = isset($dependency['max']) ? $dependency['max'] : false; $recommended = isset($dependency['recommended']) ? $dependency['recommended'] : false; if (isset($dependency['exclude'])) { if (!isset($dependency['exclude'][0])) { $exclude = array($dependency['exclude']); } } } $skippedphp = $found = $release = false; if (!is_array($info['r']) || !isset($info['r'][0])) { $info['r'] = array($info['r']); } foreach ($info['r'] as $release) { if (!isset($this->_rest->_options['force']) && ($installed && version_compare($release['v'], $installed, '<'))) { continue; } if (in_array($release['v'], $exclude)) { // skip excluded versions continue; } // allow newer releases to say "I'm OK with the dependent package" if ($xsdversion == '2.0' && isset($release['co'])) { if (!is_array($release['co']) || !isset($release['co'][0])) { $release['co'] = array($release['co']); } foreach ($release['co'] as $entry) { if (isset($entry['x']) && !is_array($entry['x'])) { $entry['x'] = array($entry['x']); } elseif (!isset($entry['x'])) { $entry['x'] = array(); } if ($entry['c'] == $deppackage['channel'] && strtolower($entry['p']) == strtolower($deppackage['package']) && version_compare($deppackage['version'], $entry['min'], '>=') && version_compare($deppackage['version'], $entry['max'], '<=') && !in_array($release['v'], $entry['x'])) { if (version_compare($release['m'], phpversion(), '>')) { // skip dependency releases that require a PHP version // newer than our PHP version $skippedphp = $release; continue; } $recommended = $release['v']; break; } } } if ($recommended) { if ($release['v'] != $recommended) { // if we want a specific // version, then skip all others continue; } if (!in_array($release['s'], $states)) { // the stability is too low, but we must return the // recommended version if possible return $this->_returnDownloadURL($base, $package, $release, $info, true, false, $channel); } } if ($min && version_compare($release['v'], $min, 'lt')) { // skip too old versions continue; } if ($max && version_compare($release['v'], $max, 'gt')) { // skip too new versions continue; } if ($installed && version_compare($release['v'], $installed, '<')) { continue; } if (in_array($release['s'], $states)) { // if in the preferred state... if (version_compare($release['m'], phpversion(), '>')) { // skip dependency releases that require a PHP version // newer than our PHP version $skippedphp = $release; continue; } $found = true; // ... then use it break; } } if (!$found && $skippedphp) { $found = null; } return $this->_returnDownloadURL($base, $package, $release, $info, $found, $skippedphp, $channel); } /** * List package upgrades but take the PHP version into account. */ function listLatestUpgrades($base, $pref_state, $installed, $channel, &$reg) { $packagelist = $this->_rest->retrieveData($base . 'p/packages.xml', false, false, $channel); if (PEAR::isError($packagelist)) { return $packagelist; } $ret = array(); if (!is_array($packagelist) || !isset($packagelist['p'])) { return $ret; } if (!is_array($packagelist['p'])) { $packagelist['p'] = array($packagelist['p']); } foreach ($packagelist['p'] as $package) { if (!isset($installed[strtolower($package)])) { continue; } $inst_version = $reg->packageInfo($package, 'version', $channel); $inst_state = $reg->packageInfo($package, 'release_state', $channel); PEAR::pushErrorHandling(PEAR_ERROR_RETURN); $info = $this->_rest->retrieveData($base . 'r/' . strtolower($package) . '/allreleases2.xml', false, false, $channel); PEAR::popErrorHandling(); if (PEAR::isError($info)) { continue; // no remote releases } if (!isset($info['r'])) { continue; } $release = $found = false; if (!is_array($info['r']) || !isset($info['r'][0])) { $info['r'] = array($info['r']); } // $info['r'] is sorted by version number usort($info['r'], array($this, '_sortReleasesByVersionNumber')); foreach ($info['r'] as $release) { if ($inst_version && version_compare($release['v'], $inst_version, '<=')) { // not newer than the one installed break; } if (version_compare($release['m'], phpversion(), '>')) { // skip dependency releases that require a PHP version // newer than our PHP version continue; } // new version > installed version if (!$pref_state) { // every state is a good state $found = true; break; } else { $new_state = $release['s']; // if new state >= installed state: go if (in_array($new_state, $this->betterStates($inst_state, true))) { $found = true; break; } else { // only allow to lower the state of package, // if new state >= preferred state: go if (in_array($new_state, $this->betterStates($pref_state, true))) { $found = true; break; } } } } if (!$found) { continue; } $relinfo = $this->_rest->retrieveCacheFirst($base . 'r/' . strtolower($package) . '/' . $release['v'] . '.xml', false, false, $channel); if (PEAR::isError($relinfo)) { return $relinfo; } $ret[$package] = array( 'version' => $release['v'], 'state' => $release['s'], 'filesize' => $relinfo['f'], ); } return $ret; } }PKu]WfPEAR/REST/10.phpnu[ * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a12 */ /** * For downloading REST xml/txt files */ require_once 'PEAR/REST.php'; /** * Implement REST 1.0 * * @category pear * @package PEAR * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a12 */ class PEAR_REST_10 { /** * @var PEAR_REST */ var $_rest; function __construct($config, $options = array()) { $this->_rest = new PEAR_REST($config, $options); } /** * Retrieve information about a remote package to be downloaded from a REST server * * @param string $base The uri to prepend to all REST calls * @param array $packageinfo an array of format: *
     *  array(
     *   'package' => 'packagename',
     *   'channel' => 'channelname',
     *  ['state' => 'alpha' (or valid state),]
     *  -or-
     *  ['version' => '1.whatever']
     * 
* @param string $prefstate Current preferred_state config variable value * @param bool $installed the installed version of this package to compare against * @return array|false|PEAR_Error see {@link _returnDownloadURL()} */ function getDownloadURL($base, $packageinfo, $prefstate, $installed, $channel = false) { $states = $this->betterStates($prefstate, true); if (!$states) { return PEAR::raiseError('"' . $prefstate . '" is not a valid state'); } $channel = $packageinfo['channel']; $package = $packageinfo['package']; $state = isset($packageinfo['state']) ? $packageinfo['state'] : null; $version = isset($packageinfo['version']) ? $packageinfo['version'] : null; $restFile = $base . 'r/' . strtolower($package) . '/allreleases.xml'; $info = $this->_rest->retrieveData($restFile, false, false, $channel); if (PEAR::isError($info)) { return PEAR::raiseError('No releases available for package "' . $channel . '/' . $package . '"'); } if (!isset($info['r'])) { return false; } $release = $found = false; if (!is_array($info['r']) || !isset($info['r'][0])) { $info['r'] = array($info['r']); } foreach ($info['r'] as $release) { if (!isset($this->_rest->_options['force']) && ($installed && version_compare($release['v'], $installed, '<'))) { continue; } if (isset($state)) { // try our preferred state first if ($release['s'] == $state) { $found = true; break; } // see if there is something newer and more stable // bug #7221 if (in_array($release['s'], $this->betterStates($state), true)) { $found = true; break; } } elseif (isset($version)) { if ($release['v'] == $version) { $found = true; break; } } else { if (in_array($release['s'], $states)) { $found = true; break; } } } return $this->_returnDownloadURL($base, $package, $release, $info, $found, false, $channel); } function getDepDownloadURL($base, $xsdversion, $dependency, $deppackage, $prefstate = 'stable', $installed = false, $channel = false) { $states = $this->betterStates($prefstate, true); if (!$states) { return PEAR::raiseError('"' . $prefstate . '" is not a valid state'); } $channel = $dependency['channel']; $package = $dependency['name']; $state = isset($dependency['state']) ? $dependency['state'] : null; $version = isset($dependency['version']) ? $dependency['version'] : null; $restFile = $base . 'r/' . strtolower($package) . '/allreleases.xml'; $info = $this->_rest->retrieveData($restFile, false, false, $channel); if (PEAR::isError($info)) { return PEAR::raiseError('Package "' . $deppackage['channel'] . '/' . $deppackage['package'] . '" dependency "' . $channel . '/' . $package . '" has no releases'); } if (!is_array($info) || !isset($info['r'])) { return false; } $exclude = array(); $min = $max = $recommended = false; if ($xsdversion == '1.0') { switch ($dependency['rel']) { case 'ge' : $min = $dependency['version']; break; case 'gt' : $min = $dependency['version']; $exclude = array($dependency['version']); break; case 'eq' : $recommended = $dependency['version']; break; case 'lt' : $max = $dependency['version']; $exclude = array($dependency['version']); break; case 'le' : $max = $dependency['version']; break; case 'ne' : $exclude = array($dependency['version']); break; } } else { $min = isset($dependency['min']) ? $dependency['min'] : false; $max = isset($dependency['max']) ? $dependency['max'] : false; $recommended = isset($dependency['recommended']) ? $dependency['recommended'] : false; if (isset($dependency['exclude'])) { if (!isset($dependency['exclude'][0])) { $exclude = array($dependency['exclude']); } } } $release = $found = false; if (!is_array($info['r']) || !isset($info['r'][0])) { $info['r'] = array($info['r']); } foreach ($info['r'] as $release) { if (!isset($this->_rest->_options['force']) && ($installed && version_compare($release['v'], $installed, '<'))) { continue; } if (in_array($release['v'], $exclude)) { // skip excluded versions continue; } // allow newer releases to say "I'm OK with the dependent package" if ($xsdversion == '2.0' && isset($release['co'])) { if (!is_array($release['co']) || !isset($release['co'][0])) { $release['co'] = array($release['co']); } foreach ($release['co'] as $entry) { if (isset($entry['x']) && !is_array($entry['x'])) { $entry['x'] = array($entry['x']); } elseif (!isset($entry['x'])) { $entry['x'] = array(); } if ($entry['c'] == $deppackage['channel'] && strtolower($entry['p']) == strtolower($deppackage['package']) && version_compare($deppackage['version'], $entry['min'], '>=') && version_compare($deppackage['version'], $entry['max'], '<=') && !in_array($release['v'], $entry['x'])) { $recommended = $release['v']; break; } } } if ($recommended) { if ($release['v'] != $recommended) { // if we want a specific // version, then skip all others continue; } else { if (!in_array($release['s'], $states)) { // the stability is too low, but we must return the // recommended version if possible return $this->_returnDownloadURL($base, $package, $release, $info, true, false, $channel); } } } if ($min && version_compare($release['v'], $min, 'lt')) { // skip too old versions continue; } if ($max && version_compare($release['v'], $max, 'gt')) { // skip too new versions continue; } if ($installed && version_compare($release['v'], $installed, '<')) { continue; } if (in_array($release['s'], $states)) { // if in the preferred state... $found = true; // ... then use it break; } } return $this->_returnDownloadURL($base, $package, $release, $info, $found, false, $channel); } /** * Take raw data and return the array needed for processing a download URL * * @param string $base REST base uri * @param string $package Package name * @param array $release an array of format array('v' => version, 's' => state) * describing the release to download * @param array $info list of all releases as defined by allreleases.xml * @param bool|null $found determines whether the release was found or this is the next * best alternative. If null, then versions were skipped because * of PHP dependency * @return array|PEAR_Error * @access private */ function _returnDownloadURL($base, $package, $release, $info, $found, $phpversion = false, $channel = false) { if (!$found) { $release = $info['r'][0]; } $packageLower = strtolower($package); $pinfo = $this->_rest->retrieveCacheFirst($base . 'p/' . $packageLower . '/' . 'info.xml', false, false, $channel); if (PEAR::isError($pinfo)) { return PEAR::raiseError('Package "' . $package . '" does not have REST info xml available'); } $releaseinfo = $this->_rest->retrieveCacheFirst($base . 'r/' . $packageLower . '/' . $release['v'] . '.xml', false, false, $channel); if (PEAR::isError($releaseinfo)) { return PEAR::raiseError('Package "' . $package . '" Version "' . $release['v'] . '" does not have REST xml available'); } $packagexml = $this->_rest->retrieveCacheFirst($base . 'r/' . $packageLower . '/' . 'deps.' . $release['v'] . '.txt', false, true, $channel); if (PEAR::isError($packagexml)) { return PEAR::raiseError('Package "' . $package . '" Version "' . $release['v'] . '" does not have REST dependency information available'); } $packagexml = unserialize($packagexml); if (!$packagexml) { $packagexml = array(); } $allinfo = $this->_rest->retrieveData($base . 'r/' . $packageLower . '/allreleases.xml', false, false, $channel); if (PEAR::isError($allinfo)) { return $allinfo; } if (!is_array($allinfo['r']) || !isset($allinfo['r'][0])) { $allinfo['r'] = array($allinfo['r']); } $compatible = false; foreach ($allinfo['r'] as $release) { if ($release['v'] != $releaseinfo['v']) { continue; } if (!isset($release['co'])) { break; } $compatible = array(); if (!is_array($release['co']) || !isset($release['co'][0])) { $release['co'] = array($release['co']); } foreach ($release['co'] as $entry) { $comp = array(); $comp['name'] = $entry['p']; $comp['channel'] = $entry['c']; $comp['min'] = $entry['min']; $comp['max'] = $entry['max']; if (isset($entry['x']) && !is_array($entry['x'])) { $comp['exclude'] = $entry['x']; } $compatible[] = $comp; } if (count($compatible) == 1) { $compatible = $compatible[0]; } break; } $deprecated = false; if (isset($pinfo['dc']) && isset($pinfo['dp'])) { if (is_array($pinfo['dp'])) { $deprecated = array('channel' => (string) $pinfo['dc'], 'package' => trim($pinfo['dp']['_content'])); } else { $deprecated = array('channel' => (string) $pinfo['dc'], 'package' => trim($pinfo['dp'])); } } $return = array( 'version' => $releaseinfo['v'], 'info' => $packagexml, 'package' => $releaseinfo['p']['_content'], 'stability' => $releaseinfo['st'], 'compatible' => $compatible, 'deprecated' => $deprecated, ); if ($found) { $return['url'] = $releaseinfo['g']; return $return; } $return['php'] = $phpversion; return $return; } function listPackages($base, $channel = false) { $packagelist = $this->_rest->retrieveData($base . 'p/packages.xml', false, false, $channel); if (PEAR::isError($packagelist)) { return $packagelist; } if (!is_array($packagelist) || !isset($packagelist['p'])) { return array(); } if (!is_array($packagelist['p'])) { $packagelist['p'] = array($packagelist['p']); } return $packagelist['p']; } /** * List all categories of a REST server * * @param string $base base URL of the server * @return array of categorynames */ function listCategories($base, $channel = false) { $categories = array(); // c/categories.xml does not exist; // check for every package its category manually // This is SLOOOWWWW : /// $packagelist = $this->_rest->retrieveData($base . 'p/packages.xml', false, false, $channel); if (PEAR::isError($packagelist)) { return $packagelist; } if (!is_array($packagelist) || !isset($packagelist['p'])) { $ret = array(); return $ret; } if (!is_array($packagelist['p'])) { $packagelist['p'] = array($packagelist['p']); } PEAR::pushErrorHandling(PEAR_ERROR_RETURN); foreach ($packagelist['p'] as $package) { $inf = $this->_rest->retrieveData($base . 'p/' . strtolower($package) . '/info.xml', false, false, $channel); if (PEAR::isError($inf)) { PEAR::popErrorHandling(); return $inf; } $cat = $inf['ca']['_content']; if (!isset($categories[$cat])) { $categories[$cat] = $inf['ca']; } } return array_values($categories); } /** * List a category of a REST server * * @param string $base base URL of the server * @param string $category name of the category * @param boolean $info also download full package info * @return array of packagenames */ function listCategory($base, $category, $info = false, $channel = false) { // gives '404 Not Found' error when category doesn't exist $packagelist = $this->_rest->retrieveData($base.'c/'.urlencode($category).'/packages.xml', false, false, $channel); if (PEAR::isError($packagelist)) { return $packagelist; } if (!is_array($packagelist) || !isset($packagelist['p'])) { return array(); } if (!is_array($packagelist['p']) || !isset($packagelist['p'][0])) { // only 1 pkg $packagelist = array($packagelist['p']); } else { $packagelist = $packagelist['p']; } if ($info == true) { // get individual package info PEAR::pushErrorHandling(PEAR_ERROR_RETURN); foreach ($packagelist as $i => $packageitem) { $url = sprintf('%s'.'r/%s/latest.txt', $base, strtolower($packageitem['_content'])); $version = $this->_rest->retrieveData($url, false, false, $channel); if (PEAR::isError($version)) { break; // skipit } $url = sprintf('%s'.'r/%s/%s.xml', $base, strtolower($packageitem['_content']), $version); $info = $this->_rest->retrieveData($url, false, false, $channel); if (PEAR::isError($info)) { break; // skipit } $packagelist[$i]['info'] = $info; } PEAR::popErrorHandling(); } return $packagelist; } function listAll($base, $dostable, $basic = true, $searchpackage = false, $searchsummary = false, $channel = false) { $packagelist = $this->_rest->retrieveData($base . 'p/packages.xml', false, false, $channel); if (PEAR::isError($packagelist)) { return $packagelist; } if ($this->_rest->config->get('verbose') > 0) { $ui = &PEAR_Frontend::singleton(); $ui->log('Retrieving data...0%', true); } $ret = array(); if (!is_array($packagelist) || !isset($packagelist['p'])) { return $ret; } if (!is_array($packagelist['p'])) { $packagelist['p'] = array($packagelist['p']); } // only search-packagename = quicksearch ! if ($searchpackage && (!$searchsummary || empty($searchpackage))) { $newpackagelist = array(); foreach ($packagelist['p'] as $package) { if (!empty($searchpackage) && stristr($package, $searchpackage) !== false) { $newpackagelist[] = $package; } } $packagelist['p'] = $newpackagelist; } PEAR::pushErrorHandling(PEAR_ERROR_RETURN); $next = .1; foreach ($packagelist['p'] as $progress => $package) { if ($this->_rest->config->get('verbose') > 0) { if ($progress / count($packagelist['p']) >= $next) { if ($next == .5) { $ui->log('50%', false); } else { $ui->log('.', false); } $next += .1; } } if ($basic) { // remote-list command if ($dostable) { $latest = $this->_rest->retrieveData($base . 'r/' . strtolower($package) . '/stable.txt', false, false, $channel); } else { $latest = $this->_rest->retrieveData($base . 'r/' . strtolower($package) . '/latest.txt', false, false, $channel); } if (PEAR::isError($latest)) { $latest = false; } $info = array('stable' => $latest); } else { // list-all command $inf = $this->_rest->retrieveData($base . 'p/' . strtolower($package) . '/info.xml', false, false, $channel); if (PEAR::isError($inf)) { PEAR::popErrorHandling(); return $inf; } if ($searchpackage) { $found = (!empty($searchpackage) && stristr($package, $searchpackage) !== false); if (!$found && !(isset($searchsummary) && !empty($searchsummary) && (stristr($inf['s'], $searchsummary) !== false || stristr($inf['d'], $searchsummary) !== false))) { continue; }; } $releases = $this->_rest->retrieveData($base . 'r/' . strtolower($package) . '/allreleases.xml', false, false, $channel); if (PEAR::isError($releases)) { continue; } if (!isset($releases['r'][0])) { $releases['r'] = array($releases['r']); } unset($latest); unset($unstable); unset($stable); unset($state); foreach ($releases['r'] as $release) { if (!isset($latest)) { if ($dostable && $release['s'] == 'stable') { $latest = $release['v']; $state = 'stable'; } if (!$dostable) { $latest = $release['v']; $state = $release['s']; } } if (!isset($stable) && $release['s'] == 'stable') { $stable = $release['v']; if (!isset($unstable)) { $unstable = $stable; } } if (!isset($unstable) && $release['s'] != 'stable') { $latest = $unstable = $release['v']; $state = $release['s']; } if (isset($latest) && !isset($state)) { $state = $release['s']; } if (isset($latest) && isset($stable) && isset($unstable)) { break; } } $deps = array(); if (!isset($unstable)) { $unstable = false; $state = 'stable'; if (isset($stable)) { $latest = $unstable = $stable; } } else { $latest = $unstable; } if (!isset($latest)) { $latest = false; } if ($latest) { $d = $this->_rest->retrieveCacheFirst($base . 'r/' . strtolower($package) . '/deps.' . $latest . '.txt', false, false, $channel); if (!PEAR::isError($d)) { $d = unserialize($d); if ($d) { if (isset($d['required'])) { if (!class_exists('PEAR_PackageFile_v2')) { require_once 'PEAR/PackageFile/v2.php'; } if (!isset($pf)) { $pf = new PEAR_PackageFile_v2; } $pf->setDeps($d); $tdeps = $pf->getDeps(); } else { $tdeps = $d; } foreach ($tdeps as $dep) { if ($dep['type'] !== 'pkg') { continue; } $deps[] = $dep; } } } } if (!isset($stable)) { $stable = '-n/a-'; } if (!$searchpackage) { $info = array('stable' => $latest, 'summary' => $inf['s'], 'description' => $inf['d'], 'deps' => $deps, 'category' => $inf['ca']['_content'], 'unstable' => $unstable, 'state' => $state); } else { $info = array('stable' => $stable, 'summary' => $inf['s'], 'description' => $inf['d'], 'deps' => $deps, 'category' => $inf['ca']['_content'], 'unstable' => $unstable, 'state' => $state); } } $ret[$package] = $info; } PEAR::popErrorHandling(); return $ret; } function listLatestUpgrades($base, $pref_state, $installed, $channel, &$reg) { $packagelist = $this->_rest->retrieveData($base . 'p/packages.xml', false, false, $channel); if (PEAR::isError($packagelist)) { return $packagelist; } $ret = array(); if (!is_array($packagelist) || !isset($packagelist['p'])) { return $ret; } if (!is_array($packagelist['p'])) { $packagelist['p'] = array($packagelist['p']); } foreach ($packagelist['p'] as $package) { if (!isset($installed[strtolower($package)])) { continue; } $inst_version = $reg->packageInfo($package, 'version', $channel); $inst_state = $reg->packageInfo($package, 'release_state', $channel); PEAR::pushErrorHandling(PEAR_ERROR_RETURN); $info = $this->_rest->retrieveData($base . 'r/' . strtolower($package) . '/allreleases.xml', false, false, $channel); PEAR::popErrorHandling(); if (PEAR::isError($info)) { continue; // no remote releases } if (!isset($info['r'])) { continue; } $release = $found = false; if (!is_array($info['r']) || !isset($info['r'][0])) { $info['r'] = array($info['r']); } // $info['r'] is sorted by version number usort($info['r'], array($this, '_sortReleasesByVersionNumber')); foreach ($info['r'] as $release) { if ($inst_version && version_compare($release['v'], $inst_version, '<=')) { // not newer than the one installed break; } // new version > installed version if (!$pref_state) { // every state is a good state $found = true; break; } else { $new_state = $release['s']; // if new state >= installed state: go if (in_array($new_state, $this->betterStates($inst_state, true))) { $found = true; break; } else { // only allow to lower the state of package, // if new state >= preferred state: go if (in_array($new_state, $this->betterStates($pref_state, true))) { $found = true; break; } } } } if (!$found) { continue; } $relinfo = $this->_rest->retrieveCacheFirst($base . 'r/' . strtolower($package) . '/' . $release['v'] . '.xml', false, false, $channel); if (PEAR::isError($relinfo)) { return $relinfo; } $ret[$package] = array( 'version' => $release['v'], 'state' => $release['s'], 'filesize' => $relinfo['f'], ); } return $ret; } function packageInfo($base, $package, $channel = false) { PEAR::pushErrorHandling(PEAR_ERROR_RETURN); $pinfo = $this->_rest->retrieveData($base . 'p/' . strtolower($package) . '/info.xml', false, false, $channel); if (PEAR::isError($pinfo)) { PEAR::popErrorHandling(); return PEAR::raiseError('Unknown package: "' . $package . '" in channel "' . $channel . '"' . "\n". 'Debug: ' . $pinfo->getMessage()); } $releases = array(); $allreleases = $this->_rest->retrieveData($base . 'r/' . strtolower($package) . '/allreleases.xml', false, false, $channel); if (!PEAR::isError($allreleases)) { if (!class_exists('PEAR_PackageFile_v2')) { require_once 'PEAR/PackageFile/v2.php'; } if (!is_array($allreleases['r']) || !isset($allreleases['r'][0])) { $allreleases['r'] = array($allreleases['r']); } $pf = new PEAR_PackageFile_v2; foreach ($allreleases['r'] as $release) { $ds = $this->_rest->retrieveCacheFirst($base . 'r/' . strtolower($package) . '/deps.' . $release['v'] . '.txt', false, false, $channel); if (PEAR::isError($ds)) { continue; } if (!isset($latest)) { $latest = $release['v']; } $pf->setDeps(unserialize($ds)); $ds = $pf->getDeps(); $info = $this->_rest->retrieveCacheFirst($base . 'r/' . strtolower($package) . '/' . $release['v'] . '.xml', false, false, $channel); if (PEAR::isError($info)) { continue; } $releases[$release['v']] = array( 'doneby' => $info['m'], 'license' => $info['l'], 'summary' => $info['s'], 'description' => $info['d'], 'releasedate' => $info['da'], 'releasenotes' => $info['n'], 'state' => $release['s'], 'deps' => $ds ? $ds : array(), ); } } else { $latest = ''; } PEAR::popErrorHandling(); if (isset($pinfo['dc']) && isset($pinfo['dp'])) { if (is_array($pinfo['dp'])) { $deprecated = array('channel' => (string) $pinfo['dc'], 'package' => trim($pinfo['dp']['_content'])); } else { $deprecated = array('channel' => (string) $pinfo['dc'], 'package' => trim($pinfo['dp'])); } } else { $deprecated = false; } if (!isset($latest)) { $latest = ''; } return array( 'name' => $pinfo['n'], 'channel' => $pinfo['c'], 'category' => $pinfo['ca']['_content'], 'stable' => $latest, 'license' => $pinfo['l'], 'summary' => $pinfo['s'], 'description' => $pinfo['d'], 'releases' => $releases, 'deprecated' => $deprecated, ); } /** * Return an array containing all of the states that are more stable than * or equal to the passed in state * * @param string Release state * @param boolean Determines whether to include $state in the list * @return false|array False if $state is not a valid release state */ function betterStates($state, $include = false) { static $states = array('snapshot', 'devel', 'alpha', 'beta', 'stable'); $i = array_search($state, $states); if ($i === false) { return false; } if ($include) { $i--; } return array_slice($states, $i + 1); } /** * Sort releases by version number * * @access private */ function _sortReleasesByVersionNumber($a, $b) { if (version_compare($a['v'], $b['v'], '=')) { return 0; } if (version_compare($a['v'], $b['v'], '>')) { return -1; } if (version_compare($a['v'], $b['v'], '<')) { return 1; } } } PKu]'PEAR/RunTest.phpnu[ * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 1.3.3 */ /** * for error handling */ require_once 'PEAR.php'; require_once 'PEAR/Config.php'; define('DETAILED', 1); putenv("PHP_PEAR_RUNTESTS=1"); /** * Simplified version of PHP's test suite * * Try it with: * * $ php -r 'include "../PEAR/RunTest.php"; $t=new PEAR_RunTest; $o=$t->run("./pear_system.phpt");print_r($o);' * * * @category pear * @package PEAR * @author Tomas V.V.Cox * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.3.3 */ class PEAR_RunTest { var $_headers = array(); var $_logger; var $_options; var $_php; var $tests_count; var $xdebug_loaded; /** * Saved value of php executable, used to reset $_php when we * have a test that uses cgi * * @var unknown_type */ var $_savephp; var $ini_overwrites = array( 'output_handler=', 'open_basedir=', 'disable_functions=', 'output_buffering=Off', 'display_errors=1', 'log_errors=0', 'html_errors=0', 'report_memleaks=0', 'report_zend_debug=0', 'docref_root=', 'docref_ext=.html', 'error_prepend_string=', 'error_append_string=', 'auto_prepend_file=', 'auto_append_file=', 'xdebug.default_enable=0', 'allow_url_fopen=1', ); /** * An object that supports the PEAR_Common->log() signature, or null * @param PEAR_Common|null */ function __construct($logger = null, $options = array()) { if (!defined('E_DEPRECATED')) { define('E_DEPRECATED', 0); } if (!defined('E_STRICT')) { define('E_STRICT', 0); } $excluded_error_reporting = E_DEPRECATED; if (!defined('PHP_VERSION_ID') || PHP_VERSION_ID < 80400) { $excluded_error_reporting |= E_STRICT; } $this->ini_overwrites[] = 'error_reporting=' . (E_ALL & ~$excluded_error_reporting); if (is_null($logger)) { require_once 'PEAR/Common.php'; $logger = new PEAR_Common; } $this->_logger = $logger; $this->_options = $options; $conf = &PEAR_Config::singleton(); $this->_php = $conf->get('php_bin'); } /** * Taken from php-src/run-tests.php * * @param string $commandline command name * @param array $env * @param string $stdin standard input to pass to the command * @return unknown */ function system_with_timeout($commandline, $env = null, $stdin = null) { $data = ''; $proc = proc_open($commandline, array( 0 => array('pipe', 'r'), 1 => array('pipe', 'w'), 2 => array('pipe', 'w') ), $pipes, null, $env, array('suppress_errors' => true)); if (!$proc) { return false; } if (is_string($stdin)) { fwrite($pipes[0], $stdin); } fclose($pipes[0]); while (true) { /* hide errors from interrupted syscalls */ $r = $pipes; unset($r[0]); $e = $w = []; $n = @stream_select($r, $w, $e, 60); if ($n === 0) { /* timed out */ $data .= "\n ** ERROR: process timed out **\n"; proc_terminate($proc); return array(1234567890, $data); } else if ($n > 0) { $line = fread($pipes[1], 8192); if (strlen($line) == 0) { /* EOF */ break; } $data .= $line; } } if (function_exists('proc_get_status')) { $stat = proc_get_status($proc); if ($stat['signaled']) { $data .= "\nTermsig=".$stat['stopsig']; } } $code = proc_close($proc); if (function_exists('proc_get_status')) { $code = $stat['exitcode']; } return array($code, $data); } /** * Turns a PHP INI string into an array * * Turns -d "include_path=/foo/bar" into this: * array( * 'include_path' => array( * 'operator' => '-d', * 'value' => '/foo/bar', * ) * ) * Works both with quotes and without * * @param string an PHP INI string, -d "include_path=/foo/bar" * @return array */ function iniString2array($ini_string) { if (!$ini_string) { return array(); } $split = preg_split('/[\s]|=/', $ini_string, -1, PREG_SPLIT_NO_EMPTY); $key = $split[1][0] == '"' ? substr($split[1], 1) : $split[1]; $value = $split[2][strlen($split[2]) - 1] == '"' ? substr($split[2], 0, -1) : $split[2]; // FIXME review if this is really the struct to go with $array = array($key => array('operator' => $split[0], 'value' => $value)); return $array; } function settings2array($settings, $ini_settings) { foreach ($settings as $setting) { if (strpos($setting, '=') !== false) { $setting = explode('=', $setting, 2); $name = trim(strtolower($setting[0])); $value = trim($setting[1]); $ini_settings[$name] = $value; } } return $ini_settings; } function settings2params($ini_settings) { $settings = ''; foreach ($ini_settings as $name => $value) { if (is_array($value)) { $operator = $value['operator']; $value = $value['value']; } else { $operator = '-d'; } $value = addslashes($value); $settings .= " $operator \"$name=$value\""; } return $settings; } function _preparePhpBin($php, $file, $ini_settings) { $file = escapeshellarg($file); $cmd = $php . $ini_settings . ' -f ' . $file; return $cmd; } function runPHPUnit($file, $ini_settings = '') { if (!file_exists($file) && file_exists(getcwd() . DIRECTORY_SEPARATOR . $file)) { $file = realpath(getcwd() . DIRECTORY_SEPARATOR . $file); } elseif (file_exists($file)) { $file = realpath($file); } $cmd = $this->_preparePhpBin($this->_php, $file, $ini_settings); if (isset($this->_logger)) { $this->_logger->log(2, 'Running command "' . $cmd . '"'); } $savedir = getcwd(); // in case the test moves us around chdir(dirname($file)); echo `$cmd`; chdir($savedir); return 'PASSED'; // we have no way of knowing this information so assume passing } /** * Runs an individual test case. * * @param string The filename of the test * @param array|string INI settings to be applied to the test run * @param integer Number what the current running test is of the * whole test suite being runned. * * @return string|object Returns PASSED, WARNED, FAILED depending on how the * test came out. * PEAR Error when the tester it self fails */ function run($file, $ini_settings = array(), $test_number = 1) { $this->_restorePHPBinary(); if (empty($this->_options['cgi'])) { // try to see if php-cgi is in the path $res = $this->system_with_timeout('php-cgi -v'); if (false !== $res && !(is_array($res) && in_array($res[0], array(-1, 127)))) { $this->_options['cgi'] = 'php-cgi'; } } if (1 < $len = strlen($this->tests_count)) { $test_number = str_pad($test_number, $len, ' ', STR_PAD_LEFT); $test_nr = "[$test_number/$this->tests_count] "; } else { $test_nr = ''; } $file = realpath($file); $section_text = $this->_readFile($file); if (PEAR::isError($section_text)) { return $section_text; } if (isset($section_text['POST_RAW']) && isset($section_text['UPLOAD'])) { return PEAR::raiseError("Cannot contain both POST_RAW and UPLOAD in test file: $file"); } $cwd = getcwd(); $pass_options = ''; if (!empty($this->_options['ini'])) { $pass_options = $this->_options['ini']; } if (is_string($ini_settings)) { $ini_settings = $this->iniString2array($ini_settings); } $ini_settings = $this->settings2array($this->ini_overwrites, $ini_settings); if ($section_text['INI']) { if (strpos($section_text['INI'], '{PWD}') !== false) { $section_text['INI'] = str_replace('{PWD}', dirname($file), $section_text['INI']); } $ini = preg_split( "/[\n\r]+/", $section_text['INI']); $ini_settings = $this->settings2array($ini, $ini_settings); } $ini_settings = $this->settings2params($ini_settings); $shortname = str_replace($cwd . DIRECTORY_SEPARATOR, '', $file); $tested = trim($section_text['TEST']); $tested.= !isset($this->_options['simple']) ? "[$shortname]" : ' '; if (!empty($section_text['POST']) || !empty($section_text['POST_RAW']) || !empty($section_text['UPLOAD']) || !empty($section_text['GET']) || !empty($section_text['COOKIE']) || !empty($section_text['EXPECTHEADERS'])) { if (empty($this->_options['cgi'])) { if (!isset($this->_options['quiet'])) { $this->_logger->log(0, "SKIP $test_nr$tested (reason: --cgi option needed for this test, type 'pear help run-tests')"); } if (isset($this->_options['tapoutput'])) { return array('ok', ' # skip --cgi option needed for this test, "pear help run-tests" for info'); } return 'SKIPPED'; } $this->_savePHPBinary(); $this->_php = $this->_options['cgi']; } $temp_dir = realpath(dirname($file)); $main_file_name = basename($file, 'phpt'); $diff_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'diff'; $log_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'log'; $exp_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'exp'; $output_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'out'; $memcheck_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'mem'; $temp_file = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'php'; $temp_skipif = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'skip.php'; $temp_clean = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'clean.php'; $tmp_post = $temp_dir . DIRECTORY_SEPARATOR . uniqid('phpt.'); // unlink old test results $this->_cleanupOldFiles($file); // Check if test should be skipped. $res = $this->_runSkipIf($section_text, $temp_skipif, $tested, $ini_settings); if ($res == 'SKIPPED' || count($res) != 2) { return $res; } $info = $res['info']; $warn = $res['warn']; // We've satisfied the preconditions - run the test! if (isset($this->_options['coverage']) && $this->xdebug_loaded) { $xdebug_file = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name . 'xdebug'; $text = "\n" . 'function coverage_shutdown() {' . "\n" . ' $xdebug = var_export(xdebug_get_code_coverage(), true);'; if (!function_exists('file_put_contents')) { $text .= "\n" . ' $fh = fopen(\'' . $xdebug_file . '\', "wb");' . "\n" . ' if ($fh !== false) {' . "\n" . ' fwrite($fh, $xdebug);' . "\n" . ' fclose($fh);' . "\n" . ' }'; } else { $text .= "\n" . ' file_put_contents(\'' . $xdebug_file . '\', $xdebug);'; } // Workaround for http://pear.php.net/bugs/bug.php?id=17292 $lines = explode("\n", $section_text['FILE']); $numLines = count($lines); $namespace = ''; $coverage_shutdown = 'coverage_shutdown'; if ( substr($lines[0], 0, 2) == 'save_text($temp_file, "save_text($temp_file, $section_text['FILE']); } $args = $section_text['ARGS'] ? ' -- '.$section_text['ARGS'] : ''; $cmd = $this->_preparePhpBin($this->_php, $temp_file, $ini_settings); $cmd.= "$args 2>&1"; if (isset($this->_logger)) { $this->_logger->log(2, 'Running command "' . $cmd . '"'); } // Reset environment from any previous test. $env = $this->_resetEnv($section_text, $temp_file); $section_text = $this->_processUpload($section_text, $file); if (PEAR::isError($section_text)) { return $section_text; } if (array_key_exists('POST_RAW', $section_text) && !empty($section_text['POST_RAW'])) { $post = trim($section_text['POST_RAW']); $raw_lines = explode("\n", $post); $request = ''; $started = false; foreach ($raw_lines as $i => $line) { if (empty($env['CONTENT_TYPE']) && preg_match('/^Content-Type:(.*)/i', $line, $res)) { $env['CONTENT_TYPE'] = trim(str_replace("\r", '', $res[1])); continue; } if ($started) { $request .= "\n"; } $started = true; $request .= $line; } $env['CONTENT_LENGTH'] = strlen($request); $env['REQUEST_METHOD'] = 'POST'; $this->save_text($tmp_post, $request); $cmd = "$this->_php$pass_options$ini_settings \"$temp_file\" 2>&1 < $tmp_post"; } elseif (array_key_exists('POST', $section_text) && !empty($section_text['POST'])) { $post = trim($section_text['POST']); $this->save_text($tmp_post, $post); $content_length = strlen($post); $env['REQUEST_METHOD'] = 'POST'; $env['CONTENT_TYPE'] = 'application/x-www-form-urlencoded'; $env['CONTENT_LENGTH'] = $content_length; $cmd = "$this->_php$pass_options$ini_settings \"$temp_file\" 2>&1 < $tmp_post"; } else { $env['REQUEST_METHOD'] = 'GET'; $env['CONTENT_TYPE'] = ''; $env['CONTENT_LENGTH'] = ''; } if (OS_WINDOWS && isset($section_text['RETURNS'])) { ob_start(); system($cmd, $return_value); $out = ob_get_contents(); ob_end_clean(); $section_text['RETURNS'] = (int) trim($section_text['RETURNS']); $returnfail = ($return_value != $section_text['RETURNS']); } else { $returnfail = false; $stdin = isset($section_text['STDIN']) ? $section_text['STDIN'] : null; $out = $this->system_with_timeout($cmd, $env, $stdin); $return_value = $out[0]; $out = $out[1]; } $output = preg_replace('/\r\n/', "\n", trim($out)); if (isset($tmp_post) && realpath($tmp_post) && file_exists($tmp_post)) { @unlink(realpath($tmp_post)); } chdir($cwd); // in case the test moves us around /* when using CGI, strip the headers from the output */ $output = $this->_stripHeadersCGI($output); if (isset($section_text['EXPECTHEADERS'])) { $testheaders = $this->_processHeaders($section_text['EXPECTHEADERS']); $missing = array_diff_assoc($testheaders, $this->_headers); $changed = ''; foreach ($missing as $header => $value) { if (isset($this->_headers[$header])) { $changed .= "-$header: $value\n+$header: "; $changed .= $this->_headers[$header]; } else { $changed .= "-$header: $value\n"; } } if ($missing) { // tack on failed headers to output: $output .= "\n====EXPECTHEADERS FAILURE====:\n$changed"; } } $this->_testCleanup($section_text, $temp_clean); // Does the output match what is expected? do { if (isset($section_text['EXPECTF']) || isset($section_text['EXPECTREGEX'])) { if (isset($section_text['EXPECTF'])) { $wanted = trim($section_text['EXPECTF']); } else { $wanted = trim($section_text['EXPECTREGEX']); } $wanted_re = preg_replace('/\r\n/', "\n", $wanted); if (isset($section_text['EXPECTF'])) { $wanted_re = preg_quote($wanted_re, '/'); // Stick to basics $wanted_re = str_replace("%s", ".+?", $wanted_re); //not greedy $wanted_re = str_replace("%S", ".*?", $wanted_re); //not greedy $wanted_re = str_replace("%i", "[+\-]?[0-9]+", $wanted_re); $wanted_re = str_replace("%d", "[0-9]+", $wanted_re); $wanted_re = str_replace("%x", "[0-9a-fA-F]+", $wanted_re); $wanted_re = str_replace("%f", "[+\-]?\.?[0-9]+\.?[0-9]*(E-?[0-9]+)?", $wanted_re); $wanted_re = str_replace("%c", ".", $wanted_re); // %f allows two points "-.0.0" but that is the best *simple* expression } /* DEBUG YOUR REGEX HERE var_dump($wanted_re); print(str_repeat('=', 80) . "\n"); var_dump($output); */ if (!$returnfail && preg_match("/^$wanted_re\$/s", $output)) { if (file_exists($temp_file)) { unlink($temp_file); } if (array_key_exists('FAIL', $section_text)) { break; } if (!isset($this->_options['quiet'])) { $this->_logger->log(0, "PASS $test_nr$tested$info"); } if (isset($this->_options['tapoutput'])) { return array('ok', ' - ' . $tested); } return 'PASSED'; } } else { if (isset($section_text['EXPECTFILE'])) { $f = $temp_dir . '/' . trim($section_text['EXPECTFILE']); if (!($fp = @fopen($f, 'rb'))) { return PEAR::raiseError('--EXPECTFILE-- section file ' . $f . ' not found'); } fclose($fp); $section_text['EXPECT'] = file_get_contents($f); } if (isset($section_text['EXPECT'])) { $wanted = preg_replace('/\r\n/', "\n", trim($section_text['EXPECT'])); } else { $wanted = ''; } // compare and leave on success if (!$returnfail && 0 == strcmp($output, $wanted)) { if (file_exists($temp_file)) { unlink($temp_file); } if (array_key_exists('FAIL', $section_text)) { break; } if (!isset($this->_options['quiet'])) { $this->_logger->log(0, "PASS $test_nr$tested$info"); } if (isset($this->_options['tapoutput'])) { return array('ok', ' - ' . $tested); } return 'PASSED'; } } } while (false); if (array_key_exists('FAIL', $section_text)) { // we expect a particular failure // this is only used for testing PEAR_RunTest $expectf = isset($section_text['EXPECTF']) ? $wanted_re : null; $faildiff = $this->generate_diff($wanted, $output, null, $expectf); $faildiff = preg_replace('/\r/', '', $faildiff); $wanted = preg_replace('/\r/', '', trim($section_text['FAIL'])); if ($faildiff == $wanted) { if (!isset($this->_options['quiet'])) { $this->_logger->log(0, "PASS $test_nr$tested$info"); } if (isset($this->_options['tapoutput'])) { return array('ok', ' - ' . $tested); } return 'PASSED'; } unset($section_text['EXPECTF']); $output = $faildiff; if (isset($section_text['RETURNS'])) { return PEAR::raiseError('Cannot have both RETURNS and FAIL in the same test: ' . $file); } } // Test failed so we need to report details. $txt = $warn ? 'WARN ' : 'FAIL '; $this->_logger->log(0, $txt . $test_nr . $tested . $info); // write .exp $res = $this->_writeLog($exp_filename, $wanted); if (PEAR::isError($res)) { return $res; } // write .out $res = $this->_writeLog($output_filename, $output); if (PEAR::isError($res)) { return $res; } // write .diff $returns = isset($section_text['RETURNS']) ? array(trim($section_text['RETURNS']), $return_value) : null; $expectf = isset($section_text['EXPECTF']) ? $wanted_re : null; $data = $this->generate_diff($wanted, $output, $returns, $expectf); $res = $this->_writeLog($diff_filename, $data); if (isset($this->_options['showdiff'])) { $this->_logger->log(0, "========DIFF========"); $this->_logger->log(0, $data); $this->_logger->log(0, "========DONE========"); } if (PEAR::isError($res)) { return $res; } // write .log $data = " ---- EXPECTED OUTPUT $wanted ---- ACTUAL OUTPUT $output ---- FAILED "; if ($returnfail) { $data .= " ---- EXPECTED RETURN $section_text[RETURNS] ---- ACTUAL RETURN $return_value "; } $res = $this->_writeLog($log_filename, $data); if (PEAR::isError($res)) { return $res; } if (isset($this->_options['tapoutput'])) { $wanted = explode("\n", $wanted); $wanted = "# Expected output:\n#\n#" . implode("\n#", $wanted); $output = explode("\n", $output); $output = "#\n#\n# Actual output:\n#\n#" . implode("\n#", $output); return array($wanted . $output . 'not ok', ' - ' . $tested); } return $warn ? 'WARNED' : 'FAILED'; } function generate_diff($wanted, $output, $rvalue, $wanted_re) { $w = explode("\n", $wanted); $o = explode("\n", $output); $wr = explode("\n", $wanted_re); $w1 = array_diff_assoc($w, $o); $o1 = array_diff_assoc($o, $w); $o2 = $w2 = array(); foreach ($w1 as $idx => $val) { if (!$wanted_re || !isset($wr[$idx]) || !isset($o1[$idx]) || !preg_match('/^' . $wr[$idx] . '\\z/', $o1[$idx])) { $w2[sprintf("%03d<", $idx)] = sprintf("%03d- ", $idx + 1) . $val; } } foreach ($o1 as $idx => $val) { if (!$wanted_re || !isset($wr[$idx]) || !preg_match('/^' . $wr[$idx] . '\\z/', $val)) { $o2[sprintf("%03d>", $idx)] = sprintf("%03d+ ", $idx + 1) . $val; } } $diff = array_merge($w2, $o2); ksort($diff); $extra = $rvalue ? "##EXPECTED: $rvalue[0]\r\n##RETURNED: $rvalue[1]" : ''; return implode("\r\n", $diff) . $extra; } // Write the given text to a temporary file, and return the filename. function save_text($filename, $text) { if (!$fp = fopen($filename, 'w')) { return PEAR::raiseError("Cannot open file '" . $filename . "' (save_text)"); } fwrite($fp, $text); fclose($fp); if (1 < DETAILED) echo " FILE $filename {{{ $text }}} "; } function _cleanupOldFiles($file) { $temp_dir = realpath(dirname($file)); $mainFileName = basename($file, 'phpt'); $diff_filename = $temp_dir . DIRECTORY_SEPARATOR . $mainFileName.'diff'; $log_filename = $temp_dir . DIRECTORY_SEPARATOR . $mainFileName.'log'; $exp_filename = $temp_dir . DIRECTORY_SEPARATOR . $mainFileName.'exp'; $output_filename = $temp_dir . DIRECTORY_SEPARATOR . $mainFileName.'out'; $memcheck_filename = $temp_dir . DIRECTORY_SEPARATOR . $mainFileName.'mem'; $temp_file = $temp_dir . DIRECTORY_SEPARATOR . $mainFileName.'php'; $temp_skipif = $temp_dir . DIRECTORY_SEPARATOR . $mainFileName.'skip.php'; $temp_clean = $temp_dir . DIRECTORY_SEPARATOR . $mainFileName.'clean.php'; $tmp_post = $temp_dir . DIRECTORY_SEPARATOR . uniqid('phpt.'); // unlink old test results @unlink($diff_filename); @unlink($log_filename); @unlink($exp_filename); @unlink($output_filename); @unlink($memcheck_filename); @unlink($temp_file); @unlink($temp_skipif); @unlink($tmp_post); @unlink($temp_clean); } function _runSkipIf($section_text, $temp_skipif, $tested, $ini_settings) { $info = ''; $warn = false; if (array_key_exists('SKIPIF', $section_text) && trim($section_text['SKIPIF'])) { $this->save_text($temp_skipif, $section_text['SKIPIF']); $output = $this->system_with_timeout("$this->_php$ini_settings -f \"$temp_skipif\""); $output = $output[1]; $loutput = ltrim($output); unlink($temp_skipif); if (!strncasecmp('skip', $loutput, 4)) { $skipreason = "SKIP $tested"; if (preg_match('/^\s*skip\s*(.+)\s*/i', $output, $m)) { $skipreason .= '(reason: ' . $m[1] . ')'; } if (!isset($this->_options['quiet'])) { $this->_logger->log(0, $skipreason); } if (isset($this->_options['tapoutput'])) { return array('ok', ' # skip ' . $reason); } return 'SKIPPED'; } if (!strncasecmp('info', $loutput, 4) && preg_match('/^\s*info\s*(.+)\s*/i', $output, $m)) { $info = " (info: $m[1])"; } if (!strncasecmp('warn', $loutput, 4) && preg_match('/^\s*warn\s*(.+)\s*/i', $output, $m)) { $warn = true; /* only if there is a reason */ $info = " (warn: $m[1])"; } } return array('warn' => $warn, 'info' => $info); } function _stripHeadersCGI($output) { $this->headers = array(); if (!empty($this->_options['cgi']) && $this->_php == $this->_options['cgi'] && preg_match("/^(.*?)(?:\n\n(.*)|\\z)/s", $output, $match)) { $output = isset($match[2]) ? trim($match[2]) : ''; $this->_headers = $this->_processHeaders($match[1]); } return $output; } /** * Return an array that can be used with array_diff() to compare headers * * @param string $text */ function _processHeaders($text) { $headers = array(); $rh = preg_split("/[\n\r]+/", $text); foreach ($rh as $line) { if (strpos($line, ':')!== false) { $line = explode(':', $line, 2); $headers[trim($line[0])] = trim($line[1]); } } return $headers; } function _readFile($file) { // Load the sections of the test file. $section_text = array( 'TEST' => '(unnamed test)', 'SKIPIF' => '', 'GET' => '', 'COOKIE' => '', 'POST' => '', 'ARGS' => '', 'INI' => '', 'CLEAN' => '', ); if (!is_file($file) || !$fp = fopen($file, "r")) { return PEAR::raiseError("Cannot open test file: $file"); } $section = ''; while (!feof($fp)) { $line = fgets($fp); // Match the beginning of a section. if (preg_match('/^--([_A-Z]+)--/', $line, $r)) { $section = $r[1]; $section_text[$section] = ''; continue; } elseif (empty($section)) { fclose($fp); return PEAR::raiseError("Invalid sections formats in test file: $file"); } // Add to the section text. $section_text[$section] .= $line; } fclose($fp); return $section_text; } function _writeLog($logname, $data) { if (!$log = fopen($logname, 'w')) { return PEAR::raiseError("Cannot create test log - $logname"); } fwrite($log, $data); fclose($log); } function _resetEnv($section_text, $temp_file) { $env = $_ENV; $env['REDIRECT_STATUS'] = ''; $env['QUERY_STRING'] = ''; $env['PATH_TRANSLATED'] = ''; $env['SCRIPT_FILENAME'] = ''; $env['REQUEST_METHOD'] = ''; $env['CONTENT_TYPE'] = ''; $env['CONTENT_LENGTH'] = ''; if (!empty($section_text['ENV'])) { if (strpos($section_text['ENV'], '{PWD}') !== false) { $section_text['ENV'] = str_replace('{PWD}', dirname($temp_file), $section_text['ENV']); } foreach (explode("\n", trim($section_text['ENV'])) as $e) { $e = explode('=', trim($e), 2); if (!empty($e[0]) && isset($e[1])) { $env[$e[0]] = $e[1]; } } } if (array_key_exists('GET', $section_text)) { $env['QUERY_STRING'] = trim($section_text['GET']); } else { $env['QUERY_STRING'] = ''; } if (array_key_exists('COOKIE', $section_text)) { $env['HTTP_COOKIE'] = trim($section_text['COOKIE']); } else { $env['HTTP_COOKIE'] = ''; } $env['REDIRECT_STATUS'] = '1'; $env['PATH_TRANSLATED'] = $temp_file; $env['SCRIPT_FILENAME'] = $temp_file; return $env; } function _processUpload($section_text, $file) { if (array_key_exists('UPLOAD', $section_text) && !empty($section_text['UPLOAD'])) { $upload_files = trim($section_text['UPLOAD']); $upload_files = explode("\n", $upload_files); $request = "Content-Type: multipart/form-data; boundary=---------------------------20896060251896012921717172737\n" . "-----------------------------20896060251896012921717172737\n"; foreach ($upload_files as $fileinfo) { $fileinfo = explode('=', $fileinfo); if (count($fileinfo) != 2) { return PEAR::raiseError("Invalid UPLOAD section in test file: $file"); } if (!realpath(dirname($file) . '/' . $fileinfo[1])) { return PEAR::raiseError("File for upload does not exist: $fileinfo[1] " . "in test file: $file"); } $file_contents = file_get_contents(dirname($file) . '/' . $fileinfo[1]); $fileinfo[1] = basename($fileinfo[1]); $request .= "Content-Disposition: form-data; name=\"$fileinfo[0]\"; filename=\"$fileinfo[1]\"\n"; $request .= "Content-Type: text/plain\n\n"; $request .= $file_contents . "\n" . "-----------------------------20896060251896012921717172737\n"; } if (array_key_exists('POST', $section_text) && !empty($section_text['POST'])) { // encode POST raw $post = trim($section_text['POST']); $post = explode('&', $post); foreach ($post as $i => $post_info) { $post_info = explode('=', $post_info); if (count($post_info) != 2) { return PEAR::raiseError("Invalid POST data in test file: $file"); } $post_info[0] = rawurldecode($post_info[0]); $post_info[1] = rawurldecode($post_info[1]); $post[$i] = $post_info; } foreach ($post as $post_info) { $request .= "Content-Disposition: form-data; name=\"$post_info[0]\"\n\n"; $request .= $post_info[1] . "\n" . "-----------------------------20896060251896012921717172737\n"; } unset($section_text['POST']); } $section_text['POST_RAW'] = $request; } return $section_text; } function _testCleanup($section_text, $temp_clean) { if ($section_text['CLEAN']) { $this->_restorePHPBinary(); // perform test cleanup $this->save_text($temp_clean, $section_text['CLEAN']); $output = $this->system_with_timeout("$this->_php $temp_clean 2>&1"); if (strlen($output[1])) { echo "BORKED --CLEAN-- section! output:\n", $output[1]; } if (file_exists($temp_clean)) { unlink($temp_clean); } } } function _savePHPBinary() { $this->_savephp = $this->_php; } function _restorePHPBinary() { if (isset($this->_savephp)) { $this->_php = $this->_savephp; unset($this->_savephp); } } } PKu]ٲ==PEAR/PackageFile.phpnu[ * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ /** * needed for PEAR_VALIDATE_* constants */ require_once 'PEAR/Validate.php'; /** * Error code if the package.xml tag does not contain a valid version */ define('PEAR_PACKAGEFILE_ERROR_NO_PACKAGEVERSION', 1); /** * Error code if the package.xml tag version is not supported (version 1.0 and 1.1 are the only supported versions, * currently */ define('PEAR_PACKAGEFILE_ERROR_INVALID_PACKAGEVERSION', 2); /** * Abstraction for the package.xml package description file * * @category pear * @package PEAR * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ class PEAR_PackageFile { /** * @var PEAR_Config */ var $_config; var $_debug; var $_logger = false; /** * @var boolean */ var $_rawReturn = false; /** * helper for extracting Archive_Tar errors * @var array * @access private */ var $_extractErrors = array(); /** * * @param PEAR_Config $config * @param ? $debug * @param string @tmpdir Optional temporary directory for uncompressing * files */ function __construct(&$config, $debug = false) { $this->_config = $config; $this->_debug = $debug; } /** * Turn off validation - return a parsed package.xml without checking it * * This is used by the package-validate command */ function rawReturn() { $this->_rawReturn = true; } function setLogger(&$l) { $this->_logger = &$l; } /** * Create a PEAR_PackageFile_Parser_v* of a given version. * @param int $version * @return PEAR_PackageFile_Parser_v1|PEAR_PackageFile_Parser_v1 */ function &parserFactory($version) { if (!in_array($version[0], array('1', '2'))) { $a = false; return $a; } include_once 'PEAR/PackageFile/Parser/v' . $version[0] . '.php'; $version = $version[0]; $class = "PEAR_PackageFile_Parser_v$version"; $a = new $class; return $a; } /** * For simpler unit-testing * @return string */ function getClassPrefix() { return 'PEAR_PackageFile_v'; } /** * Create a PEAR_PackageFile_v* of a given version. * @param int $version * @return PEAR_PackageFile_v1|PEAR_PackageFile_v1 */ function &factory($version) { if (!in_array($version[0], array('1', '2'))) { $a = false; return $a; } include_once 'PEAR/PackageFile/v' . $version[0] . '.php'; $version = $version[0]; $class = $this->getClassPrefix() . $version; $a = new $class; return $a; } /** * Create a PEAR_PackageFile_v* from its toArray() method * * WARNING: no validation is performed, the array is assumed to be valid, * always parse from xml if you want validation. * @param array $arr * @return PEAR_PackageFileManager_v1|PEAR_PackageFileManager_v2 * @uses factory() to construct the returned object. */ function &fromArray($arr) { if (isset($arr['xsdversion'])) { $obj = &$this->factory($arr['xsdversion']); if ($this->_logger) { $obj->setLogger($this->_logger); } $obj->setConfig($this->_config); $obj->fromArray($arr); return $obj; } if (isset($arr['package']['attribs']['version'])) { $obj = &$this->factory($arr['package']['attribs']['version']); } else { $obj = &$this->factory('1.0'); } if ($this->_logger) { $obj->setLogger($this->_logger); } $obj->setConfig($this->_config); $obj->fromArray($arr); return $obj; } /** * Create a PEAR_PackageFile_v* from an XML string. * @access public * @param string $data contents of package.xml file * @param int $state package state (one of PEAR_VALIDATE_* constants) * @param string $file full path to the package.xml file (and the files * it references) * @param string $archive optional name of the archive that the XML was * extracted from, if any * @return PEAR_PackageFile_v1|PEAR_PackageFile_v2 * @uses parserFactory() to construct a parser to load the package. */ function &fromXmlString($data, $state, $file, $archive = false) { if (preg_match('/]+version=[\'"]([0-9]+\.[0-9]+)[\'"]/', $data, $packageversion)) { if (!in_array($packageversion[1], array('1.0', '2.0', '2.1'))) { return PEAR::raiseError('package.xml version "' . $packageversion[1] . '" is not supported, only 1.0, 2.0, and 2.1 are supported.'); } $object = &$this->parserFactory($packageversion[1]); if ($this->_logger) { $object->setLogger($this->_logger); } $object->setConfig($this->_config); $pf = $object->parse($data, $file, $archive); if (PEAR::isError($pf)) { return $pf; } if ($this->_rawReturn) { return $pf; } if (!$pf->validate($state)) {; if ($this->_config->get('verbose') > 0 && $this->_logger && $pf->getValidationWarnings(false) ) { foreach ($pf->getValidationWarnings(false) as $warning) { $this->_logger->log(0, 'ERROR: ' . $warning['message']); } } $a = PEAR::raiseError('Parsing of package.xml from file "' . $file . '" failed', 2, null, null, $pf->getValidationWarnings()); return $a; } if ($this->_logger && $pf->getValidationWarnings(false)) { foreach ($pf->getValidationWarnings() as $warning) { $this->_logger->log(0, 'WARNING: ' . $warning['message']); } } if (method_exists($pf, 'flattenFilelist')) { $pf->flattenFilelist(); // for v2 } return $pf; } elseif (preg_match('/]+version=[\'"]([^"\']+)[\'"]/', $data, $packageversion)) { $a = PEAR::raiseError('package.xml file "' . $file . '" has unsupported package.xml version "' . $packageversion[1] . '"'); return $a; } else { if (!class_exists('PEAR_ErrorStack')) { require_once 'PEAR/ErrorStack.php'; } PEAR_ErrorStack::staticPush('PEAR_PackageFile', PEAR_PACKAGEFILE_ERROR_NO_PACKAGEVERSION, 'warning', array('xml' => $data), 'package.xml "' . $file . '" has no package.xml version'); $object = &$this->parserFactory('1.0'); $object->setConfig($this->_config); $pf = $object->parse($data, $file, $archive); if (PEAR::isError($pf)) { return $pf; } if ($this->_rawReturn) { return $pf; } if (!$pf->validate($state)) { $a = PEAR::raiseError('Parsing of package.xml from file "' . $file . '" failed', 2, null, null, $pf->getValidationWarnings()); return $a; } if ($this->_logger && $pf->getValidationWarnings(false)) { foreach ($pf->getValidationWarnings() as $warning) { $this->_logger->log(0, 'WARNING: ' . $warning['message']); } } if (method_exists($pf, 'flattenFilelist')) { $pf->flattenFilelist(); // for v2 } return $pf; } } /** * Register a temporary file or directory. When the destructor is * executed, all registered temporary files and directories are * removed. * * @param string $file name of file or directory * @return void */ static function addTempFile($file) { $GLOBALS['_PEAR_Common_tempfiles'][] = $file; } /** * Create a PEAR_PackageFile_v* from a compressed Tar or Tgz file. * @access public * @param string contents of package.xml file * @param int package state (one of PEAR_VALIDATE_* constants) * @return PEAR_PackageFile_v1|PEAR_PackageFile_v2 * @using Archive_Tar to extract the files * @using fromPackageFile() to load the package after the package.xml * file is extracted. */ function &fromTgzFile($file, $state) { if (!class_exists('Archive_Tar')) { require_once 'Archive/Tar.php'; } $tar = new Archive_Tar($file); if ($this->_debug <= 1) { $tar->pushErrorHandling(PEAR_ERROR_RETURN); } $content = $tar->listContent(); if ($this->_debug <= 1) { $tar->popErrorHandling(); } if (!is_array($content)) { if (is_string($file) && strlen($file) < 255 && (!file_exists($file) || !@is_file($file))) { $ret = PEAR::raiseError("could not open file \"$file\""); return $ret; } $file = realpath($file); $ret = PEAR::raiseError("Could not get contents of package \"$file\"". '. Invalid tgz file.'); return $ret; } if (!count($content) && !@is_file($file)) { $ret = PEAR::raiseError("could not open file \"$file\""); return $ret; } $xml = null; $origfile = $file; foreach ($content as $file) { $name = $file['filename']; if ($name == 'package2.xml') { // allow a .tgz to distribute both versions $xml = $name; break; } if ($name == 'package.xml') { $xml = $name; break; } elseif (preg_match('/package.xml$/', $name, $match)) { $xml = $name; break; } } $tmpdir = System::mktemp('-t "' . $this->_config->get('temp_dir') . '" -d pear'); if ($tmpdir === false) { $ret = PEAR::raiseError("there was a problem with getting the configured temp directory"); return $ret; } PEAR_PackageFile::addTempFile($tmpdir); $this->_extractErrors(); PEAR::staticPushErrorHandling(PEAR_ERROR_CALLBACK, array($this, '_extractErrors')); if (!$xml || !$tar->extractList(array($xml), $tmpdir)) { $extra = implode("\n", $this->_extractErrors()); if ($extra) { $extra = ' ' . $extra; } PEAR::staticPopErrorHandling(); $ret = PEAR::raiseError('could not extract the package.xml file from "' . $origfile . '"' . $extra); return $ret; } PEAR::staticPopErrorHandling(); $ret = &PEAR_PackageFile::fromPackageFile("$tmpdir/$xml", $state, $origfile); return $ret; } /** * helper callback for extracting Archive_Tar errors * * @param PEAR_Error|null $err * @return array * @access private */ function _extractErrors($err = null) { static $errors = array(); if ($err === null) { $e = $errors; $errors = array(); return $e; } $errors[] = $err->getMessage(); } /** * Create a PEAR_PackageFile_v* from a package.xml file. * * @access public * @param string $descfile name of package xml file * @param int $state package state (one of PEAR_VALIDATE_* constants) * @param string|false $archive name of the archive this package.xml came * from, if any * @return PEAR_PackageFile_v1|PEAR_PackageFile_v2 * @uses PEAR_PackageFile::fromXmlString to create the oject after the * XML is loaded from the package.xml file. */ function &fromPackageFile($descfile, $state, $archive = false) { $fp = false; if (is_string($descfile) && strlen($descfile) < 255 && ( !file_exists($descfile) || !is_file($descfile) || !is_readable($descfile) || (!$fp = @fopen($descfile, 'r')) ) ) { $a = PEAR::raiseError("Unable to open $descfile"); return $a; } // read the whole thing so we only get one cdata callback // for each block of cdata fclose($fp); $data = file_get_contents($descfile); $ret = &PEAR_PackageFile::fromXmlString($data, $state, $descfile, $archive); return $ret; } /** * Create a PEAR_PackageFile_v* from a .tgz archive or package.xml file. * * This method is able to extract information about a package from a .tgz * archive or from a XML package definition file. * * @access public * @param string $info file name * @param int $state package state (one of PEAR_VALIDATE_* constants) * @return PEAR_PackageFile_v1|PEAR_PackageFile_v2 * @uses fromPackageFile() if the file appears to be XML * @uses fromTgzFile() to load all non-XML files */ function &fromAnyFile($info, $state) { if (is_dir($info)) { $dir_name = realpath($info); if (file_exists($dir_name . '/package.xml')) { $info = PEAR_PackageFile::fromPackageFile($dir_name . '/package.xml', $state); } elseif (file_exists($dir_name . '/package2.xml')) { $info = PEAR_PackageFile::fromPackageFile($dir_name . '/package2.xml', $state); } else { $info = PEAR::raiseError("No package definition found in '$info' directory"); } return $info; } $fp = false; if (is_string($info) && strlen($info) < 255 && (file_exists($info) || ($fp = @fopen($info, 'r'))) ) { if ($fp) { fclose($fp); } $tmp = substr($info, -4); if ($tmp == '.xml') { $info = &PEAR_PackageFile::fromPackageFile($info, $state); } elseif ($tmp == '.tar' || $tmp == '.tgz') { $info = &PEAR_PackageFile::fromTgzFile($info, $state); } else { $fp = fopen($info, 'r'); $test = fread($fp, 5); fclose($fp); if ($test == ' * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ /** * base xml parser class */ require_once 'PEAR/XMLParser.php'; require_once 'PEAR/ChannelFile.php'; /** * Parser for channel.xml * @category pear * @package PEAR * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ class PEAR_ChannelFile_Parser extends PEAR_XMLParser { var $_config; var $_logger; var $_registry; function setConfig(&$c) { $this->_config = &$c; $this->_registry = &$c->getRegistry(); } function setLogger(&$l) { $this->_logger = &$l; } function parse($data, $file) { if (PEAR::isError($err = parent::parse($data, $file))) { return $err; } $ret = new PEAR_ChannelFile; $ret->setConfig($this->_config); if (isset($this->_logger)) { $ret->setLogger($this->_logger); } $ret->fromArray($this->_unserializedData); // make sure the filelist is in the easy to read format needed $ret->flattenFilelist(); $ret->setPackagefile($file, $archive); return $ret; } }PKu]`eEAEA PEAR/REST.phpnu[ * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ /** * For downloading xml files */ require_once 'PEAR.php'; require_once 'PEAR/XMLParser.php'; require_once 'PEAR/Proxy.php'; /** * Intelligently retrieve data, following hyperlinks if necessary, and re-directing * as well * @category pear * @package PEAR * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ class PEAR_REST { var $config; var $_options; function __construct(&$config, $options = array()) { $this->config = &$config; $this->_options = $options; } /** * Retrieve REST data, but always retrieve the local cache if it is available. * * This is useful for elements that should never change, such as information on a particular * release * @param string full URL to this resource * @param array|false contents of the accept-encoding header * @param boolean if true, xml will be returned as a string, otherwise, xml will be * parsed using PEAR_XMLParser * @return string|array */ function retrieveCacheFirst($url, $accept = false, $forcestring = false, $channel = false) { $cachefile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR . md5($url) . 'rest.cachefile'; if (file_exists($cachefile)) { return unserialize(implode('', file($cachefile))); } return $this->retrieveData($url, $accept, $forcestring, $channel); } /** * Retrieve a remote REST resource * @param string full URL to this resource * @param array|false contents of the accept-encoding header * @param boolean if true, xml will be returned as a string, otherwise, xml will be * parsed using PEAR_XMLParser * @return string|array */ function retrieveData($url, $accept = false, $forcestring = false, $channel = false) { $cacheId = $this->getCacheId($url); if ($ret = $this->useLocalCache($url, $cacheId)) { return $ret; } $file = $trieddownload = false; if (!isset($this->_options['offline'])) { $trieddownload = true; $file = $this->downloadHttp($url, $cacheId ? $cacheId['lastChange'] : false, $accept, $channel); } if (PEAR::isError($file)) { if ($file->getCode() !== -9276) { return $file; } $trieddownload = false; $file = false; // use local copy if available on socket connect error } if (!$file) { $ret = $this->getCache($url); if (!PEAR::isError($ret) && $trieddownload) { // reset the age of the cache if the server says it was unmodified $result = $this->saveCache($url, $ret, null, true, $cacheId); if (PEAR::isError($result)) { return PEAR::raiseError($result->getMessage()); } } return $ret; } if (is_array($file)) { $headers = $file[2]; $lastmodified = $file[1]; $content = $file[0]; } else { $headers = array(); $lastmodified = false; $content = $file; } if ($forcestring) { $result = $this->saveCache($url, $content, $lastmodified, false, $cacheId); if (PEAR::isError($result)) { return PEAR::raiseError($result->getMessage()); } return $content; } if (isset($headers['content-type'])) { $content_type = explode(";", $headers['content-type']); $content_type = $content_type[0]; switch ($content_type) { case 'text/xml' : case 'application/xml' : case 'text/plain' : if ($content_type === 'text/plain') { $check = substr($content, 0, 5); if ($check !== 'parse($content); PEAR::popErrorHandling(); if (PEAR::isError($err)) { return PEAR::raiseError('Invalid xml downloaded from "' . $url . '": ' . $err->getMessage()); } $content = $parser->getData(); case 'text/html' : default : // use it as a string } } else { // assume XML $parser = new PEAR_XMLParser; $parser->parse($content); $content = $parser->getData(); } $result = $this->saveCache($url, $content, $lastmodified, false, $cacheId); if (PEAR::isError($result)) { return PEAR::raiseError($result->getMessage()); } return $content; } function useLocalCache($url, $cacheid = null) { if (!is_array($cacheid)) { $cacheid = $this->getCacheId($url); } $cachettl = $this->config->get('cache_ttl'); // If cache is newer than $cachettl seconds, we use the cache! if (is_array($cacheid) && time() - $cacheid['age'] < $cachettl) { return $this->getCache($url); } return false; } /** * @param string $url * * @return bool|mixed */ function getCacheId($url) { $cacheidfile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR . md5($url) . 'rest.cacheid'; if (!file_exists($cacheidfile)) { return false; } $ret = unserialize(implode('', file($cacheidfile))); return $ret; } function getCache($url) { $cachefile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR . md5($url) . 'rest.cachefile'; if (!file_exists($cachefile)) { return PEAR::raiseError('No cached content available for "' . $url . '"'); } return unserialize(implode('', file($cachefile))); } /** * @param string full URL to REST resource * @param string original contents of the REST resource * @param array HTTP Last-Modified and ETag headers * @param bool if true, then the cache id file should be regenerated to * trigger a new time-to-live value */ function saveCache($url, $contents, $lastmodified, $nochange = false, $cacheid = null) { $cache_dir = $this->config->get('cache_dir'); $d = $cache_dir . DIRECTORY_SEPARATOR . md5($url); $cacheidfile = $d . 'rest.cacheid'; $cachefile = $d . 'rest.cachefile'; if (!is_dir($cache_dir)) { if (System::mkdir(array('-p', $cache_dir)) === false) { return PEAR::raiseError("The value of config option cache_dir ($cache_dir) is not a directory and attempts to create the directory failed."); } } if (!is_writeable($cache_dir)) { // If writing to the cache dir is not going to work, silently do nothing. // An ugly hack, but retains compat with PEAR 1.9.1 where many commands // work fine as non-root user (w/out write access to default cache dir). return true; } if ($cacheid === null && $nochange) { $cacheid = unserialize(implode('', file($cacheidfile))); } $idData = serialize(array( 'age' => time(), 'lastChange' => ($nochange ? $cacheid['lastChange'] : $lastmodified), )); $result = $this->saveCacheFile($cacheidfile, $idData); if (PEAR::isError($result)) { return $result; } elseif ($nochange) { return true; } $result = $this->saveCacheFile($cachefile, serialize($contents)); if (PEAR::isError($result)) { if (file_exists($cacheidfile)) { @unlink($cacheidfile); } return $result; } return true; } function saveCacheFile($file, $contents) { $len = strlen($contents); $cachefile_fp = @fopen($file, 'xb'); // x is the O_CREAT|O_EXCL mode if ($cachefile_fp !== false) { // create file if (fwrite($cachefile_fp, $contents, $len) < $len) { fclose($cachefile_fp); return PEAR::raiseError("Could not write $file."); } } else { // update file $cachefile_fp = @fopen($file, 'r+b'); // do not truncate file if (!$cachefile_fp) { return PEAR::raiseError("Could not open $file for writing."); } if (OS_WINDOWS) { $not_symlink = !is_link($file); // see bug #18834 } else { $cachefile_lstat = lstat($file); $cachefile_fstat = fstat($cachefile_fp); $not_symlink = $cachefile_lstat['mode'] == $cachefile_fstat['mode'] && $cachefile_lstat['ino'] == $cachefile_fstat['ino'] && $cachefile_lstat['dev'] == $cachefile_fstat['dev'] && $cachefile_fstat['nlink'] === 1; } if ($not_symlink) { ftruncate($cachefile_fp, 0); // NOW truncate if (fwrite($cachefile_fp, $contents, $len) < $len) { fclose($cachefile_fp); return PEAR::raiseError("Could not write $file."); } } else { fclose($cachefile_fp); $link = function_exists('readlink') ? readlink($file) : $file; return PEAR::raiseError('SECURITY ERROR: Will not write to ' . $file . ' as it is symlinked to ' . $link . ' - Possible symlink attack'); } } fclose($cachefile_fp); return true; } /** * Efficiently Download a file through HTTP. Returns downloaded file as a string in-memory * This is best used for small files * * If an HTTP proxy has been configured (http_proxy PEAR_Config * setting), the proxy will be used. * * @param string $url the URL to download * @param string $save_dir directory to save file in * @param false|string|array $lastmodified header values to check against for caching * use false to return the header values from this download * @param false|array $accept Accept headers to send * @return string|array Returns the contents of the downloaded file or a PEAR * error on failure. If the error is caused by * socket-related errors, the error object will * have the fsockopen error code available through * getCode(). If caching is requested, then return the header * values. * * @access public */ function downloadHttp($url, $lastmodified = null, $accept = false, $channel = false) { static $redirect = 0; // always reset , so we are clean case of error $wasredirect = $redirect; $redirect = 0; $info = parse_url($url); if (!isset($info['scheme']) || !in_array($info['scheme'], array('http', 'https'))) { return PEAR::raiseError('Cannot download non-http URL "' . $url . '"'); } if (!isset($info['host'])) { return PEAR::raiseError('Cannot download from non-URL "' . $url . '"'); } $host = isset($info['host']) ? $info['host'] : null; $port = isset($info['port']) ? $info['port'] : null; $path = isset($info['path']) ? $info['path'] : null; $schema = (isset($info['scheme']) && $info['scheme'] == 'https') ? 'https' : 'http'; $proxy = new PEAR_Proxy($this->config); if (empty($port)) { $port = (isset($info['scheme']) && $info['scheme'] == 'https') ? 443 : 80; } if ($proxy->isProxyConfigured() && $schema === 'http') { $request = "GET $url HTTP/1.1\r\n"; } else { $request = "GET $path HTTP/1.1\r\n"; } $request .= "Host: $host\r\n"; $ifmodifiedsince = ''; if (is_array($lastmodified)) { if (isset($lastmodified['Last-Modified'])) { $ifmodifiedsince = 'If-Modified-Since: ' . $lastmodified['Last-Modified'] . "\r\n"; } if (isset($lastmodified['ETag'])) { $ifmodifiedsince .= "If-None-Match: $lastmodified[ETag]\r\n"; } } else { $ifmodifiedsince = ($lastmodified ? "If-Modified-Since: $lastmodified\r\n" : ''); } $request .= $ifmodifiedsince . "User-Agent: PEAR/1.10.16/PHP/" . PHP_VERSION . "\r\n"; $username = $this->config->get('username', null, $channel); $password = $this->config->get('password', null, $channel); if ($username && $password) { $tmp = base64_encode("$username:$password"); $request .= "Authorization: Basic $tmp\r\n"; } $proxyAuth = $proxy->getProxyAuth(); if ($proxyAuth) { $request .= 'Proxy-Authorization: Basic ' . $proxyAuth . "\r\n"; } if ($accept) { $request .= 'Accept: ' . implode(', ', $accept) . "\r\n"; } $request .= "Accept-Encoding:\r\n"; $request .= "Connection: close\r\n"; $request .= "\r\n"; $secure = ($schema == 'https'); $fp = $proxy->openSocket($host, $port, $secure); if (PEAR::isError($fp)) { return $fp; } fwrite($fp, $request); $headers = array(); $reply = 0; while ($line = trim(fgets($fp, 1024))) { if (preg_match('/^([^:]+):\s+(.*)\s*\\z/', $line, $matches)) { $headers[strtolower($matches[1])] = trim($matches[2]); } elseif (preg_match('|^HTTP/1.[01] ([0-9]{3}) |', $line, $matches)) { $reply = (int)$matches[1]; if ($reply == 304 && ($lastmodified || ($lastmodified === false))) { return false; } if (!in_array($reply, array(200, 301, 302, 303, 305, 307))) { return PEAR::raiseError("File $schema://$host:$port$path not valid (received: $line)"); } } } if ($reply != 200) { if (!isset($headers['location'])) { return PEAR::raiseError("File $schema://$host:$port$path not valid (redirected but no location)"); } if ($wasredirect > 4) { return PEAR::raiseError("File $schema://$host:$port$path not valid (redirection looped more than 5 times)"); } $redirect = $wasredirect + 1; return $this->downloadHttp($headers['location'], $lastmodified, $accept, $channel); } $length = isset($headers['content-length']) ? $headers['content-length'] : -1; $data = ''; while ($chunk = @fread($fp, 8192)) { $data .= $chunk; } fclose($fp); if ($lastmodified === false || $lastmodified) { if (isset($headers['etag'])) { $lastmodified = array('ETag' => $headers['etag']); } if (isset($headers['last-modified'])) { if (is_array($lastmodified)) { $lastmodified['Last-Modified'] = $headers['last-modified']; } else { $lastmodified = $headers['last-modified']; } } return array($data, $lastmodified, $headers); } return $data; } } PKu]{ ))PEAR/Downloader/Package.phpnu[ * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ /** * Error code when parameter initialization fails because no releases * exist within preferred_state, but releases do exist */ define('PEAR_DOWNLOADER_PACKAGE_STATE', -1003); /** * Error code when parameter initialization fails because no releases * exist that will work with the existing PHP version */ define('PEAR_DOWNLOADER_PACKAGE_PHPVERSION', -1004); /** * Coordinates download parameters and manages their dependencies * prior to downloading them. * * Input can come from three sources: * * - local files (archives or package.xml) * - remote files (downloadable urls) * - abstract package names * * The first two elements are handled cleanly by PEAR_PackageFile, but the third requires * accessing pearweb's xml-rpc interface to determine necessary dependencies, and the * format returned of dependencies is slightly different from that used in package.xml. * * This class hides the differences between these elements, and makes automatic * dependency resolution a piece of cake. It also manages conflicts when * two classes depend on incompatible dependencies, or differing versions of the same * package dependency. In addition, download will not be attempted if the php version is * not supported, PEAR installer version is not supported, or non-PECL extensions are not * installed. * @category pear * @package PEAR * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ class PEAR_Downloader_Package { /** * @var PEAR_Downloader */ var $_downloader; /** * @var PEAR_Config */ var $_config; /** * @var PEAR_Registry */ var $_registry; /** * Used to implement packagingroot properly * @var PEAR_Registry */ var $_installRegistry; /** * @var PEAR_PackageFile_v1|PEAR_PackageFile|v2 */ var $_packagefile; /** * @var array */ var $_parsedname; /** * @var array */ var $_downloadURL; /** * @var array */ var $_downloadDeps = array(); /** * @var boolean */ var $_valid = false; /** * @var boolean */ var $_analyzed = false; /** * if this or a parent package was invoked with Package-state, this is set to the * state variable. * * This allows temporary reassignment of preferred_state for a parent package and all of * its dependencies. * @var string|false */ var $_explicitState = false; /** * If this package is invoked with Package#group, this variable will be true */ var $_explicitGroup = false; /** * Package type local|url * @var string */ var $_type; /** * Contents of package.xml, if downloaded from a remote channel * @var string|false * @access private */ var $_rawpackagefile; /** * @var boolean * @access private */ var $_validated = false; /** * @param PEAR_Downloader */ function __construct(&$downloader) { $this->_downloader = &$downloader; $this->_config = &$this->_downloader->config; $this->_registry = &$this->_config->getRegistry(); $options = $downloader->getOptions(); if (isset($options['packagingroot'])) { $this->_config->setInstallRoot($options['packagingroot']); $this->_installRegistry = &$this->_config->getRegistry(); $this->_config->setInstallRoot(false); } else { $this->_installRegistry = &$this->_registry; } $this->_valid = $this->_analyzed = false; } /** * Parse the input and determine whether this is a local file, a remote uri, or an * abstract package name. * * This is the heart of the PEAR_Downloader_Package(), and is used in * {@link PEAR_Downloader::download()} * @param string * @return bool|PEAR_Error */ function initialize($param) { $origErr = $this->_fromFile($param); if ($this->_valid) { return true; } $options = $this->_downloader->getOptions(); if (isset($options['offline'])) { if (PEAR::isError($origErr) && !isset($options['soft'])) { foreach ($origErr->getUserInfo() as $userInfo) { if (isset($userInfo['message'])) { $this->_downloader->log(0, $userInfo['message']); } } $this->_downloader->log(0, $origErr->getMessage()); } return PEAR::raiseError('Cannot download non-local package "' . $param . '"'); } $err = $this->_fromUrl($param); if (PEAR::isError($err) || !$this->_valid) { if ($this->_type == 'url') { if (PEAR::isError($err) && !isset($options['soft'])) { $this->_downloader->log(0, $err->getMessage()); } return PEAR::raiseError("Invalid or missing remote package file"); } $err = $this->_fromString($param); if (PEAR::isError($err) || !$this->_valid) { if (PEAR::isError($err) && $err->getCode() == PEAR_DOWNLOADER_PACKAGE_STATE) { return false; // instruct the downloader to silently skip } if (isset($this->_type) && $this->_type == 'local' && PEAR::isError($origErr)) { if (is_array($origErr->getUserInfo())) { foreach ($origErr->getUserInfo() as $err) { if (is_array($err)) { $err = $err['message']; } if (!isset($options['soft'])) { $this->_downloader->log(0, $err); } } } if (!isset($options['soft'])) { $this->_downloader->log(0, $origErr->getMessage()); } if (is_array($param)) { $param = $this->_registry->parsedPackageNameToString($param, true); } if (!isset($options['soft'])) { $this->_downloader->log(2, "Cannot initialize '$param', invalid or missing package file"); } // Passing no message back - already logged above return PEAR::raiseError(); } if (PEAR::isError($err) && !isset($options['soft'])) { $this->_downloader->log(0, $err->getMessage()); } if (is_array($param)) { $param = $this->_registry->parsedPackageNameToString($param, true); } if (!isset($options['soft'])) { $this->_downloader->log(2, "Cannot initialize '$param', invalid or missing package file"); } // Passing no message back - already logged above return PEAR::raiseError(); } } return true; } /** * Retrieve any non-local packages * @return PEAR_PackageFile_v1|PEAR_PackageFile_v2|PEAR_Error */ function &download() { if (isset($this->_packagefile)) { return $this->_packagefile; } if (isset($this->_downloadURL['url'])) { $this->_isvalid = false; $info = $this->getParsedPackage(); foreach ($info as $i => $p) { $info[$i] = strtolower($p); } $err = $this->_fromUrl($this->_downloadURL['url'], $this->_registry->parsedPackageNameToString($this->_parsedname, true)); $newinfo = $this->getParsedPackage(); foreach ($newinfo as $i => $p) { $newinfo[$i] = strtolower($p); } if ($info != $newinfo) { do { if ($info['channel'] == 'pecl.php.net' && $newinfo['channel'] == 'pear.php.net') { $info['channel'] = 'pear.php.net'; if ($info == $newinfo) { // skip the channel check if a pecl package says it's a PEAR package break; } } if ($info['channel'] == 'pear.php.net' && $newinfo['channel'] == 'pecl.php.net') { $info['channel'] = 'pecl.php.net'; if ($info == $newinfo) { // skip the channel check if a pecl package says it's a PEAR package break; } } return PEAR::raiseError('CRITICAL ERROR: We are ' . $this->_registry->parsedPackageNameToString($info) . ', but the file ' . 'downloaded claims to be ' . $this->_registry->parsedPackageNameToString($this->getParsedPackage())); } while (false); } if (PEAR::isError($err) || !$this->_valid) { return $err; } } $this->_type = 'local'; return $this->_packagefile; } function &getPackageFile() { return $this->_packagefile; } function &getDownloader() { return $this->_downloader; } function getType() { return $this->_type; } /** * Like {@link initialize()}, but operates on a dependency */ function fromDepURL($dep) { $this->_downloadURL = $dep; if (isset($dep['uri'])) { $options = $this->_downloader->getOptions(); if (!extension_loaded("zlib") || isset($options['nocompress'])) { $ext = '.tar'; } else { $ext = '.tgz'; } PEAR::pushErrorHandling(PEAR_ERROR_RETURN); $err = $this->_fromUrl($dep['uri'] . $ext); PEAR::popErrorHandling(); if (PEAR::isError($err)) { if (!isset($options['soft'])) { $this->_downloader->log(0, $err->getMessage()); } return PEAR::raiseError('Invalid uri dependency "' . $dep['uri'] . $ext . '", ' . 'cannot download'); } } else { $this->_parsedname = array( 'package' => $dep['info']->getPackage(), 'channel' => $dep['info']->getChannel(), 'version' => $dep['version'] ); if (!isset($dep['nodefault'])) { $this->_parsedname['group'] = 'default'; // download the default dependency group $this->_explicitGroup = false; } $this->_rawpackagefile = $dep['raw']; } } function detectDependencies($params) { $options = $this->_downloader->getOptions(); if (isset($options['downloadonly'])) { return; } if (isset($options['offline'])) { $this->_downloader->log(3, 'Skipping dependency download check, --offline specified'); return; } $pname = $this->getParsedPackage(); if (!$pname) { return; } $deps = $this->getDeps(); if (!$deps) { return; } if (isset($deps['required'])) { // package.xml 2.0 return $this->_detect2($deps, $pname, $options, $params); } return $this->_detect1($deps, $pname, $options, $params); } function setValidated() { $this->_validated = true; } function alreadyValidated() { return $this->_validated; } /** * Remove packages to be downloaded that are already installed * @param array of PEAR_Downloader_Package objects */ public static function removeInstalled(&$params) { if (!isset($params[0])) { return; } $options = $params[0]->_downloader->getOptions(); if (!isset($options['downloadonly'])) { foreach ($params as $i => $param) { $package = $param->getPackage(); $channel = $param->getChannel(); // remove self if already installed with this version // this does not need any pecl magic - we only remove exact matches if ($param->_installRegistry->packageExists($package, $channel)) { $packageVersion = $param->_installRegistry->packageInfo($package, 'version', $channel); if (version_compare($packageVersion, $param->getVersion(), '==')) { if (!isset($options['force']) && !isset($options['packagingroot'])) { $info = $param->getParsedPackage(); unset($info['version']); unset($info['state']); if (!isset($options['soft'])) { $param->_downloader->log(1, 'Skipping package "' . $param->getShortName() . '", already installed as version ' . $packageVersion); } $params[$i] = false; } } elseif (!isset($options['force']) && !isset($options['upgrade']) && !isset($options['soft']) && !isset($options['packagingroot'])) { $info = $param->getParsedPackage(); $param->_downloader->log(1, 'Skipping package "' . $param->getShortName() . '", already installed as version ' . $packageVersion); $params[$i] = false; } } } } PEAR_Downloader_Package::removeDuplicates($params); } function _detect2($deps, $pname, $options, $params) { $this->_downloadDeps = array(); $groupnotfound = false; foreach (array('package', 'subpackage') as $packagetype) { // get required dependency group if (isset($deps['required'][$packagetype])) { if (isset($deps['required'][$packagetype][0])) { foreach ($deps['required'][$packagetype] as $dep) { if (isset($dep['conflicts'])) { // skip any package that this package conflicts with continue; } $ret = $this->_detect2Dep($dep, $pname, 'required', $params); if (is_array($ret)) { $this->_downloadDeps[] = $ret; } elseif (PEAR::isError($ret) && !isset($options['soft'])) { $this->_downloader->log(0, $ret->getMessage()); } } } else { $dep = $deps['required'][$packagetype]; if (!isset($dep['conflicts'])) { // skip any package that this package conflicts with $ret = $this->_detect2Dep($dep, $pname, 'required', $params); if (is_array($ret)) { $this->_downloadDeps[] = $ret; } elseif (PEAR::isError($ret) && !isset($options['soft'])) { $this->_downloader->log(0, $ret->getMessage()); } } } } // get optional dependency group, if any if (isset($deps['optional'][$packagetype])) { $skipnames = array(); if (!isset($deps['optional'][$packagetype][0])) { $deps['optional'][$packagetype] = array($deps['optional'][$packagetype]); } foreach ($deps['optional'][$packagetype] as $dep) { $skip = false; if (!isset($options['alldeps'])) { $dep['package'] = $dep['name']; if (!isset($options['soft'])) { $this->_downloader->log(3, 'Notice: package "' . $this->_registry->parsedPackageNameToString($this->getParsedPackage(), true) . '" optional dependency "' . $this->_registry->parsedPackageNameToString(array('package' => $dep['name'], 'channel' => 'pear.php.net'), true) . '" will not be automatically downloaded'); } $skipnames[] = $this->_registry->parsedPackageNameToString($dep, true); $skip = true; unset($dep['package']); } $ret = $this->_detect2Dep($dep, $pname, 'optional', $params); if (PEAR::isError($ret) && !isset($options['soft'])) { $this->_downloader->log(0, $ret->getMessage()); } if (!$ret) { $dep['package'] = $dep['name']; $skip = count($skipnames) ? $skipnames[count($skipnames) - 1] : ''; if ($skip == $this->_registry->parsedPackageNameToString($dep, true)) { array_pop($skipnames); } } if (!$skip && is_array($ret)) { $this->_downloadDeps[] = $ret; } } if (count($skipnames)) { if (!isset($options['soft'])) { $this->_downloader->log(1, 'Did not download optional dependencies: ' . implode(', ', $skipnames) . ', use --alldeps to download automatically'); } } } // get requested dependency group, if any $groupname = $this->getGroup(); $explicit = $this->_explicitGroup; if (!$groupname) { if (!$this->canDefault()) { continue; } $groupname = 'default'; // try the default dependency group } if ($groupnotfound) { continue; } if (isset($deps['group'])) { if (isset($deps['group']['attribs'])) { if (strtolower($deps['group']['attribs']['name']) == strtolower($groupname)) { $group = $deps['group']; } elseif ($explicit) { if (!isset($options['soft'])) { $this->_downloader->log(0, 'Warning: package "' . $this->_registry->parsedPackageNameToString($pname, true) . '" has no dependency ' . 'group named "' . $groupname . '"'); } $groupnotfound = true; continue; } } else { $found = false; foreach ($deps['group'] as $group) { if (strtolower($group['attribs']['name']) == strtolower($groupname)) { $found = true; break; } } if (!$found) { if ($explicit) { if (!isset($options['soft'])) { $this->_downloader->log(0, 'Warning: package "' . $this->_registry->parsedPackageNameToString($pname, true) . '" has no dependency ' . 'group named "' . $groupname . '"'); } } $groupnotfound = true; continue; } } } if (isset($group) && isset($group[$packagetype])) { if (isset($group[$packagetype][0])) { foreach ($group[$packagetype] as $dep) { $ret = $this->_detect2Dep($dep, $pname, 'dependency group "' . $group['attribs']['name'] . '"', $params); if (is_array($ret)) { $this->_downloadDeps[] = $ret; } elseif (PEAR::isError($ret) && !isset($options['soft'])) { $this->_downloader->log(0, $ret->getMessage()); } } } else { $ret = $this->_detect2Dep($group[$packagetype], $pname, 'dependency group "' . $group['attribs']['name'] . '"', $params); if (is_array($ret)) { $this->_downloadDeps[] = $ret; } elseif (PEAR::isError($ret) && !isset($options['soft'])) { $this->_downloader->log(0, $ret->getMessage()); } } } } } function _detect2Dep($dep, $pname, $group, $params) { if (isset($dep['conflicts'])) { return true; } $options = $this->_downloader->getOptions(); if (isset($dep['uri'])) { return array('uri' => $dep['uri'], 'dep' => $dep);; } $testdep = $dep; $testdep['package'] = $dep['name']; if (PEAR_Downloader_Package::willDownload($testdep, $params)) { $dep['package'] = $dep['name']; if (!isset($options['soft'])) { $this->_downloader->log(2, $this->getShortName() . ': Skipping ' . $group . ' dependency "' . $this->_registry->parsedPackageNameToString($dep, true) . '", will be installed'); } return false; } $options = $this->_downloader->getOptions(); PEAR::pushErrorHandling(PEAR_ERROR_RETURN); if ($this->_explicitState) { $pname['state'] = $this->_explicitState; } $url = $this->_downloader->_getDepPackageDownloadUrl($dep, $pname); if (PEAR::isError($url)) { PEAR::popErrorHandling(); return $url; } $dep['package'] = $dep['name']; $ret = $this->_analyzeDownloadURL($url, 'dependency', $dep, $params, $group == 'optional' && !isset($options['alldeps']), true); PEAR::popErrorHandling(); if (PEAR::isError($ret)) { if (!isset($options['soft'])) { $this->_downloader->log(0, $ret->getMessage()); } return false; } // check to see if a dep is already installed and is the same or newer if (!isset($dep['min']) && !isset($dep['max']) && !isset($dep['recommended'])) { $oper = 'has'; } else { $oper = 'gt'; } // do not try to move this before getDepPackageDownloadURL // we can't determine whether upgrade is necessary until we know what // version would be downloaded if (!isset($options['force']) && $this->isInstalled($ret, $oper)) { $version = $this->_installRegistry->packageInfo($dep['name'], 'version', $dep['channel']); $dep['package'] = $dep['name']; if (!isset($options['soft'])) { $this->_downloader->log(3, $this->getShortName() . ': Skipping ' . $group . ' dependency "' . $this->_registry->parsedPackageNameToString($dep, true) . '" version ' . $url['version'] . ', already installed as version ' . $version); } return false; } if (isset($dep['nodefault'])) { $ret['nodefault'] = true; } return $ret; } function _detect1($deps, $pname, $options, $params) { $this->_downloadDeps = array(); $skipnames = array(); foreach ($deps as $dep) { $nodownload = false; if (isset ($dep['type']) && $dep['type'] === 'pkg') { $dep['channel'] = 'pear.php.net'; $dep['package'] = $dep['name']; switch ($dep['rel']) { case 'not' : continue 2; case 'ge' : case 'eq' : case 'gt' : case 'has' : $group = (!isset($dep['optional']) || $dep['optional'] == 'no') ? 'required' : 'optional'; if (PEAR_Downloader_Package::willDownload($dep, $params)) { $this->_downloader->log(2, $this->getShortName() . ': Skipping ' . $group . ' dependency "' . $this->_registry->parsedPackageNameToString($dep, true) . '", will be installed'); continue 2; } $fakedp = new PEAR_PackageFile_v1; $fakedp->setPackage($dep['name']); // skip internet check if we are not upgrading (bug #5810) if (!isset($options['upgrade']) && $this->isInstalled( $fakedp, $dep['rel'])) { $this->_downloader->log(2, $this->getShortName() . ': Skipping ' . $group . ' dependency "' . $this->_registry->parsedPackageNameToString($dep, true) . '", is already installed'); continue 2; } } PEAR::pushErrorHandling(PEAR_ERROR_RETURN); if ($this->_explicitState) { $pname['state'] = $this->_explicitState; } $url = $this->_downloader->_getDepPackageDownloadUrl($dep, $pname); $chan = 'pear.php.net'; if (PEAR::isError($url)) { // check to see if this is a pecl package that has jumped // from pear.php.net to pecl.php.net channel if (!class_exists('PEAR_Dependency2')) { require_once 'PEAR/Dependency2.php'; } $newdep = PEAR_Dependency2::normalizeDep($dep); $newdep = $newdep[0]; $newdep['channel'] = 'pecl.php.net'; $chan = 'pecl.php.net'; $url = $this->_downloader->_getDepPackageDownloadUrl($newdep, $pname); $obj = &$this->_installRegistry->getPackage($dep['name']); if (PEAR::isError($url)) { PEAR::popErrorHandling(); if ($obj !== null && $this->isInstalled($obj, $dep['rel'])) { $group = (!isset($dep['optional']) || $dep['optional'] == 'no') ? 'required' : 'optional'; $dep['package'] = $dep['name']; if (!isset($options['soft'])) { $this->_downloader->log(3, $this->getShortName() . ': Skipping ' . $group . ' dependency "' . $this->_registry->parsedPackageNameToString($dep, true) . '", already installed as version ' . $obj->getVersion()); } $skip = count($skipnames) ? $skipnames[count($skipnames) - 1] : ''; if ($skip == $this->_registry->parsedPackageNameToString($dep, true)) { array_pop($skipnames); } continue; } else { if (isset($dep['optional']) && $dep['optional'] == 'yes') { $this->_downloader->log(2, $this->getShortName() . ': Skipping optional dependency "' . $this->_registry->parsedPackageNameToString($dep, true) . '", no releases exist'); continue; } else { return $url; } } } } PEAR::popErrorHandling(); if (!isset($options['alldeps'])) { if (isset($dep['optional']) && $dep['optional'] == 'yes') { if (!isset($options['soft'])) { $this->_downloader->log(3, 'Notice: package "' . $this->getShortName() . '" optional dependency "' . $this->_registry->parsedPackageNameToString( array('channel' => $chan, 'package' => $dep['name']), true) . '" will not be automatically downloaded'); } $skipnames[] = $this->_registry->parsedPackageNameToString( array('channel' => $chan, 'package' => $dep['name']), true); $nodownload = true; } } if (!isset($options['alldeps']) && !isset($options['onlyreqdeps'])) { if (!isset($dep['optional']) || $dep['optional'] == 'no') { if (!isset($options['soft'])) { $this->_downloader->log(3, 'Notice: package "' . $this->getShortName() . '" required dependency "' . $this->_registry->parsedPackageNameToString( array('channel' => $chan, 'package' => $dep['name']), true) . '" will not be automatically downloaded'); } $skipnames[] = $this->_registry->parsedPackageNameToString( array('channel' => $chan, 'package' => $dep['name']), true); $nodownload = true; } } // check to see if a dep is already installed // do not try to move this before getDepPackageDownloadURL // we can't determine whether upgrade is necessary until we know what // version would be downloaded if (!isset($options['force']) && $this->isInstalled( $url, $dep['rel'])) { $group = (!isset($dep['optional']) || $dep['optional'] == 'no') ? 'required' : 'optional'; $dep['package'] = $dep['name']; if (isset($newdep)) { $version = $this->_installRegistry->packageInfo($newdep['name'], 'version', $newdep['channel']); } else { $version = $this->_installRegistry->packageInfo($dep['name'], 'version'); } $dep['version'] = $url['version']; if (!isset($options['soft'])) { $this->_downloader->log(3, $this->getShortName() . ': Skipping ' . $group . ' dependency "' . $this->_registry->parsedPackageNameToString($dep, true) . '", already installed as version ' . $version); } $skip = count($skipnames) ? $skipnames[count($skipnames) - 1] : ''; if ($skip == $this->_registry->parsedPackageNameToString($dep, true)) { array_pop($skipnames); } continue; } if ($nodownload) { continue; } PEAR::pushErrorHandling(PEAR_ERROR_RETURN); if (isset($newdep)) { $dep = $newdep; } $dep['package'] = $dep['name']; $ret = $this->_analyzeDownloadURL($url, 'dependency', $dep, $params, isset($dep['optional']) && $dep['optional'] == 'yes' && !isset($options['alldeps']), true); PEAR::popErrorHandling(); if (PEAR::isError($ret)) { if (!isset($options['soft'])) { $this->_downloader->log(0, $ret->getMessage()); } continue; } $this->_downloadDeps[] = $ret; } } if (count($skipnames)) { if (!isset($options['soft'])) { $this->_downloader->log(1, 'Did not download dependencies: ' . implode(', ', $skipnames) . ', use --alldeps or --onlyreqdeps to download automatically'); } } } function setDownloadURL($pkg) { $this->_downloadURL = $pkg; } /** * Set the package.xml object for this downloaded package * * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 $pkg */ function setPackageFile(&$pkg) { $this->_packagefile = &$pkg; } function getShortName() { return $this->_registry->parsedPackageNameToString(array('channel' => $this->getChannel(), 'package' => $this->getPackage()), true); } function getParsedPackage() { if (isset($this->_packagefile) || isset($this->_parsedname)) { return array('channel' => $this->getChannel(), 'package' => $this->getPackage(), 'version' => $this->getVersion()); } return false; } function getDownloadURL() { return $this->_downloadURL; } function canDefault() { if (isset($this->_downloadURL) && isset($this->_downloadURL['nodefault'])) { return false; } return true; } function getPackage() { if (isset($this->_packagefile)) { return $this->_packagefile->getPackage(); } elseif (isset($this->_downloadURL['info'])) { return $this->_downloadURL['info']->getPackage(); } return false; } /** * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 */ function isSubpackage(&$pf) { if (isset($this->_packagefile)) { return $this->_packagefile->isSubpackage($pf); } elseif (isset($this->_downloadURL['info'])) { return $this->_downloadURL['info']->isSubpackage($pf); } return false; } function getPackageType() { if (isset($this->_packagefile)) { return $this->_packagefile->getPackageType(); } elseif (isset($this->_downloadURL['info'])) { return $this->_downloadURL['info']->getPackageType(); } return false; } function isBundle() { if (isset($this->_packagefile)) { return $this->_packagefile->getPackageType() == 'bundle'; } return false; } function getPackageXmlVersion() { if (isset($this->_packagefile)) { return $this->_packagefile->getPackagexmlVersion(); } elseif (isset($this->_downloadURL['info'])) { return $this->_downloadURL['info']->getPackagexmlVersion(); } return '1.0'; } function getChannel() { if (isset($this->_packagefile)) { return $this->_packagefile->getChannel(); } elseif (isset($this->_downloadURL['info'])) { return $this->_downloadURL['info']->getChannel(); } return false; } function getURI() { if (isset($this->_packagefile)) { return $this->_packagefile->getURI(); } elseif (isset($this->_downloadURL['info'])) { return $this->_downloadURL['info']->getURI(); } return false; } function getVersion() { if (isset($this->_packagefile)) { return $this->_packagefile->getVersion(); } elseif (isset($this->_downloadURL['version'])) { return $this->_downloadURL['version']; } return false; } function isCompatible($pf) { if (isset($this->_packagefile)) { return $this->_packagefile->isCompatible($pf); } elseif (isset($this->_downloadURL['info'])) { return $this->_downloadURL['info']->isCompatible($pf); } return true; } function setGroup($group) { $this->_parsedname['group'] = $group; } function getGroup() { if (isset($this->_parsedname['group'])) { return $this->_parsedname['group']; } return ''; } function isExtension($name) { if (isset($this->_packagefile)) { return $this->_packagefile->isExtension($name); } elseif (isset($this->_downloadURL['info'])) { if ($this->_downloadURL['info']->getPackagexmlVersion() == '2.0') { return $this->_downloadURL['info']->getProvidesExtension() == $name; } return false; } return false; } function getDeps() { if (isset($this->_packagefile)) { $ver = $this->_packagefile->getPackagexmlVersion(); if (version_compare($ver, '2.0', '>=')) { return $this->_packagefile->getDeps(true); } return $this->_packagefile->getDeps(); } elseif (isset($this->_downloadURL['info'])) { $ver = $this->_downloadURL['info']->getPackagexmlVersion(); if (version_compare($ver, '2.0', '>=')) { return $this->_downloadURL['info']->getDeps(true); } return $this->_downloadURL['info']->getDeps(); } return array(); } /** * @param array Parsed array from {@link PEAR_Registry::parsePackageName()} or a dependency * returned from getDepDownloadURL() */ function isEqual($param) { if (is_object($param)) { $channel = $param->getChannel(); $package = $param->getPackage(); if ($param->getURI()) { $param = array( 'channel' => $param->getChannel(), 'package' => $param->getPackage(), 'version' => $param->getVersion(), 'uri' => $param->getURI(), ); } else { $param = array( 'channel' => $param->getChannel(), 'package' => $param->getPackage(), 'version' => $param->getVersion(), ); } } else { if (isset($param['uri'])) { if ($this->getChannel() != '__uri') { return false; } return $param['uri'] == $this->getURI(); } $package = isset($param['package']) ? $param['package'] : $param['info']->getPackage(); $channel = isset($param['channel']) ? $param['channel'] : $param['info']->getChannel(); if (isset($param['rel'])) { if (!class_exists('PEAR_Dependency2')) { require_once 'PEAR/Dependency2.php'; } $newdep = PEAR_Dependency2::normalizeDep($param); $newdep = $newdep[0]; } elseif (isset($param['min'])) { $newdep = $param; } } if (isset($newdep)) { if (!isset($newdep['min'])) { $newdep['min'] = '0'; } if (!isset($newdep['max'])) { $newdep['max'] = '100000000000000000000'; } // use magic to support pecl packages suddenly jumping to the pecl channel // we need to support both dependency possibilities if ($channel == 'pear.php.net' && $this->getChannel() == 'pecl.php.net') { if ($package == $this->getPackage()) { $channel = 'pecl.php.net'; } } if ($channel == 'pecl.php.net' && $this->getChannel() == 'pear.php.net') { if ($package == $this->getPackage()) { $channel = 'pear.php.net'; } } return (strtolower($package) == strtolower($this->getPackage()) && $channel == $this->getChannel() && version_compare($newdep['min'], $this->getVersion(), '<=') && version_compare($newdep['max'], $this->getVersion(), '>=')); } // use magic to support pecl packages suddenly jumping to the pecl channel if ($channel == 'pecl.php.net' && $this->getChannel() == 'pear.php.net') { if (strtolower($package) == strtolower($this->getPackage())) { $channel = 'pear.php.net'; } } if (isset($param['version'])) { return (strtolower($package) == strtolower($this->getPackage()) && $channel == $this->getChannel() && $param['version'] == $this->getVersion()); } return strtolower($package) == strtolower($this->getPackage()) && $channel == $this->getChannel(); } function isInstalled($dep, $oper = '==') { if (!$dep) { return false; } if ($oper != 'ge' && $oper != 'gt' && $oper != 'has' && $oper != '==') { return false; } if (is_object($dep)) { $package = $dep->getPackage(); $channel = $dep->getChannel(); if ($dep->getURI()) { $dep = array( 'uri' => $dep->getURI(), 'version' => $dep->getVersion(), ); } else { $dep = array( 'version' => $dep->getVersion(), ); } } else { if (isset($dep['uri'])) { $channel = '__uri'; $package = $dep['dep']['name']; } else { $channel = $dep['info']->getChannel(); $package = $dep['info']->getPackage(); } } $options = $this->_downloader->getOptions(); $test = $this->_installRegistry->packageExists($package, $channel); if (!$test && $channel == 'pecl.php.net') { // do magic to allow upgrading from old pecl packages to new ones $test = $this->_installRegistry->packageExists($package, 'pear.php.net'); $channel = 'pear.php.net'; } if ($test) { if (isset($dep['uri'])) { if ($this->_installRegistry->packageInfo($package, 'uri', '__uri') == $dep['uri']) { return true; } } if (isset($options['upgrade'])) { $packageVersion = $this->_installRegistry->packageInfo($package, 'version', $channel); if (version_compare($packageVersion, $dep['version'], '>=')) { return true; } return false; } return true; } return false; } /** * Detect duplicate package names with differing versions * * If a user requests to install Date 1.4.6 and Date 1.4.7, * for instance, this is a logic error. This method * detects this situation. * * @param array $params array of PEAR_Downloader_Package objects * @param array $errorparams empty array * @return array array of stupid duplicated packages in PEAR_Downloader_Package obejcts */ public static function detectStupidDuplicates($params, &$errorparams) { $existing = array(); foreach ($params as $i => $param) { $package = $param->getPackage(); $channel = $param->getChannel(); $group = $param->getGroup(); if (!isset($existing[$channel . '/' . $package])) { $existing[$channel . '/' . $package] = array(); } if (!isset($existing[$channel . '/' . $package][$group])) { $existing[$channel . '/' . $package][$group] = array(); } $existing[$channel . '/' . $package][$group][] = $i; } $indices = array(); foreach ($existing as $package => $groups) { foreach ($groups as $group => $dupes) { if (count($dupes) > 1) { $indices = $indices + $dupes; } } } $indices = array_unique($indices); foreach ($indices as $index) { $errorparams[] = $params[$index]; } return count($errorparams); } /** * @param array * @param bool ignore install groups - for final removal of dupe packages */ public static function removeDuplicates(&$params, $ignoreGroups = false) { $pnames = array(); foreach ($params as $i => $param) { if (!$param) { continue; } if ($param->getPackage()) { $group = $ignoreGroups ? '' : $param->getGroup(); $pnames[$i] = $param->getChannel() . '/' . $param->getPackage() . '-' . $param->getVersion() . '#' . $group; } } $pnames = array_unique($pnames); $unset = array_diff(array_keys($params), array_keys($pnames)); $testp = array_flip($pnames); foreach ($params as $i => $param) { if (!$param) { $unset[] = $i; continue; } if (!is_a($param, 'PEAR_Downloader_Package')) { $unset[] = $i; continue; } $group = $ignoreGroups ? '' : $param->getGroup(); if (!isset($testp[$param->getChannel() . '/' . $param->getPackage() . '-' . $param->getVersion() . '#' . $group])) { $unset[] = $i; } } foreach ($unset as $i) { unset($params[$i]); } $ret = array(); foreach ($params as $i => $param) { $ret[] = &$params[$i]; } $params = array(); foreach ($ret as $i => $param) { $params[] = &$ret[$i]; } } function explicitState() { return $this->_explicitState; } function setExplicitState($s) { $this->_explicitState = $s; } /** */ public static function mergeDependencies(&$params) { $bundles = $newparams = array(); foreach ($params as $i => $param) { if (!$param->isBundle()) { continue; } $bundles[] = $i; $pf = &$param->getPackageFile(); $newdeps = array(); $contents = $pf->getBundledPackages(); if (!is_array($contents)) { $contents = array($contents); } foreach ($contents as $file) { $filecontents = $pf->getFileContents($file); $dl = &$param->getDownloader(); $options = $dl->getOptions(); if (PEAR::isError($dir = $dl->getDownloadDir())) { return $dir; } $fp = @fopen($dir . DIRECTORY_SEPARATOR . $file, 'wb'); if (!$fp) { continue; } // FIXME do symlink check fwrite($fp, $filecontents, strlen($filecontents)); fclose($fp); if ($s = $params[$i]->explicitState()) { $obj->setExplicitState($s); } $obj = new PEAR_Downloader_Package($params[$i]->getDownloader()); PEAR::pushErrorHandling(PEAR_ERROR_RETURN); if (PEAR::isError($dir = $dl->getDownloadDir())) { PEAR::popErrorHandling(); return $dir; } $a = $dir . DIRECTORY_SEPARATOR . $file; $e = $obj->_fromFile($a); PEAR::popErrorHandling(); if (PEAR::isError($e)) { if (!isset($options['soft'])) { $dl->log(0, $e->getMessage()); } continue; } if (!PEAR_Downloader_Package::willDownload($obj, array_merge($params, $newparams)) && !$param->isInstalled($obj)) { $newparams[] = $obj; } } } foreach ($bundles as $i) { unset($params[$i]); // remove bundles - only their contents matter for installation } PEAR_Downloader_Package::removeDuplicates($params); // strip any unset indices if (count($newparams)) { // add in bundled packages for install foreach ($newparams as $i => $unused) { $params[] = &$newparams[$i]; } $newparams = array(); } foreach ($params as $i => $param) { $newdeps = array(); foreach ($param->_downloadDeps as $dep) { $merge = array_merge($params, $newparams); if (!PEAR_Downloader_Package::willDownload($dep, $merge) && !$param->isInstalled($dep) ) { $newdeps[] = $dep; } else { //var_dump($dep); // detect versioning conflicts here } } // convert the dependencies into PEAR_Downloader_Package objects for the next time around $params[$i]->_downloadDeps = array(); foreach ($newdeps as $dep) { $obj = new PEAR_Downloader_Package($params[$i]->getDownloader()); if ($s = $params[$i]->explicitState()) { $obj->setExplicitState($s); } PEAR::pushErrorHandling(PEAR_ERROR_RETURN); $e = $obj->fromDepURL($dep); PEAR::popErrorHandling(); if (PEAR::isError($e)) { if (!isset($options['soft'])) { $obj->_downloader->log(0, $e->getMessage()); } continue; } $e = $obj->detectDependencies($params); if (PEAR::isError($e)) { if (!isset($options['soft'])) { $obj->_downloader->log(0, $e->getMessage()); } } $newparams[] = $obj; } } if (count($newparams)) { foreach ($newparams as $i => $unused) { $params[] = &$newparams[$i]; } return true; } return false; } /** */ public static function willDownload($param, $params) { if (!is_array($params)) { return false; } foreach ($params as $obj) { if ($obj->isEqual($param)) { return true; } } return false; } /** * For simpler unit-testing * @param PEAR_Config * @param int * @param string */ function &getPackagefileObject(&$c, $d) { $a = new PEAR_PackageFile($c, $d); return $a; } /** * This will retrieve from a local file if possible, and parse out * a group name as well. The original parameter will be modified to reflect this. * @param string|array can be a parsed package name as well * @access private */ function _fromFile(&$param) { $saveparam = $param; if (is_string($param) && substr($param, 0, 10) !== 'channel://') { if (!@file_exists($param)) { $test = explode('#', $param); $group = array_pop($test); if (@file_exists(implode('#', $test))) { $this->setGroup($group); $param = implode('#', $test); $this->_explicitGroup = true; } } if (@is_file($param)) { $this->_type = 'local'; $options = $this->_downloader->getOptions(); $pkg = &$this->getPackagefileObject($this->_config, $this->_downloader->_debug); PEAR::pushErrorHandling(PEAR_ERROR_RETURN); $pf = &$pkg->fromAnyFile($param, PEAR_VALIDATE_INSTALLING); PEAR::popErrorHandling(); if (PEAR::isError($pf)) { $this->_valid = false; $param = $saveparam; return $pf; } $this->_packagefile = &$pf; if (!$this->getGroup()) { $this->setGroup('default'); // install the default dependency group } return $this->_valid = true; } } $param = $saveparam; return $this->_valid = false; } function _fromUrl($param, $saveparam = '') { if (!is_array($param) && (preg_match('#^(http|https|ftp)://#', $param))) { $options = $this->_downloader->getOptions(); $this->_type = 'url'; $callback = $this->_downloader->ui ? array(&$this->_downloader, '_downloadCallback') : null; $this->_downloader->pushErrorHandling(PEAR_ERROR_RETURN); if (PEAR::isError($dir = $this->_downloader->getDownloadDir())) { $this->_downloader->popErrorHandling(); return $dir; } $this->_downloader->log(3, 'Downloading "' . $param . '"'); $file = $this->_downloader->downloadHttp($param, $this->_downloader->ui, $dir, $callback, null, false, $this->getChannel()); $this->_downloader->popErrorHandling(); if (PEAR::isError($file)) { if (!empty($saveparam)) { $saveparam = ", cannot download \"$saveparam\""; } $err = PEAR::raiseError('Could not download from "' . $param . '"' . $saveparam . ' (' . $file->getMessage() . ')'); return $err; } if ($this->_rawpackagefile) { require_once 'Archive/Tar.php'; $tar = new Archive_Tar($file); $packagexml = $tar->extractInString('package2.xml'); if (!$packagexml) { $packagexml = $tar->extractInString('package.xml'); } if (str_replace(array("\n", "\r"), array('',''), $packagexml) != str_replace(array("\n", "\r"), array('',''), $this->_rawpackagefile)) { if ($this->getChannel() != 'pear.php.net') { return PEAR::raiseError('CRITICAL ERROR: package.xml downloaded does ' . 'not match value returned from xml-rpc'); } // be more lax for the existing PEAR packages that have not-ok // characters in their package.xml $this->_downloader->log(0, 'CRITICAL WARNING: The "' . $this->getPackage() . '" package has invalid characters in its ' . 'package.xml. The next version of PEAR may not be able to install ' . 'this package for security reasons. Please open a bug report at ' . 'http://pear.php.net/package/' . $this->getPackage() . '/bugs'); } } // whew, download worked! $pkg = &$this->getPackagefileObject($this->_config, $this->_downloader->debug); PEAR::pushErrorHandling(PEAR_ERROR_RETURN); $pf = &$pkg->fromAnyFile($file, PEAR_VALIDATE_INSTALLING); PEAR::popErrorHandling(); if (PEAR::isError($pf)) { if (is_array($pf->getUserInfo())) { foreach ($pf->getUserInfo() as $err) { if (is_array($err)) { $err = $err['message']; } if (!isset($options['soft'])) { $this->_downloader->log(0, "Validation Error: $err"); } } } if (!isset($options['soft'])) { $this->_downloader->log(0, $pf->getMessage()); } ///FIXME need to pass back some error code that we can use to match with to cancel all further operations /// At least stop all deps of this package from being installed $out = $saveparam ? $saveparam : $param; $err = PEAR::raiseError('Download of "' . $out . '" succeeded, but it is not a valid package archive'); $this->_valid = false; return $err; } $this->_packagefile = &$pf; $this->setGroup('default'); // install the default dependency group return $this->_valid = true; } return $this->_valid = false; } /** * * @param string|array pass in an array of format * array( * 'package' => 'pname', * ['channel' => 'channame',] * ['version' => 'version',] * ['state' => 'state',]) * or a string of format [channame/]pname[-version|-state] */ function _fromString($param) { $options = $this->_downloader->getOptions(); $channel = $this->_config->get('default_channel'); PEAR::pushErrorHandling(PEAR_ERROR_RETURN); $pname = $this->_registry->parsePackageName($param, $channel); PEAR::popErrorHandling(); if (PEAR::isError($pname)) { if ($pname->getCode() == 'invalid') { $this->_valid = false; return false; } if ($pname->getCode() == 'channel') { $parsed = $pname->getUserInfo(); if ($this->_downloader->discover($parsed['channel'])) { if ($this->_config->get('auto_discover')) { PEAR::pushErrorHandling(PEAR_ERROR_RETURN); $pname = $this->_registry->parsePackageName($param, $channel); PEAR::popErrorHandling(); } else { if (!isset($options['soft'])) { $this->_downloader->log(0, 'Channel "' . $parsed['channel'] . '" is not initialized, use ' . '"pear channel-discover ' . $parsed['channel'] . '" to initialize' . 'or pear config-set auto_discover 1'); } } } if (PEAR::isError($pname)) { if (!isset($options['soft'])) { $this->_downloader->log(0, $pname->getMessage()); } if (is_array($param)) { $param = $this->_registry->parsedPackageNameToString($param); } $err = PEAR::raiseError('invalid package name/package file "' . $param . '"'); $this->_valid = false; return $err; } } else { if (!isset($options['soft'])) { $this->_downloader->log(0, $pname->getMessage()); } $err = PEAR::raiseError('invalid package name/package file "' . $param . '"'); $this->_valid = false; return $err; } } if (!isset($this->_type)) { $this->_type = 'rest'; } $this->_parsedname = $pname; $this->_explicitState = isset($pname['state']) ? $pname['state'] : false; $this->_explicitGroup = isset($pname['group']) ? true : false; $info = $this->_downloader->_getPackageDownloadUrl($pname); if (PEAR::isError($info)) { if ($info->getCode() != -976 && $pname['channel'] == 'pear.php.net') { // try pecl $pname['channel'] = 'pecl.php.net'; if ($test = $this->_downloader->_getPackageDownloadUrl($pname)) { if (!PEAR::isError($test)) { $info = PEAR::raiseError($info->getMessage() . ' - package ' . $this->_registry->parsedPackageNameToString($pname, true) . ' can be installed with "pecl install ' . $pname['package'] . '"'); } else { $pname['channel'] = 'pear.php.net'; } } else { $pname['channel'] = 'pear.php.net'; } } return $info; } $this->_rawpackagefile = $info['raw']; $ret = $this->_analyzeDownloadURL($info, $param, $pname); if (PEAR::isError($ret)) { return $ret; } if ($ret) { $this->_downloadURL = $ret; return $this->_valid = (bool) $ret; } } /** * @param array output of package.getDownloadURL * @param string|array|object information for detecting packages to be downloaded, and * for errors * @param array name information of the package * @param array|null packages to be downloaded * @param bool is this an optional dependency? * @param bool is this any kind of dependency? * @access private */ function _analyzeDownloadURL($info, $param, $pname, $params = null, $optional = false, $isdependency = false) { if (!is_string($param) && PEAR_Downloader_Package::willDownload($param, $params)) { return false; } if ($info === false) { $saveparam = !is_string($param) ? ", cannot download \"$param\"" : ''; // no releases exist return PEAR::raiseError('No releases for package "' . $this->_registry->parsedPackageNameToString($pname, true) . '" exist' . $saveparam); } if (strtolower($info['info']->getChannel()) != strtolower($pname['channel'])) { $err = false; if ($pname['channel'] == 'pecl.php.net') { if ($info['info']->getChannel() != 'pear.php.net') { $err = true; } } elseif ($info['info']->getChannel() == 'pecl.php.net') { if ($pname['channel'] != 'pear.php.net') { $err = true; } } else { $err = true; } if ($err) { return PEAR::raiseError('SECURITY ERROR: package in channel "' . $pname['channel'] . '" retrieved another channel\'s name for download! ("' . $info['info']->getChannel() . '")'); } } $preferred_state = $this->_config->get('preferred_state'); if (!isset($info['url'])) { $package_version = $this->_registry->packageInfo($info['info']->getPackage(), 'version', $info['info']->getChannel()); if ($this->isInstalled($info)) { if ($isdependency && version_compare($info['version'], $package_version, '<=')) { // ignore bogus errors of "failed to download dependency" // if it is already installed and the one that would be // downloaded is older or the same version (Bug #7219) return false; } } if ($info['version'] === $package_version) { if (!isset($options['soft'])) { $this->_downloader->log(1, 'WARNING: failed to download ' . $pname['channel'] . '/' . $pname['package'] . '-' . $package_version. ', additionally the suggested version' . ' (' . $package_version . ') is the same as the locally installed one.'); } return false; } if (version_compare($info['version'], $package_version, '<=')) { if (!isset($options['soft'])) { $this->_downloader->log(1, 'WARNING: failed to download ' . $pname['channel'] . '/' . $pname['package'] . '-' . $package_version . ', additionally the suggested version' . ' (' . $info['version'] . ') is a lower version than the locally installed one (' . $package_version . ').'); } return false; } $instead = ', will instead download version ' . $info['version'] . ', stability "' . $info['info']->getState() . '"'; // releases exist, but we failed to get any if (isset($this->_downloader->_options['force'])) { if (isset($pname['version'])) { $vs = ', version "' . $pname['version'] . '"'; } elseif (isset($pname['state'])) { $vs = ', stability "' . $pname['state'] . '"'; } elseif ($param == 'dependency') { if (!class_exists('PEAR_Common')) { require_once 'PEAR/Common.php'; } if (!in_array($info['info']->getState(), PEAR_Common::betterStates($preferred_state, true))) { if ($optional) { // don't spit out confusing error message return $this->_downloader->_getPackageDownloadUrl( array('package' => $pname['package'], 'channel' => $pname['channel'], 'version' => $info['version'])); } $vs = ' within preferred state "' . $preferred_state . '"'; } else { if (!class_exists('PEAR_Dependency2')) { require_once 'PEAR/Dependency2.php'; } if ($optional) { // don't spit out confusing error message return $this->_downloader->_getPackageDownloadUrl( array('package' => $pname['package'], 'channel' => $pname['channel'], 'version' => $info['version'])); } $vs = PEAR_Dependency2::_getExtraString($pname); $instead = ''; } } else { $vs = ' within preferred state "' . $preferred_state . '"'; } if (!isset($options['soft'])) { $this->_downloader->log(1, 'WARNING: failed to download ' . $pname['channel'] . '/' . $pname['package'] . $vs . $instead); } // download the latest release return $this->_downloader->_getPackageDownloadUrl( array('package' => $pname['package'], 'channel' => $pname['channel'], 'version' => $info['version'])); } else { if (isset($info['php']) && $info['php']) { $err = PEAR::raiseError('Failed to download ' . $this->_registry->parsedPackageNameToString( array('channel' => $pname['channel'], 'package' => $pname['package']), true) . ', latest release is version ' . $info['php']['v'] . ', but it requires PHP version "' . $info['php']['m'] . '", use "' . $this->_registry->parsedPackageNameToString( array('channel' => $pname['channel'], 'package' => $pname['package'], 'version' => $info['php']['v'])) . '" to install', PEAR_DOWNLOADER_PACKAGE_PHPVERSION); return $err; } // construct helpful error message if (isset($pname['version'])) { $vs = ', version "' . $pname['version'] . '"'; } elseif (isset($pname['state'])) { $vs = ', stability "' . $pname['state'] . '"'; } elseif ($param == 'dependency') { if (!class_exists('PEAR_Common')) { require_once 'PEAR/Common.php'; } if (!in_array($info['info']->getState(), PEAR_Common::betterStates($preferred_state, true))) { if ($optional) { // don't spit out confusing error message, and don't die on // optional dep failure! return $this->_downloader->_getPackageDownloadUrl( array('package' => $pname['package'], 'channel' => $pname['channel'], 'version' => $info['version'])); } $vs = ' within preferred state "' . $preferred_state . '"'; } else { if (!class_exists('PEAR_Dependency2')) { require_once 'PEAR/Dependency2.php'; } if ($optional) { // don't spit out confusing error message, and don't die on // optional dep failure! return $this->_downloader->_getPackageDownloadUrl( array('package' => $pname['package'], 'channel' => $pname['channel'], 'version' => $info['version'])); } $vs = PEAR_Dependency2::_getExtraString($pname); } } else { $vs = ' within preferred state "' . $this->_downloader->config->get('preferred_state') . '"'; } $options = $this->_downloader->getOptions(); // this is only set by the "download-all" command if (isset($options['ignorepreferred_state'])) { $err = PEAR::raiseError( 'Failed to download ' . $this->_registry->parsedPackageNameToString( array('channel' => $pname['channel'], 'package' => $pname['package']), true) . $vs . ', latest release is version ' . $info['version'] . ', stability "' . $info['info']->getState() . '", use "' . $this->_registry->parsedPackageNameToString( array('channel' => $pname['channel'], 'package' => $pname['package'], 'version' => $info['version'])) . '" to install', PEAR_DOWNLOADER_PACKAGE_STATE); return $err; } // Checks if the user has a package installed already and checks the release against // the state against the installed package, this allows upgrades for packages // with lower stability than the preferred_state $stability = $this->_registry->packageInfo($pname['package'], 'stability', $pname['channel']); if (!$this->isInstalled($info) || !in_array($info['info']->getState(), PEAR_Common::betterStates($stability['release'], true)) ) { $err = PEAR::raiseError( 'Failed to download ' . $this->_registry->parsedPackageNameToString( array('channel' => $pname['channel'], 'package' => $pname['package']), true) . $vs . ', latest release is version ' . $info['version'] . ', stability "' . $info['info']->getState() . '", use "' . $this->_registry->parsedPackageNameToString( array('channel' => $pname['channel'], 'package' => $pname['package'], 'version' => $info['version'])) . '" to install'); return $err; } } } if (isset($info['deprecated']) && $info['deprecated']) { $this->_downloader->log(0, 'WARNING: "' . $this->_registry->parsedPackageNameToString( array('channel' => $info['info']->getChannel(), 'package' => $info['info']->getPackage()), true) . '" is deprecated in favor of "' . $this->_registry->parsedPackageNameToString($info['deprecated'], true) . '"'); } return $info; } } PKu]_00PEAR/Command.phpnu[ * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 0.1 */ /** * Needed for error handling */ require_once 'PEAR.php'; require_once 'PEAR/Frontend.php'; require_once 'PEAR/XMLParser.php'; /** * List of commands and what classes they are implemented in. * @var array command => implementing class */ $GLOBALS['_PEAR_Command_commandlist'] = array(); /** * List of commands and their descriptions * @var array command => description */ $GLOBALS['_PEAR_Command_commanddesc'] = array(); /** * List of shortcuts to common commands. * @var array shortcut => command */ $GLOBALS['_PEAR_Command_shortcuts'] = array(); /** * Array of command objects * @var array class => object */ $GLOBALS['_PEAR_Command_objects'] = array(); /** * PEAR command class, a simple factory class for administrative * commands. * * How to implement command classes: * * - The class must be called PEAR_Command_Nnn, installed in the * "PEAR/Common" subdir, with a method called getCommands() that * returns an array of the commands implemented by the class (see * PEAR/Command/Install.php for an example). * * - The class must implement a run() function that is called with three * params: * * (string) command name * (array) assoc array with options, freely defined by each * command, for example: * array('force' => true) * (array) list of the other parameters * * The run() function returns a PEAR_CommandResponse object. Use * these methods to get information: * * int getStatus() Returns PEAR_COMMAND_(SUCCESS|FAILURE|PARTIAL) * *_PARTIAL means that you need to issue at least * one more command to complete the operation * (used for example for validation steps). * * string getMessage() Returns a message for the user. Remember, * no HTML or other interface-specific markup. * * If something unexpected happens, run() returns a PEAR error. * * - DON'T OUTPUT ANYTHING! Return text for output instead. * * - DON'T USE HTML! The text you return will be used from both Gtk, * web and command-line interfaces, so for now, keep everything to * plain text. * * - DON'T USE EXIT OR DIE! Always use pear errors. From static * classes do PEAR::raiseError(), from other classes do * $this->raiseError(). * @category pear * @package PEAR * @author Stig Bakken * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 0.1 */ class PEAR_Command { // {{{ factory() /** * Get the right object for executing a command. * * @param string $command The name of the command * @param object $config Instance of PEAR_Config object * * @return object the command object or a PEAR error */ public static function &factory($command, &$config) { if (empty($GLOBALS['_PEAR_Command_commandlist'])) { PEAR_Command::registerCommands(); } if (isset($GLOBALS['_PEAR_Command_shortcuts'][$command])) { $command = $GLOBALS['_PEAR_Command_shortcuts'][$command]; } if (!isset($GLOBALS['_PEAR_Command_commandlist'][$command])) { $a = PEAR::raiseError("unknown command `$command'"); return $a; } $class = $GLOBALS['_PEAR_Command_commandlist'][$command]; if (!class_exists($class)) { require_once $GLOBALS['_PEAR_Command_objects'][$class]; } if (!class_exists($class)) { $a = PEAR::raiseError("unknown command `$command'"); return $a; } $ui =& PEAR_Command::getFrontendObject(); $obj = new $class($ui, $config); return $obj; } // }}} // {{{ & getObject() public static function &getObject($command) { $class = $GLOBALS['_PEAR_Command_commandlist'][$command]; if (!class_exists($class)) { require_once $GLOBALS['_PEAR_Command_objects'][$class]; } if (!class_exists($class)) { return PEAR::raiseError("unknown command `$command'"); } $ui =& PEAR_Command::getFrontendObject(); $config = &PEAR_Config::singleton(); $obj = new $class($ui, $config); return $obj; } // }}} // {{{ & getFrontendObject() /** * Get instance of frontend object. * * @return object|PEAR_Error */ public static function &getFrontendObject() { $a = &PEAR_Frontend::singleton(); return $a; } // }}} // {{{ & setFrontendClass() /** * Load current frontend class. * * @param string $uiclass Name of class implementing the frontend * * @return object the frontend object, or a PEAR error */ public static function &setFrontendClass($uiclass) { $a = &PEAR_Frontend::setFrontendClass($uiclass); return $a; } // }}} // {{{ setFrontendType() /** * Set current frontend. * * @param string $uitype Name of the frontend type (for example "CLI") * * @return object the frontend object, or a PEAR error */ public static function setFrontendType($uitype) { $uiclass = 'PEAR_Frontend_' . $uitype; return PEAR_Command::setFrontendClass($uiclass); } // }}} // {{{ registerCommands() /** * Scan through the Command directory looking for classes * and see what commands they implement. * * @param bool (optional) if FALSE (default), the new list of * commands should replace the current one. If TRUE, * new entries will be merged with old. * * @param string (optional) where (what directory) to look for * classes, defaults to the Command subdirectory of * the directory from where this file (__FILE__) is * included. * * @return bool TRUE on success, a PEAR error on failure */ public static function registerCommands($merge = false, $dir = null) { $parser = new PEAR_XMLParser; if ($dir === null) { $dir = dirname(__FILE__) . '/Command'; } if (!is_dir($dir)) { return PEAR::raiseError("registerCommands: opendir($dir) '$dir' does not exist or is not a directory"); } $dp = @opendir($dir); if (empty($dp)) { return PEAR::raiseError("registerCommands: opendir($dir) failed"); } if (!$merge) { $GLOBALS['_PEAR_Command_commandlist'] = array(); } while ($file = readdir($dp)) { if ($file[0] == '.' || substr($file, -4) != '.xml') { continue; } $f = substr($file, 0, -4); $class = "PEAR_Command_" . $f; // List of commands if (empty($GLOBALS['_PEAR_Command_objects'][$class])) { $GLOBALS['_PEAR_Command_objects'][$class] = "$dir/" . $f . '.php'; } $parser->parse(file_get_contents("$dir/$file")); $implements = $parser->getData(); foreach ($implements as $command => $desc) { if ($command == 'attribs') { continue; } if (isset($GLOBALS['_PEAR_Command_commandlist'][$command])) { return PEAR::raiseError('Command "' . $command . '" already registered in ' . 'class "' . $GLOBALS['_PEAR_Command_commandlist'][$command] . '"'); } $GLOBALS['_PEAR_Command_commandlist'][$command] = $class; $GLOBALS['_PEAR_Command_commanddesc'][$command] = $desc['summary']; if (isset($desc['shortcut'])) { $shortcut = $desc['shortcut']; if (isset($GLOBALS['_PEAR_Command_shortcuts'][$shortcut])) { return PEAR::raiseError('Command shortcut "' . $shortcut . '" already ' . 'registered to command "' . $command . '" in class "' . $GLOBALS['_PEAR_Command_commandlist'][$command] . '"'); } $GLOBALS['_PEAR_Command_shortcuts'][$shortcut] = $command; } if (isset($desc['options']) && $desc['options']) { foreach ($desc['options'] as $oname => $option) { if (isset($option['shortopt']) && strlen($option['shortopt']) > 1) { return PEAR::raiseError('Option "' . $oname . '" short option "' . $option['shortopt'] . '" must be ' . 'only 1 character in Command "' . $command . '" in class "' . $class . '"'); } } } } } ksort($GLOBALS['_PEAR_Command_shortcuts']); ksort($GLOBALS['_PEAR_Command_commandlist']); @closedir($dp); return true; } // }}} // {{{ getCommands() /** * Get the list of currently supported commands, and what * classes implement them. * * @return array command => implementing class */ public static function getCommands() { if (empty($GLOBALS['_PEAR_Command_commandlist'])) { PEAR_Command::registerCommands(); } return $GLOBALS['_PEAR_Command_commandlist']; } // }}} // {{{ getShortcuts() /** * Get the list of command shortcuts. * * @return array shortcut => command */ public static function getShortcuts() { if (empty($GLOBALS['_PEAR_Command_shortcuts'])) { PEAR_Command::registerCommands(); } return $GLOBALS['_PEAR_Command_shortcuts']; } // }}} // {{{ getGetoptArgs() /** * Compiles arguments for getopt. * * @param string $command command to get optstring for * @param string $short_args (reference) short getopt format * @param array $long_args (reference) long getopt format * * @return void */ public static function getGetoptArgs($command, &$short_args, &$long_args) { if (empty($GLOBALS['_PEAR_Command_commandlist'])) { PEAR_Command::registerCommands(); } if (isset($GLOBALS['_PEAR_Command_shortcuts'][$command])) { $command = $GLOBALS['_PEAR_Command_shortcuts'][$command]; } if (!isset($GLOBALS['_PEAR_Command_commandlist'][$command])) { return null; } $obj = &PEAR_Command::getObject($command); return $obj->getGetoptArgs($command, $short_args, $long_args); } // }}} // {{{ getDescription() /** * Get description for a command. * * @param string $command Name of the command * * @return string command description */ public static function getDescription($command) { if (!isset($GLOBALS['_PEAR_Command_commanddesc'][$command])) { return null; } return $GLOBALS['_PEAR_Command_commanddesc'][$command]; } // }}} // {{{ getHelp() /** * Get help for command. * * @param string $command Name of the command to return help for */ public static function getHelp($command) { $cmds = PEAR_Command::getCommands(); if (isset($GLOBALS['_PEAR_Command_shortcuts'][$command])) { $command = $GLOBALS['_PEAR_Command_shortcuts'][$command]; } if (isset($cmds[$command])) { $obj = &PEAR_Command::getObject($command); return $obj->getHelp($command); } return false; } // }}} }PKu]^D{  PEAR/Installer/Role/Www.phpnu[ * @copyright 2007-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 1.7.0 */ /** * @category pear * @package PEAR * @author Greg Beaver * @copyright 2007-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.7.0 */ class PEAR_Installer_Role_Www extends PEAR_Installer_Role_Common {} ?>PKu]YPEAR/Installer/Role/Test.phpnu[ * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ /** * @category pear * @package PEAR * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ class PEAR_Installer_Role_Test extends PEAR_Installer_Role_Common {} ?>PKu]0cPEAR/Installer/Role/Man.xmlnu[ php extsrc extbin zendextsrc zendextbin 1 man_dir 1 PKu]/PEAR/Installer/Role/Cfg.xmlnu[ php extsrc extbin zendextsrc zendextbin 1 cfg_dir 1 PKu]BBPEAR/Installer/Role/Ext.xmlnu[ extbin zendextbin 1 ext_dir 1 1 PKu]?m  PEAR/Installer/Role/Php.phpnu[ * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ /** * @category pear * @package PEAR * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ class PEAR_Installer_Role_Php extends PEAR_Installer_Role_Common {} ?>PKu]@vаPEAR/Installer/Role/Script.xmlnu[ php extsrc extbin zendextsrc zendextbin 1 bin_dir 1 1 PKu][PEAR/Installer/Role/Script.phpnu[ * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ /** * @category pear * @package PEAR * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ class PEAR_Installer_Role_Script extends PEAR_Installer_Role_Common {} ?>PKu]h&P*PEAR/Installer/Role/Doc.xmlnu[ php extsrc extbin zendextsrc zendextbin 1 doc_dir PKu]>1HPEAR/Installer/Role/Www.xmlnu[ php extsrc extbin zendextsrc zendextbin 1 www_dir 1 PKu]K  PEAR/Installer/Role/Ext.phpnu[ * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ /** * @category pear * @package PEAR * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ class PEAR_Installer_Role_Ext extends PEAR_Installer_Role_Common {} ?>PKu]B] PEAR/Installer/Role/Test.xmlnu[ php extsrc extbin zendextsrc zendextbin 1 test_dir PKu]*Y| %%PEAR/Installer/Role/Man.phpnu[ * @copyright 2011 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id: $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.10.0 */ /** * @category pear * @package PEAR * @author Hannes Magnusson * @copyright 2011 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.10.0 */ class PEAR_Installer_Role_Man extends PEAR_Installer_Role_Common {} ?> PKu]fszPEAR/Installer/Role/Data.xmlnu[ php extsrc extbin zendextsrc zendextbin 1 data_dir PKu]zqPEAR/Installer/Role/Php.xmlnu[ php extsrc extbin zendextsrc zendextbin 1 php_dir 1 1 PKu]p""PEAR/Installer/Role/Src.xmlnu[ extsrc zendextsrc 1 temp_dir PKu]  PEAR/Installer/Role/Doc.phpnu[ * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ /** * @category pear * @package PEAR * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ class PEAR_Installer_Role_Doc extends PEAR_Installer_Role_Common {} ?>PKu]?GGPEAR/Installer/Role/Common.phpnu[ * @copyright 1997-2006 The PHP Group * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ /** * Base class for all installation roles. * * This class allows extensibility of file roles. Packages with complex * customization can now provide custom file roles along with the possibility of * adding configuration values to match. * @category pear * @package PEAR * @author Greg Beaver * @copyright 1997-2006 The PHP Group * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ class PEAR_Installer_Role_Common { /** * @var PEAR_Config * @access protected */ var $config; /** * @param PEAR_Config */ function __construct(&$config) { $this->config = $config; } /** * Retrieve configuration information about a file role from its XML info * * @param string $role Role Classname, as in "PEAR_Installer_Role_Data" * @return array */ function getInfo($role) { if (empty($GLOBALS['_PEAR_INSTALLER_ROLES'][$role])) { return PEAR::raiseError('Unknown Role class: "' . $role . '"'); } return $GLOBALS['_PEAR_INSTALLER_ROLES'][$role]; } /** * This is called for each file to set up the directories and files * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 * @param array attributes from the tag * @param string file name * @return array an array consisting of: * * 1 the original, pre-baseinstalldir installation directory * 2 the final installation directory * 3 the full path to the final location of the file * 4 the location of the pre-installation file */ function processInstallation($pkg, $atts, $file, $tmp_path, $layer = null) { $roleInfo = PEAR_Installer_Role_Common::getInfo('PEAR_Installer_Role_' . ucfirst(str_replace('pear_installer_role_', '', strtolower(get_class($this))))); if (PEAR::isError($roleInfo)) { return $roleInfo; } if (!$roleInfo['locationconfig']) { return false; } if ($roleInfo['honorsbaseinstall']) { $dest_dir = $save_destdir = $this->config->get($roleInfo['locationconfig'], $layer, $pkg->getChannel()); if (!empty($atts['baseinstalldir'])) { $dest_dir .= DIRECTORY_SEPARATOR . $atts['baseinstalldir']; } } elseif ($roleInfo['unusualbaseinstall']) { $dest_dir = $save_destdir = $this->config->get($roleInfo['locationconfig'], $layer, $pkg->getChannel()) . DIRECTORY_SEPARATOR . $pkg->getPackage(); if (!empty($atts['baseinstalldir'])) { $dest_dir .= DIRECTORY_SEPARATOR . $atts['baseinstalldir']; } } else { $dest_dir = $save_destdir = $this->config->get($roleInfo['locationconfig'], $layer, $pkg->getChannel()) . DIRECTORY_SEPARATOR . $pkg->getPackage(); } if (dirname($file) != '.' && empty($atts['install-as'])) { $dest_dir .= DIRECTORY_SEPARATOR . dirname($file); } if (empty($atts['install-as'])) { $dest_file = $dest_dir . DIRECTORY_SEPARATOR . basename($file); } else { $dest_file = $dest_dir . DIRECTORY_SEPARATOR . $atts['install-as']; } $orig_file = $tmp_path . DIRECTORY_SEPARATOR . $file; // Clean up the DIRECTORY_SEPARATOR mess $ds2 = DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR; list($dest_dir, $dest_file, $orig_file) = preg_replace(array('!\\\\+!', '!/!', "!$ds2+!"), array(DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR), array($dest_dir, $dest_file, $orig_file)); return array($save_destdir, $dest_dir, $dest_file, $orig_file); } /** * Get the name of the configuration variable that specifies the location of this file * @return string|false */ function getLocationConfig() { $roleInfo = PEAR_Installer_Role_Common::getInfo('PEAR_Installer_Role_' . ucfirst(str_replace('pear_installer_role_', '', strtolower(get_class($this))))); if (PEAR::isError($roleInfo)) { return $roleInfo; } return $roleInfo['locationconfig']; } /** * Do any unusual setup here * @param PEAR_Installer * @param PEAR_PackageFile_v2 * @param array file attributes * @param string file name */ function setup(&$installer, $pkg, $atts, $file) { } function isExecutable() { $roleInfo = PEAR_Installer_Role_Common::getInfo('PEAR_Installer_Role_' . ucfirst(str_replace('pear_installer_role_', '', strtolower(get_class($this))))); if (PEAR::isError($roleInfo)) { return $roleInfo; } return $roleInfo['executable']; } function isInstallable() { $roleInfo = PEAR_Installer_Role_Common::getInfo('PEAR_Installer_Role_' . ucfirst(str_replace('pear_installer_role_', '', strtolower(get_class($this))))); if (PEAR::isError($roleInfo)) { return $roleInfo; } return $roleInfo['installable']; } function isExtension() { $roleInfo = PEAR_Installer_Role_Common::getInfo('PEAR_Installer_Role_' . ucfirst(str_replace('pear_installer_role_', '', strtolower(get_class($this))))); if (PEAR::isError($roleInfo)) { return $roleInfo; } return $roleInfo['phpextension']; } } ?> PKu]ƤPEAR/Installer/Role/Cfg.phpnu[ * @copyright 2007-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 1.7.0 */ /** * @category pear * @package PEAR * @author Greg Beaver * @copyright 2007-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.7.0 */ class PEAR_Installer_Role_Cfg extends PEAR_Installer_Role_Common { /** * @var PEAR_Installer */ var $installer; /** * the md5 of the original file * * @var unknown_type */ var $md5 = null; /** * Do any unusual setup here * @param PEAR_Installer * @param PEAR_PackageFile_v2 * @param array file attributes * @param string file name */ function setup(&$installer, $pkg, $atts, $file) { $this->installer = &$installer; $reg = &$this->installer->config->getRegistry(); $package = $reg->getPackage($pkg->getPackage(), $pkg->getChannel()); if ($package) { $filelist = $package->getFilelist(); if (isset($filelist[$file]) && isset($filelist[$file]['md5sum'])) { $this->md5 = $filelist[$file]['md5sum']; } } } function processInstallation($pkg, $atts, $file, $tmp_path, $layer = null) { $test = parent::processInstallation($pkg, $atts, $file, $tmp_path, $layer); if (@file_exists($test[2]) && @file_exists($test[3])) { $md5 = md5_file($test[2]); // configuration has already been installed, check for mods if ($md5 !== $this->md5 && $md5 !== md5_file($test[3])) { // configuration has been modified, so save our version as // configfile-version $old = $test[2]; $test[2] .= '.new-' . $pkg->getVersion(); // backup original and re-install it PEAR::pushErrorHandling(PEAR_ERROR_RETURN); $tmpcfg = $this->config->get('temp_dir'); $newloc = System::mkdir(array('-p', $tmpcfg)); if (!$newloc) { // try temp_dir $newloc = System::mktemp(array('-d')); if (!$newloc || PEAR::isError($newloc)) { PEAR::popErrorHandling(); return PEAR::raiseError('Could not save existing configuration file '. $old . ', unable to install. Please set temp_dir ' . 'configuration variable to a writeable location and try again'); } } else { $newloc = $tmpcfg; } $temp_file = $newloc . DIRECTORY_SEPARATOR . uniqid('savefile'); if (!@copy($old, $temp_file)) { PEAR::popErrorHandling(); return PEAR::raiseError('Could not save existing configuration file '. $old . ', unable to install. Please set temp_dir ' . 'configuration variable to a writeable location and try again'); } PEAR::popErrorHandling(); $this->installer->log(0, "WARNING: configuration file $old is being installed as $test[2], you should manually merge in changes to the existing configuration file"); $this->installer->addFileOperation('rename', array($temp_file, $old, false)); $this->installer->addFileOperation('delete', array($temp_file)); } } return $test; } }PKu]srrPEAR/Installer/Role/Src.phpnu[ * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ /** * @category pear * @package PEAR * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ class PEAR_Installer_Role_Src extends PEAR_Installer_Role_Common { function setup(&$installer, $pkg, $atts, $file) { $installer->source_files++; } } ?>PKu] PEAR/Installer/Role/Data.phpnu[ * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ /** * @category pear * @package PEAR * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ class PEAR_Installer_Role_Data extends PEAR_Installer_Role_Common {} ?>PKu]VZPEAR/Installer/Role.phpnu[ * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ /** * base class for installer roles */ require_once 'PEAR/Installer/Role/Common.php'; require_once 'PEAR/XMLParser.php'; /** * @category pear * @package PEAR * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ class PEAR_Installer_Role { /** * Set up any additional configuration variables that file roles require * * Never call this directly, it is called by the PEAR_Config constructor * @param PEAR_Config */ public static function initializeConfig(&$config) { if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) { PEAR_Installer_Role::registerRoles(); } foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $class => $info) { if (!$info['config_vars']) { continue; } $config->_addConfigVars($class, $info['config_vars']); } } /** * @param PEAR_PackageFile_v2 * @param string role name * @param PEAR_Config * @return PEAR_Installer_Role_Common */ public static function &factory($pkg, $role, &$config) { if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) { PEAR_Installer_Role::registerRoles(); } if (!in_array($role, PEAR_Installer_Role::getValidRoles($pkg->getPackageType()))) { $a = false; return $a; } $a = 'PEAR_Installer_Role_' . ucfirst($role); if (!class_exists($a)) { require_once str_replace('_', '/', $a) . '.php'; } $b = new $a($config); return $b; } /** * Get a list of file roles that are valid for the particular release type. * * For instance, src files serve no purpose in regular php releases. * @param string * @param bool clear cache * @return array */ public static function getValidRoles($release, $clear = false) { if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) { PEAR_Installer_Role::registerRoles(); } static $ret = array(); if ($clear) { $ret = array(); } if (isset($ret[$release])) { return $ret[$release]; } $ret[$release] = array(); foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $role => $okreleases) { if (in_array($release, $okreleases['releasetypes'])) { $ret[$release][] = strtolower(str_replace('PEAR_Installer_Role_', '', $role)); } } return $ret[$release]; } /** * Get a list of roles that require their files to be installed * * Most roles must be installed, but src and package roles, for instance * are pseudo-roles. src files are compiled into a new extension. Package * roles are actually fully bundled releases of a package * @param bool clear cache * @return array */ public static function getInstallableRoles($clear = false) { if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) { PEAR_Installer_Role::registerRoles(); } static $ret; if ($clear) { unset($ret); } if (isset($ret)) { return $ret; } $ret = array(); foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $role => $okreleases) { if ($okreleases['installable']) { $ret[] = strtolower(str_replace('PEAR_Installer_Role_', '', $role)); } } return $ret; } /** * Return an array of roles that are affected by the baseinstalldir attribute * * Most roles ignore this attribute, and instead install directly into: * PackageName/filepath * so a tests file tests/file.phpt is installed into PackageName/tests/filepath.php * @param bool clear cache * @return array */ public static function getBaseinstallRoles($clear = false) { if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) { PEAR_Installer_Role::registerRoles(); } static $ret; if ($clear) { unset($ret); } if (isset($ret)) { return $ret; } $ret = array(); foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $role => $okreleases) { if ($okreleases['honorsbaseinstall']) { $ret[] = strtolower(str_replace('PEAR_Installer_Role_', '', $role)); } } return $ret; } /** * Return an array of file roles that should be analyzed for PHP content at package time, * like the "php" role. * @param bool clear cache * @return array */ public static function getPhpRoles($clear = false) { if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) { PEAR_Installer_Role::registerRoles(); } static $ret; if ($clear) { unset($ret); } if (isset($ret)) { return $ret; } $ret = array(); foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $role => $okreleases) { if ($okreleases['phpfile']) { $ret[] = strtolower(str_replace('PEAR_Installer_Role_', '', $role)); } } return $ret; } /** * Scan through the Command directory looking for classes * and see what commands they implement. * @param string which directory to look for classes, defaults to * the Installer/Roles subdirectory of * the directory from where this file (__FILE__) is * included. * * @return bool TRUE on success, a PEAR error on failure */ public static function registerRoles($dir = null) { $GLOBALS['_PEAR_INSTALLER_ROLES'] = array(); $parser = new PEAR_XMLParser; if ($dir === null) { $dir = dirname(__FILE__) . '/Role'; } if (!file_exists($dir) || !is_dir($dir)) { return PEAR::raiseError("registerRoles: opendir($dir) failed: does not exist/is not directory"); } $dp = @opendir($dir); if (empty($dp)) { return PEAR::raiseError("registerRoles: opendir($dir) failed: $php_errmsg"); } while ($entry = readdir($dp)) { if ($entry[0] == '.' || substr($entry, -4) != '.xml') { continue; } $class = "PEAR_Installer_Role_".substr($entry, 0, -4); // List of roles if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'][$class])) { $file = "$dir/$entry"; $parser->parse(file_get_contents($file)); $data = $parser->getData(); if (!is_array($data['releasetypes'])) { $data['releasetypes'] = array($data['releasetypes']); } $GLOBALS['_PEAR_INSTALLER_ROLES'][$class] = $data; } } closedir($dp); ksort($GLOBALS['_PEAR_INSTALLER_ROLES']); PEAR_Installer_Role::getBaseinstallRoles(true); PEAR_Installer_Role::getInstallableRoles(true); PEAR_Installer_Role::getPhpRoles(true); PEAR_Installer_Role::getValidRoles('****', true); return true; } }PKu]،wPEAR/Installer.phpnu[ * @author Tomas V.V. Cox * @author Martin Jansen * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 0.1 */ /** * Used for installation groups in package.xml 2.0 and platform exceptions */ require_once 'OS/Guess.php'; require_once 'PEAR/Downloader.php'; define('PEAR_INSTALLER_NOBINARY', -240); /** * Administration class used to install PEAR packages and maintain the * installed package database. * * @category pear * @package PEAR * @author Stig Bakken * @author Tomas V.V. Cox * @author Martin Jansen * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 0.1 */ class PEAR_Installer extends PEAR_Downloader { // {{{ properties /** name of the package directory, for example Foo-1.0 * @var string */ var $pkgdir; /** directory where PHP code files go * @var string */ var $phpdir; /** directory where PHP extension files go * @var string */ var $extdir; /** directory where documentation goes * @var string */ var $docdir; /** installation root directory (ala PHP's INSTALL_ROOT or * automake's DESTDIR * @var string */ var $installroot = ''; /** debug level * @var int */ var $debug = 1; /** temporary directory * @var string */ var $tmpdir; /** * PEAR_Registry object used by the installer * @var PEAR_Registry */ var $registry; /** * array of PEAR_Downloader_Packages * @var array */ var $_downloadedPackages; /** List of file transactions queued for an install/upgrade/uninstall. * * Format: * array( * 0 => array("rename => array("from-file", "to-file")), * 1 => array("delete" => array("file-to-delete")), * ... * ) * * @var array */ var $file_operations = array(); // }}} // {{{ constructor /** * PEAR_Installer constructor. * * @param object $ui user interface object (instance of PEAR_Frontend_*) * * @access public */ function __construct(&$ui) { parent::__construct($ui, array(), null); $this->setFrontendObject($ui); $this->debug = $this->config->get('verbose'); } function setOptions($options) { $this->_options = $options; } function setConfig(&$config) { $this->config = &$config; $this->_registry = &$config->getRegistry(); } // }}} function _removeBackups($files) { foreach ($files as $path) { $this->addFileOperation('removebackup', array($path)); } } // {{{ _deletePackageFiles() /** * Delete a package's installed files, does not remove empty directories. * * @param string package name * @param string channel name * @param bool if true, then files are backed up first * @return bool TRUE on success, or a PEAR error on failure * @access protected */ function _deletePackageFiles($package, $channel = false, $backup = false) { if (!$channel) { $channel = 'pear.php.net'; } if (!strlen($package)) { return $this->raiseError("No package to uninstall given"); } if (strtolower($package) == 'pear' && $channel == 'pear.php.net') { // to avoid race conditions, include all possible needed files require_once 'PEAR/Task/Common.php'; require_once 'PEAR/Task/Replace.php'; require_once 'PEAR/Task/Unixeol.php'; require_once 'PEAR/Task/Windowseol.php'; require_once 'PEAR/PackageFile/v1.php'; require_once 'PEAR/PackageFile/v2.php'; require_once 'PEAR/PackageFile/Generator/v1.php'; require_once 'PEAR/PackageFile/Generator/v2.php'; } $filelist = $this->_registry->packageInfo($package, 'filelist', $channel); if ($filelist == null) { return $this->raiseError("$channel/$package not installed"); } $ret = array(); foreach ($filelist as $file => $props) { if (empty($props['installed_as'])) { continue; } $path = $props['installed_as']; if ($backup) { $this->addFileOperation('backup', array($path)); $ret[] = $path; } $this->addFileOperation('delete', array($path)); } if ($backup) { return $ret; } return true; } // }}} // {{{ _installFile() /** * @param string filename * @param array attributes from tag in package.xml * @param string path to install the file in * @param array options from command-line * @access private */ function _installFile($file, $atts, $tmp_path, $options) { // {{{ return if this file is meant for another platform static $os; if (!isset($this->_registry)) { $this->_registry = &$this->config->getRegistry(); } if (isset($atts['platform'])) { if (empty($os)) { $os = new OS_Guess(); } if (strlen($atts['platform']) && $atts['platform'][0] == '!') { $negate = true; $platform = substr($atts['platform'], 1); } else { $negate = false; $platform = $atts['platform']; } if ((bool) $os->matchSignature($platform) === $negate) { $this->log(3, "skipped $file (meant for $atts[platform], we are ".$os->getSignature().")"); return PEAR_INSTALLER_SKIPPED; } } // }}} $channel = $this->pkginfo->getChannel(); // {{{ assemble the destination paths switch ($atts['role']) { case 'src': case 'extsrc': $this->source_files++; return; case 'doc': case 'data': case 'test': $dest_dir = $this->config->get($atts['role'] . '_dir', null, $channel) . DIRECTORY_SEPARATOR . $this->pkginfo->getPackage(); unset($atts['baseinstalldir']); break; case 'ext': case 'php': $dest_dir = $this->config->get($atts['role'] . '_dir', null, $channel); break; case 'script': $dest_dir = $this->config->get('bin_dir', null, $channel); break; default: return $this->raiseError("Invalid role `$atts[role]' for file $file"); } $save_destdir = $dest_dir; if (!empty($atts['baseinstalldir'])) { $dest_dir .= DIRECTORY_SEPARATOR . $atts['baseinstalldir']; } if (dirname($file) != '.' && empty($atts['install-as'])) { $dest_dir .= DIRECTORY_SEPARATOR . dirname($file); } if (empty($atts['install-as'])) { $dest_file = $dest_dir . DIRECTORY_SEPARATOR . basename($file); } else { $dest_file = $dest_dir . DIRECTORY_SEPARATOR . $atts['install-as']; } $orig_file = $tmp_path . DIRECTORY_SEPARATOR . $file; // Clean up the DIRECTORY_SEPARATOR mess $ds2 = DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR; list($dest_file, $orig_file) = preg_replace(array('!\\\\+!', '!/!', "!$ds2+!"), array(DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR), array($dest_file, $orig_file)); $final_dest_file = $installed_as = $dest_file; if (isset($this->_options['packagingroot'])) { $installedas_dest_dir = dirname($final_dest_file); $installedas_dest_file = $dest_dir . DIRECTORY_SEPARATOR . '.tmp' . basename($final_dest_file); $final_dest_file = $this->_prependPath($final_dest_file, $this->_options['packagingroot']); } else { $installedas_dest_dir = dirname($final_dest_file); $installedas_dest_file = $installedas_dest_dir . DIRECTORY_SEPARATOR . '.tmp' . basename($final_dest_file); } $dest_dir = dirname($final_dest_file); $dest_file = $dest_dir . DIRECTORY_SEPARATOR . '.tmp' . basename($final_dest_file); if (preg_match('~/\.\.(/|\\z)|^\.\./~', str_replace('\\', '/', $dest_file))) { return $this->raiseError("SECURITY ERROR: file $file (installed to $dest_file) contains parent directory reference ..", PEAR_INSTALLER_FAILED); } // }}} if (empty($this->_options['register-only']) && (!file_exists($dest_dir) || !is_dir($dest_dir))) { if (!$this->mkDirHier($dest_dir)) { return $this->raiseError("failed to mkdir $dest_dir", PEAR_INSTALLER_FAILED); } $this->log(3, "+ mkdir $dest_dir"); } // pretty much nothing happens if we are only registering the install if (empty($this->_options['register-only'])) { if (empty($atts['replacements'])) { if (!file_exists($orig_file)) { return $this->raiseError("file $orig_file does not exist", PEAR_INSTALLER_FAILED); } if (!@copy($orig_file, $dest_file)) { return $this->raiseError( "failed to write $dest_file: " . error_get_last()["message"], PEAR_INSTALLER_FAILED); } $this->log(3, "+ cp $orig_file $dest_file"); if (isset($atts['md5sum'])) { $md5sum = md5_file($dest_file); } } else { // {{{ file with replacements if (!file_exists($orig_file)) { return $this->raiseError("file does not exist", PEAR_INSTALLER_FAILED); } $contents = file_get_contents($orig_file); if ($contents === false) { $contents = ''; } if (isset($atts['md5sum'])) { $md5sum = md5($contents); } $subst_from = $subst_to = array(); foreach ($atts['replacements'] as $a) { $to = ''; if ($a['type'] == 'php-const') { if (preg_match('/^[a-z0-9_]+\\z/i', $a['to'])) { eval("\$to = $a[to];"); } else { if (!isset($options['soft'])) { $this->log(0, "invalid php-const replacement: $a[to]"); } continue; } } elseif ($a['type'] == 'pear-config') { if ($a['to'] == 'master_server') { $chan = $this->_registry->getChannel($channel); if (!PEAR::isError($chan)) { $to = $chan->getServer(); } else { $to = $this->config->get($a['to'], null, $channel); } } else { $to = $this->config->get($a['to'], null, $channel); } if (is_null($to)) { if (!isset($options['soft'])) { $this->log(0, "invalid pear-config replacement: $a[to]"); } continue; } } elseif ($a['type'] == 'package-info') { if ($t = $this->pkginfo->packageInfo($a['to'])) { $to = $t; } else { if (!isset($options['soft'])) { $this->log(0, "invalid package-info replacement: $a[to]"); } continue; } } if (!is_null($to)) { $subst_from[] = $a['from']; $subst_to[] = $to; } } $this->log(3, "doing ".sizeof($subst_from)." substitution(s) for $final_dest_file"); if (sizeof($subst_from)) { $contents = str_replace($subst_from, $subst_to, $contents); } $wp = @fopen($dest_file, "wb"); if (!is_resource($wp)) { return $this->raiseError( "failed to create $dest_file: " . error_get_last()["message"], PEAR_INSTALLER_FAILED); } if (@fwrite($wp, $contents) === false) { return $this->raiseError( "failed writing to $dest_file: " . error_get_last()["message"], PEAR_INSTALLER_FAILED); } fclose($wp); // }}} } // {{{ check the md5 if (isset($md5sum)) { if (strtolower($md5sum) === strtolower($atts['md5sum'])) { $this->log(2, "md5sum ok: $final_dest_file"); } else { if (empty($options['force'])) { // delete the file if (file_exists($dest_file)) { unlink($dest_file); } if (!isset($options['ignore-errors'])) { return $this->raiseError("bad md5sum for file $final_dest_file", PEAR_INSTALLER_FAILED); } if (!isset($options['soft'])) { $this->log(0, "warning : bad md5sum for file $final_dest_file"); } } else { if (!isset($options['soft'])) { $this->log(0, "warning : bad md5sum for file $final_dest_file"); } } } } // }}} // {{{ set file permissions if (!OS_WINDOWS) { if ($atts['role'] == 'script') { $mode = 0777 & ~(int)octdec($this->config->get('umask')); $this->log(3, "+ chmod +x $dest_file"); } else { $mode = 0666 & ~(int)octdec($this->config->get('umask')); } if ($atts['role'] != 'src') { $this->addFileOperation("chmod", array($mode, $dest_file)); if (!@chmod($dest_file, $mode)) { if (!isset($options['soft'])) { $this->log(0, "failed to change mode of $dest_file: " . error_get_last()["message"]); } } } } // }}} if ($atts['role'] == 'src') { rename($dest_file, $final_dest_file); $this->log(2, "renamed source file $dest_file to $final_dest_file"); } else { $this->addFileOperation("rename", array($dest_file, $final_dest_file, $atts['role'] == 'ext')); } } // Store the full path where the file was installed for easy unistall if ($atts['role'] != 'script') { $loc = $this->config->get($atts['role'] . '_dir'); } else { $loc = $this->config->get('bin_dir'); } if ($atts['role'] != 'src') { $this->addFileOperation("installed_as", array($file, $installed_as, $loc, dirname(substr($installedas_dest_file, strlen($loc))))); } //$this->log(2, "installed: $dest_file"); return PEAR_INSTALLER_OK; } // }}} // {{{ _installFile2() /** * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 * @param string filename * @param array attributes from tag in package.xml * @param string path to install the file in * @param array options from command-line * @access private */ function _installFile2(&$pkg, $file, &$real_atts, $tmp_path, $options) { $atts = $real_atts; if (!isset($this->_registry)) { $this->_registry = &$this->config->getRegistry(); } $channel = $pkg->getChannel(); // {{{ assemble the destination paths if (!in_array($atts['attribs']['role'], PEAR_Installer_Role::getValidRoles($pkg->getPackageType()))) { return $this->raiseError('Invalid role `' . $atts['attribs']['role'] . "' for file $file"); } $role = &PEAR_Installer_Role::factory($pkg, $atts['attribs']['role'], $this->config); $err = $role->setup($this, $pkg, $atts['attribs'], $file); if (PEAR::isError($err)) { return $err; } if (!$role->isInstallable()) { return; } $info = $role->processInstallation($pkg, $atts['attribs'], $file, $tmp_path); if (PEAR::isError($info)) { return $info; } list($save_destdir, $dest_dir, $dest_file, $orig_file) = $info; if (preg_match('~/\.\.(/|\\z)|^\.\./~', str_replace('\\', '/', $dest_file))) { return $this->raiseError("SECURITY ERROR: file $file (installed to $dest_file) contains parent directory reference ..", PEAR_INSTALLER_FAILED); } $final_dest_file = $installed_as = $dest_file; if (isset($this->_options['packagingroot'])) { $final_dest_file = $this->_prependPath($final_dest_file, $this->_options['packagingroot']); } $dest_dir = dirname($final_dest_file); $dest_file = $dest_dir . DIRECTORY_SEPARATOR . '.tmp' . basename($final_dest_file); // }}} if (empty($this->_options['register-only'])) { if (!file_exists($dest_dir) || !is_dir($dest_dir)) { if (!$this->mkDirHier($dest_dir)) { return $this->raiseError("failed to mkdir $dest_dir", PEAR_INSTALLER_FAILED); } $this->log(3, "+ mkdir $dest_dir"); } } $attribs = $atts['attribs']; unset($atts['attribs']); // pretty much nothing happens if we are only registering the install if (empty($this->_options['register-only'])) { if (!count($atts)) { // no tasks if (!file_exists($orig_file)) { return $this->raiseError("file $orig_file does not exist", PEAR_INSTALLER_FAILED); } if (!@copy($orig_file, $dest_file)) { return $this->raiseError( "failed to write $dest_file: " . error_get_last()["message"], PEAR_INSTALLER_FAILED); } $this->log(3, "+ cp $orig_file $dest_file"); if (isset($attribs['md5sum'])) { $md5sum = md5_file($dest_file); } } else { // file with tasks if (!file_exists($orig_file)) { return $this->raiseError("file $orig_file does not exist", PEAR_INSTALLER_FAILED); } $contents = file_get_contents($orig_file); if ($contents === false) { $contents = ''; } if (isset($attribs['md5sum'])) { $md5sum = md5($contents); } foreach ($atts as $tag => $raw) { $tag = str_replace(array($pkg->getTasksNs() . ':', '-'), array('', '_'), $tag); $task = "PEAR_Task_$tag"; $task = new $task($this->config, $this, PEAR_TASK_INSTALL); if (!$task->isScript()) { // scripts are only handled after installation $task->init($raw, $attribs, $pkg->getLastInstalledVersion()); $res = $task->startSession($pkg, $contents, $final_dest_file); if ($res === false) { continue; // skip this file } if (PEAR::isError($res)) { return $res; } $contents = $res; // save changes } $wp = @fopen($dest_file, "wb"); if (!is_resource($wp)) { return $this->raiseError( "failed to create $dest_file: " . error_get_last()["message"], PEAR_INSTALLER_FAILED); } if (fwrite($wp, $contents) === false) { return $this->raiseError( "failed writing to $dest_file: " . error_get_last()["message"], PEAR_INSTALLER_FAILED); } fclose($wp); } } // {{{ check the md5 if (isset($md5sum)) { // Make sure the original md5 sum matches with expected if (strtolower($md5sum) === strtolower($attribs['md5sum'])) { $this->log(2, "md5sum ok: $final_dest_file"); if (isset($contents)) { // set md5 sum based on $content in case any tasks were run. $real_atts['attribs']['md5sum'] = md5($contents); } } else { if (empty($options['force'])) { // delete the file if (file_exists($dest_file)) { unlink($dest_file); } if (!isset($options['ignore-errors'])) { return $this->raiseError("bad md5sum for file $final_dest_file", PEAR_INSTALLER_FAILED); } if (!isset($options['soft'])) { $this->log(0, "warning : bad md5sum for file $final_dest_file"); } } else { if (!isset($options['soft'])) { $this->log(0, "warning : bad md5sum for file $final_dest_file"); } } } } else { $real_atts['attribs']['md5sum'] = md5_file($dest_file); } // }}} // {{{ set file permissions if (!OS_WINDOWS) { if ($role->isExecutable()) { $mode = 0777 & ~(int)octdec($this->config->get('umask')); $this->log(3, "+ chmod +x $dest_file"); } else { $mode = 0666 & ~(int)octdec($this->config->get('umask')); } if ($attribs['role'] != 'src') { $this->addFileOperation("chmod", array($mode, $dest_file)); if (!@chmod($dest_file, $mode)) { if (!isset($options['soft'])) { $this->log(0, "failed to change mode of $dest_file: " . error_get_last()["message"]); } } } } // }}} if ($attribs['role'] == 'src') { rename($dest_file, $final_dest_file); $this->log(2, "renamed source file $dest_file to $final_dest_file"); } else { $this->addFileOperation("rename", array($dest_file, $final_dest_file, $role->isExtension())); } } // Store the full path where the file was installed for easy uninstall if ($attribs['role'] != 'src') { $loc = $this->config->get($role->getLocationConfig(), null, $channel); $this->addFileOperation('installed_as', array($file, $installed_as, $loc, dirname(substr($installed_as, strlen($loc))))); } //$this->log(2, "installed: $dest_file"); return PEAR_INSTALLER_OK; } // }}} // {{{ addFileOperation() /** * Add a file operation to the current file transaction. * * @see startFileTransaction() * @param string $type This can be one of: * - rename: rename a file ($data has 3 values) * - backup: backup an existing file ($data has 1 value) * - removebackup: clean up backups created during install ($data has 1 value) * - chmod: change permissions on a file ($data has 2 values) * - delete: delete a file ($data has 1 value) * - rmdir: delete a directory if empty ($data has 1 value) * - installed_as: mark a file as installed ($data has 4 values). * @param array $data For all file operations, this array must contain the * full path to the file or directory that is being operated on. For * the rename command, the first parameter must be the file to rename, * the second its new name, the third whether this is a PHP extension. * * The installed_as operation contains 4 elements in this order: * 1. Filename as listed in the filelist element from package.xml * 2. Full path to the installed file * 3. Full path from the php_dir configuration variable used in this * installation * 4. Relative path from the php_dir that this file is installed in */ function addFileOperation($type, $data) { if (!is_array($data)) { return $this->raiseError('Internal Error: $data in addFileOperation' . ' must be an array, was ' . gettype($data)); } if ($type == 'chmod') { $octmode = decoct($data[0]); $this->log(3, "adding to transaction: $type $octmode $data[1]"); } else { $this->log(3, "adding to transaction: $type " . implode(" ", $data)); } $this->file_operations[] = array($type, $data); } // }}} // {{{ startFileTransaction() function startFileTransaction($rollback_in_case = false) { if (count($this->file_operations) && $rollback_in_case) { $this->rollbackFileTransaction(); } $this->file_operations = array(); } // }}} // {{{ commitFileTransaction() function commitFileTransaction() { // {{{ first, check permissions and such manually $errors = array(); foreach ($this->file_operations as $key => $tr) { list($type, $data) = $tr; switch ($type) { case 'rename': if (!file_exists($data[0])) { $errors[] = "cannot rename file $data[0], doesn't exist"; } // check that dest dir. is writable if (!is_writable(dirname($data[1]))) { $errors[] = "permission denied ($type): $data[1]"; } break; case 'chmod': // check that file is writable if (!is_writable($data[1])) { $errors[] = "permission denied ($type): $data[1] " . decoct($data[0]); } break; case 'delete': if (!file_exists($data[0])) { $this->log(2, "warning: file $data[0] doesn't exist, can't be deleted"); } // check that directory is writable if (file_exists($data[0])) { if (!is_writable(dirname($data[0]))) { $errors[] = "permission denied ($type): $data[0]"; } else { // make sure the file to be deleted can be opened for writing $fp = false; if (!is_dir($data[0]) && (!is_writable($data[0]) || !($fp = @fopen($data[0], 'a')))) { $errors[] = "permission denied ($type): $data[0]"; } elseif ($fp) { fclose($fp); } } /* Verify we are not deleting a file owned by another package * This can happen when a file moves from package A to B in * an upgrade ala http://pear.php.net/17986 */ $info = array( 'package' => strtolower($this->pkginfo->getName()), 'channel' => strtolower($this->pkginfo->getChannel()), ); $result = $this->_registry->checkFileMap($data[0], $info, '1.1'); if (is_array($result)) { $res = array_diff($result, $info); if (!empty($res)) { $new = $this->_registry->getPackage($result[1], $result[0]); $this->file_operations[$key] = false; $pkginfoName = $this->pkginfo->getName(); $newChannel = $new->getChannel(); $newPackage = $new->getName(); $this->log(3, "file $data[0] was scheduled for removal from $pkginfoName but is owned by $newChannel/$newPackage, removal has been cancelled."); } } } break; } } // }}} $n = count($this->file_operations); $this->log(2, "about to commit $n file operations for " . $this->pkginfo->getName()); $m = count($errors); if ($m > 0) { foreach ($errors as $error) { if (!isset($this->_options['soft'])) { $this->log(1, $error); } } if (!isset($this->_options['ignore-errors'])) { return false; } } $this->_dirtree = array(); // {{{ really commit the transaction foreach ($this->file_operations as $i => $tr) { if (!$tr) { // support removal of non-existing backups continue; } list($type, $data) = $tr; switch ($type) { case 'backup': if (!file_exists($data[0])) { $this->file_operations[$i] = false; break; } if (!@copy($data[0], $data[0] . '.bak')) { $this->log(1, 'Could not copy ' . $data[0] . ' to ' . $data[0] . '.bak ' . error_get_last()["message"]); return false; } $this->log(3, "+ backup $data[0] to $data[0].bak"); break; case 'removebackup': if (file_exists($data[0] . '.bak') && is_writable($data[0] . '.bak')) { unlink($data[0] . '.bak'); $this->log(3, "+ rm backup of $data[0] ($data[0].bak)"); } break; case 'rename': $test = file_exists($data[1]) ? @unlink($data[1]) : null; if (!$test && file_exists($data[1])) { if ($data[2]) { $extra = ', this extension must be installed manually. Rename to "' . basename($data[1]) . '"'; } else { $extra = ''; } if (!isset($this->_options['soft'])) { $this->log(1, 'Could not delete ' . $data[1] . ', cannot rename ' . $data[0] . $extra); } if (!isset($this->_options['ignore-errors'])) { return false; } } // permissions issues with rename - copy() is far superior $perms = @fileperms($data[0]); if (!@copy($data[0], $data[1])) { $this->log(1, 'Could not rename ' . $data[0] . ' to ' . $data[1] . ' ' . error_get_last()["message"]); return false; } // copy over permissions, otherwise they are lost @chmod($data[1], $perms); @unlink($data[0]); $this->log(3, "+ mv $data[0] $data[1]"); break; case 'chmod': if (!@chmod($data[1], $data[0])) { $this->log(1, 'Could not chmod ' . $data[1] . ' to ' . decoct($data[0]) . ' ' . error_get_last()["message"]); return false; } $octmode = decoct($data[0]); $this->log(3, "+ chmod $octmode $data[1]"); break; case 'delete': if (file_exists($data[0])) { if (!@unlink($data[0])) { $this->log(1, 'Could not delete ' . $data[0] . ' ' . error_get_last()["message"]); return false; } $this->log(3, "+ rm $data[0]"); } break; case 'rmdir': if (file_exists($data[0])) { do { $testme = opendir($data[0]); while (false !== ($entry = readdir($testme))) { if ($entry == '.' || $entry == '..') { continue; } closedir($testme); break 2; // this directory is not empty and can't be // deleted } closedir($testme); if (!@rmdir($data[0])) { $this->log(1, 'Could not rmdir ' . $data[0] . ' ' . error_get_last()["message"]); return false; } $this->log(3, "+ rmdir $data[0]"); } while (false); } break; case 'installed_as': $this->pkginfo->setInstalledAs($data[0], $data[1]); if (!isset($this->_dirtree[dirname($data[1])])) { $this->_dirtree[dirname($data[1])] = true; $this->pkginfo->setDirtree(dirname($data[1])); while(!empty($data[3]) && dirname($data[3]) != $data[3] && $data[3] != '/' && $data[3] != '\\') { $this->pkginfo->setDirtree($pp = $this->_prependPath($data[3], $data[2])); $this->_dirtree[$pp] = true; $data[3] = dirname($data[3]); } } break; } } // }}} $this->log(2, "successfully committed $n file operations"); $this->file_operations = array(); return true; } // }}} // {{{ rollbackFileTransaction() function rollbackFileTransaction() { $n = count($this->file_operations); $this->log(2, "rolling back $n file operations"); foreach ($this->file_operations as $tr) { list($type, $data) = $tr; switch ($type) { case 'backup': if (file_exists($data[0] . '.bak')) { if (file_exists($data[0] && is_writable($data[0]))) { unlink($data[0]); } @copy($data[0] . '.bak', $data[0]); $this->log(3, "+ restore $data[0] from $data[0].bak"); } break; case 'removebackup': if (file_exists($data[0] . '.bak') && is_writable($data[0] . '.bak')) { unlink($data[0] . '.bak'); $this->log(3, "+ rm backup of $data[0] ($data[0].bak)"); } break; case 'rename': @unlink($data[0]); $this->log(3, "+ rm $data[0]"); break; case 'mkdir': @rmdir($data[0]); $this->log(3, "+ rmdir $data[0]"); break; case 'chmod': break; case 'delete': break; case 'installed_as': $this->pkginfo->setInstalledAs($data[0], false); break; } } $this->pkginfo->resetDirtree(); $this->file_operations = array(); } // }}} // {{{ mkDirHier($dir) function mkDirHier($dir) { $this->addFileOperation('mkdir', array($dir)); return parent::mkDirHier($dir); } // }}} // {{{ _parsePackageXml() function _parsePackageXml(&$descfile) { // Parse xml file ----------------------------------------------- $pkg = new PEAR_PackageFile($this->config, $this->debug); PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); $p = &$pkg->fromAnyFile($descfile, PEAR_VALIDATE_INSTALLING); PEAR::staticPopErrorHandling(); if (PEAR::isError($p)) { if (is_array($p->getUserInfo())) { foreach ($p->getUserInfo() as $err) { $loglevel = $err['level'] == 'error' ? 0 : 1; if (!isset($this->_options['soft'])) { $this->log($loglevel, ucfirst($err['level']) . ': ' . $err['message']); } } } return $this->raiseError('Installation failed: invalid package file'); } $descfile = $p->getPackageFile(); return $p; } // }}} /** * Set the list of PEAR_Downloader_Package objects to allow more sane * dependency validation * @param array */ function setDownloadedPackages(&$pkgs) { PEAR::pushErrorHandling(PEAR_ERROR_RETURN); $err = $this->analyzeDependencies($pkgs); PEAR::popErrorHandling(); if (PEAR::isError($err)) { return $err; } $this->_downloadedPackages = &$pkgs; } /** * Set the list of PEAR_Downloader_Package objects to allow more sane * dependency validation * @param array */ function setUninstallPackages(&$pkgs) { $this->_downloadedPackages = &$pkgs; } function getInstallPackages() { return $this->_downloadedPackages; } // {{{ install() /** * Installs the files within the package file specified. * * @param string|PEAR_Downloader_Package $pkgfile path to the package file, * or a pre-initialized packagefile object * @param array $options * recognized options: * - installroot : optional prefix directory for installation * - force : force installation * - register-only : update registry but don't install files * - upgrade : upgrade existing install * - soft : fail silently * - nodeps : ignore dependency conflicts/missing dependencies * - alldeps : install all dependencies * - onlyreqdeps : install only required dependencies * * @return array|PEAR_Error package info if successful */ function install($pkgfile, $options = array()) { $this->_options = $options; $this->_registry = &$this->config->getRegistry(); if (is_object($pkgfile)) { $dlpkg = &$pkgfile; $pkg = $pkgfile->getPackageFile(); $pkgfile = $pkg->getArchiveFile(); $descfile = $pkg->getPackageFile(); } else { $descfile = $pkgfile; $pkg = $this->_parsePackageXml($descfile); if (PEAR::isError($pkg)) { return $pkg; } } $tmpdir = dirname($descfile); if (realpath($descfile) != realpath($pkgfile)) { // Use the temp_dir since $descfile can contain the download dir path $tmpdir = $this->config->get('temp_dir', null, 'pear.php.net'); $tmpdir = System::mktemp('-d -t "' . $tmpdir . '"'); $tar = new Archive_Tar($pkgfile); if (!$tar->extract($tmpdir)) { return $this->raiseError("unable to unpack $pkgfile"); } } $pkgname = $pkg->getName(); $channel = $pkg->getChannel(); if (isset($options['installroot'])) { $this->config->setInstallRoot($options['installroot']); $this->_registry = &$this->config->getRegistry(); $installregistry = &$this->_registry; $this->installroot = ''; // all done automagically now $php_dir = $this->config->get('php_dir', null, $channel); } else { $this->config->setInstallRoot(false); $this->_registry = &$this->config->getRegistry(); if (isset($this->_options['packagingroot'])) { $regdir = $this->_prependPath( $this->config->get('php_dir', null, 'pear.php.net'), $this->_options['packagingroot']); $metadata_dir = $this->config->get('metadata_dir', null, 'pear.php.net'); if ($metadata_dir) { $metadata_dir = $this->_prependPath( $metadata_dir, $this->_options['packagingroot']); } $packrootphp_dir = $this->_prependPath( $this->config->get('php_dir', null, $channel), $this->_options['packagingroot']); $installregistry = new PEAR_Registry($regdir, false, false, $metadata_dir); if (!$installregistry->channelExists($channel, true)) { // we need to fake a channel-discover of this channel $chanobj = $this->_registry->getChannel($channel, true); $installregistry->addChannel($chanobj); } $php_dir = $packrootphp_dir; } else { $installregistry = &$this->_registry; $php_dir = $this->config->get('php_dir', null, $channel); } $this->installroot = ''; } // {{{ checks to do when not in "force" mode if (empty($options['force']) && (file_exists($this->config->get('php_dir')) && is_dir($this->config->get('php_dir')))) { $testp = $channel == 'pear.php.net' ? $pkgname : array($channel, $pkgname); $instfilelist = $pkg->getInstallationFileList(true); if (PEAR::isError($instfilelist)) { return $instfilelist; } // ensure we have the most accurate registry $installregistry->flushFileMap(); $test = $installregistry->checkFileMap($instfilelist, $testp, '1.1'); if (PEAR::isError($test)) { return $test; } if (sizeof($test)) { $pkgs = $this->getInstallPackages(); $found = false; foreach ($pkgs as $param) { if ($pkg->isSubpackageOf($param)) { $found = true; break; } } if ($found) { // subpackages can conflict with earlier versions of parent packages $parentreg = $installregistry->packageInfo($param->getPackage(), null, $param->getChannel()); $tmp = $test; foreach ($tmp as $file => $info) { if (is_array($info)) { if (strtolower($info[1]) == strtolower($param->getPackage()) && strtolower($info[0]) == strtolower($param->getChannel()) ) { if (isset($parentreg['filelist'][$file])) { unset($parentreg['filelist'][$file]); } else{ $pos = strpos($file, '/'); $basedir = substr($file, 0, $pos); $file2 = substr($file, $pos + 1); if (isset($parentreg['filelist'][$file2]['baseinstalldir']) && $parentreg['filelist'][$file2]['baseinstalldir'] === $basedir ) { unset($parentreg['filelist'][$file2]); } } unset($test[$file]); } } else { if (strtolower($param->getChannel()) != 'pear.php.net') { continue; } if (strtolower($info) == strtolower($param->getPackage())) { if (isset($parentreg['filelist'][$file])) { unset($parentreg['filelist'][$file]); } else{ $pos = strpos($file, '/'); $basedir = substr($file, 0, $pos); $file2 = substr($file, $pos + 1); if (isset($parentreg['filelist'][$file2]['baseinstalldir']) && $parentreg['filelist'][$file2]['baseinstalldir'] === $basedir ) { unset($parentreg['filelist'][$file2]); } } unset($test[$file]); } } } $pfk = new PEAR_PackageFile($this->config); $parentpkg = &$pfk->fromArray($parentreg); $installregistry->updatePackage2($parentpkg); } if ($param->getChannel() == 'pecl.php.net' && isset($options['upgrade'])) { $tmp = $test; foreach ($tmp as $file => $info) { if (is_string($info)) { // pear.php.net packages are always stored as strings if (strtolower($info) == strtolower($param->getPackage())) { // upgrading existing package unset($test[$file]); } } } } if (count($test)) { $msg = "$channel/$pkgname: conflicting files found:\n"; $longest = max(array_map("strlen", array_keys($test))); $fmt = "%{$longest}s (%s)\n"; foreach ($test as $file => $info) { if (!is_array($info)) { $info = array('pear.php.net', $info); } $info = $info[0] . '/' . $info[1]; $msg .= sprintf($fmt, $file, $info); } if (!isset($options['ignore-errors'])) { return $this->raiseError($msg); } if (!isset($options['soft'])) { $this->log(0, "WARNING: $msg"); } } } } // }}} $this->startFileTransaction(); $usechannel = $channel; if ($channel == 'pecl.php.net') { $test = $installregistry->packageExists($pkgname, $channel); if (!$test) { $test = $installregistry->packageExists($pkgname, 'pear.php.net'); $usechannel = 'pear.php.net'; } } else { $test = $installregistry->packageExists($pkgname, $channel); } if (empty($options['upgrade']) && empty($options['soft'])) { // checks to do only when installing new packages if (empty($options['force']) && $test) { return $this->raiseError("$channel/$pkgname is already installed"); } } else { // Upgrade if ($test) { $v1 = $installregistry->packageInfo($pkgname, 'version', $usechannel); $v2 = $pkg->getVersion(); $cmp = version_compare("$v1", "$v2", 'gt'); if (empty($options['force']) && !version_compare("$v2", "$v1", 'gt')) { return $this->raiseError("upgrade to a newer version ($v2 is not newer than $v1)"); } } } // Do cleanups for upgrade and install, remove old release's files first if ($test && empty($options['register-only'])) { // when upgrading, remove old release's files first: if (PEAR::isError($err = $this->_deletePackageFiles($pkgname, $usechannel, true))) { if (!isset($options['ignore-errors'])) { return $this->raiseError($err); } if (!isset($options['soft'])) { $this->log(0, 'WARNING: ' . $err->getMessage()); } } else { $backedup = $err; } } // {{{ Copy files to dest dir --------------------------------------- // info from the package it self we want to access from _installFile $this->pkginfo = &$pkg; // used to determine whether we should build any C code $this->source_files = 0; $savechannel = $this->config->get('default_channel'); if (empty($options['register-only']) && !is_dir($php_dir)) { if (PEAR::isError(System::mkdir(array('-p'), $php_dir))) { return $this->raiseError("no installation destination directory '$php_dir'\n"); } } if (substr($pkgfile, -4) != '.xml') { $tmpdir .= DIRECTORY_SEPARATOR . $pkgname . '-' . $pkg->getVersion(); } $this->configSet('default_channel', $channel); // {{{ install files $ver = $pkg->getPackagexmlVersion(); if (version_compare($ver, '2.0', '>=')) { $filelist = $pkg->getInstallationFilelist(); } else { $filelist = $pkg->getFileList(); } if (PEAR::isError($filelist)) { return $filelist; } $p = &$installregistry->getPackage($pkgname, $channel); $dirtree = (empty($options['register-only']) && $p) ? $p->getDirTree() : false; $pkg->resetFilelist(); $pkg->setLastInstalledVersion($installregistry->packageInfo($pkg->getPackage(), 'version', $pkg->getChannel())); foreach ($filelist as $file => $atts) { $this->expectError(PEAR_INSTALLER_FAILED); if ($pkg->getPackagexmlVersion() == '1.0') { $res = $this->_installFile($file, $atts, $tmpdir, $options); } else { $res = $this->_installFile2($pkg, $file, $atts, $tmpdir, $options); } $this->popExpect(); if (PEAR::isError($res)) { if (empty($options['ignore-errors'])) { $this->rollbackFileTransaction(); if ($res->getMessage() == "file does not exist") { $this->raiseError("file $file in package.xml does not exist"); } return $this->raiseError($res); } if (!isset($options['soft'])) { $this->log(0, "Warning: " . $res->getMessage()); } } $real = isset($atts['attribs']) ? $atts['attribs'] : $atts; if ($res == PEAR_INSTALLER_OK && $real['role'] != 'src') { // Register files that were installed $pkg->installedFile($file, $atts); } } // }}} // {{{ compile and install source files if ($this->source_files > 0 && empty($options['nobuild'])) { $configureoptions = empty($options['configureoptions']) ? '' : $options['configureoptions']; if (PEAR::isError($err = $this->_compileSourceFiles($savechannel, $pkg, $configureoptions))) { return $err; } } // }}} if (isset($backedup)) { $this->_removeBackups($backedup); } if (!$this->commitFileTransaction()) { $this->rollbackFileTransaction(); $this->configSet('default_channel', $savechannel); return $this->raiseError("commit failed", PEAR_INSTALLER_FAILED); } // }}} $ret = false; $installphase = 'install'; $oldversion = false; // {{{ Register that the package is installed ----------------------- if (empty($options['upgrade'])) { // if 'force' is used, replace the info in registry $usechannel = $channel; if ($channel == 'pecl.php.net') { $test = $installregistry->packageExists($pkgname, $channel); if (!$test) { $test = $installregistry->packageExists($pkgname, 'pear.php.net'); $usechannel = 'pear.php.net'; } } else { $test = $installregistry->packageExists($pkgname, $channel); } if (!empty($options['force']) && $test) { $oldversion = $installregistry->packageInfo($pkgname, 'version', $usechannel); $installregistry->deletePackage($pkgname, $usechannel); } $ret = $installregistry->addPackage2($pkg); } else { if ($dirtree) { $this->startFileTransaction(); // attempt to delete empty directories uksort($dirtree, array($this, '_sortDirs')); foreach($dirtree as $dir => $notused) { $this->addFileOperation('rmdir', array($dir)); } $this->commitFileTransaction(); } $usechannel = $channel; if ($channel == 'pecl.php.net') { $test = $installregistry->packageExists($pkgname, $channel); if (!$test) { $test = $installregistry->packageExists($pkgname, 'pear.php.net'); $usechannel = 'pear.php.net'; } } else { $test = $installregistry->packageExists($pkgname, $channel); } // new: upgrade installs a package if it isn't installed if (!$test) { $ret = $installregistry->addPackage2($pkg); } else { if ($usechannel != $channel) { $installregistry->deletePackage($pkgname, $usechannel); $ret = $installregistry->addPackage2($pkg); } else { $ret = $installregistry->updatePackage2($pkg); } $installphase = 'upgrade'; } } if (!$ret) { $this->configSet('default_channel', $savechannel); return $this->raiseError("Adding package $channel/$pkgname to registry failed"); } // }}} $this->configSet('default_channel', $savechannel); if (class_exists('PEAR_Task_Common')) { // this is auto-included if any tasks exist if (PEAR_Task_Common::hasPostinstallTasks()) { PEAR_Task_Common::runPostinstallTasks($installphase); } } return $pkg->toArray(true); } // }}} // {{{ _compileSourceFiles() /** * @param string * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 * @param mixed[] $configureoptions */ function _compileSourceFiles($savechannel, &$filelist, $configureoptions) { require_once 'PEAR/Builder.php'; $this->log(1, "$this->source_files source files, building"); $bob = new PEAR_Builder($configureoptions, $this->ui); $bob->debug = $this->debug; $built = $bob->build($filelist, array(&$this, '_buildCallback')); if (PEAR::isError($built)) { $this->rollbackFileTransaction(); $this->configSet('default_channel', $savechannel); return $built; } $this->log(1, "\nBuild process completed successfully"); foreach ($built as $ext) { $bn = basename($ext['file']); list($_ext_name, $_ext_suff) = explode('.', $bn); if ($_ext_suff == 'so' || $_ext_suff == 'dll') { if (extension_loaded($_ext_name)) { return $this->raiseError("Extension '$_ext_name' already loaded. " . 'Please unload it in your php.ini file ' . 'prior to install or upgrade'); } $role = 'ext'; } else { $role = 'src'; } $dest = $ext['dest']; $packagingroot = ''; if (isset($this->_options['packagingroot'])) { $packagingroot = $this->_options['packagingroot']; } $copyto = $this->_prependPath($dest, $packagingroot); $extra = $copyto != $dest ? " as '$copyto'" : ''; $this->log(1, "Installing '$dest'$extra"); $copydir = dirname($copyto); // pretty much nothing happens if we are only registering the install if (empty($this->_options['register-only'])) { if (!file_exists($copydir) || !is_dir($copydir)) { if (!$this->mkDirHier($copydir)) { return $this->raiseError("failed to mkdir $copydir", PEAR_INSTALLER_FAILED); } $this->log(3, "+ mkdir $copydir"); } if (!@copy($ext['file'], $copyto)) { return $this->raiseError( "failed to write $copyto (" . error_get_last()["message"] . ")", PEAR_INSTALLER_FAILED); } $this->log(3, "+ cp $ext[file] $copyto"); $this->addFileOperation('rename', array($ext['file'], $copyto)); if (!OS_WINDOWS) { $mode = 0666 & ~(int)octdec($this->config->get('umask')); $this->addFileOperation('chmod', array($mode, $copyto)); if (!@chmod($copyto, $mode)) { $this->log(0, "failed to change mode of $copyto (" . error_get_last()["message"] . ")"); } } } $data = array( 'role' => $role, 'name' => $bn, 'installed_as' => $dest, 'php_api' => $ext['php_api'], 'zend_mod_api' => $ext['zend_mod_api'], 'zend_ext_api' => $ext['zend_ext_api'], ); if ($filelist->getPackageXmlVersion() == '1.0') { $filelist->installedFile($bn, $data); } else { $filelist->installedFile($bn, array('attribs' => $data)); } } } // }}} function &getUninstallPackages() { return $this->_downloadedPackages; } // {{{ uninstall() /** * Uninstall a package * * This method removes all files installed by the application, and then * removes any empty directories. * @param string package name * @param array Command-line options. Possibilities include: * * - installroot: base installation dir, if not the default * - register-only : update registry but don't remove files * - nodeps: do not process dependencies of other packages to ensure * uninstallation does not break things */ function uninstall($package, $options = array()) { $installRoot = isset($options['installroot']) ? $options['installroot'] : ''; $this->config->setInstallRoot($installRoot); $this->installroot = ''; $this->_registry = &$this->config->getRegistry(); if (is_object($package)) { $channel = $package->getChannel(); $pkg = $package; $package = $pkg->getPackage(); } else { $pkg = false; $info = $this->_registry->parsePackageName($package, $this->config->get('default_channel')); $channel = $info['channel']; $package = $info['package']; } $savechannel = $this->config->get('default_channel'); $this->configSet('default_channel', $channel); if (!is_object($pkg)) { $pkg = $this->_registry->getPackage($package, $channel); } if (!$pkg) { $this->configSet('default_channel', $savechannel); return $this->raiseError($this->_registry->parsedPackageNameToString( array( 'channel' => $channel, 'package' => $package ), true) . ' not installed'); } if ($pkg->getInstalledBinary()) { // this is just an alias for a binary package return $this->_registry->deletePackage($package, $channel); } $filelist = $pkg->getFilelist(); PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); if (!class_exists('PEAR_Dependency2')) { require_once 'PEAR/Dependency2.php'; } $depchecker = new PEAR_Dependency2($this->config, $options, array('channel' => $channel, 'package' => $package), PEAR_VALIDATE_UNINSTALLING); $e = $depchecker->validatePackageUninstall($this); PEAR::staticPopErrorHandling(); if (PEAR::isError($e)) { if (!isset($options['ignore-errors'])) { return $this->raiseError($e); } if (!isset($options['soft'])) { $this->log(0, 'WARNING: ' . $e->getMessage()); } } elseif (is_array($e)) { if (!isset($options['soft'])) { $this->log(0, $e[0]); } } $this->pkginfo = &$pkg; // pretty much nothing happens if we are only registering the uninstall if (empty($options['register-only'])) { // {{{ Delete the files $this->startFileTransaction(); PEAR::pushErrorHandling(PEAR_ERROR_RETURN); if (PEAR::isError($err = $this->_deletePackageFiles($package, $channel))) { PEAR::popErrorHandling(); $this->rollbackFileTransaction(); $this->configSet('default_channel', $savechannel); if (!isset($options['ignore-errors'])) { return $this->raiseError($err); } if (!isset($options['soft'])) { $this->log(0, 'WARNING: ' . $err->getMessage()); } } else { PEAR::popErrorHandling(); } if (!$this->commitFileTransaction()) { $this->rollbackFileTransaction(); if (!isset($options['ignore-errors'])) { return $this->raiseError("uninstall failed"); } if (!isset($options['soft'])) { $this->log(0, 'WARNING: uninstall failed'); } } else { $this->startFileTransaction(); $dirtree = $pkg->getDirTree(); if ($dirtree === false) { $this->configSet('default_channel', $savechannel); return $this->_registry->deletePackage($package, $channel); } // attempt to delete empty directories uksort($dirtree, array($this, '_sortDirs')); foreach($dirtree as $dir => $notused) { $this->addFileOperation('rmdir', array($dir)); } if (!$this->commitFileTransaction()) { $this->rollbackFileTransaction(); if (!isset($options['ignore-errors'])) { return $this->raiseError("uninstall failed"); } if (!isset($options['soft'])) { $this->log(0, 'WARNING: uninstall failed'); } } } // }}} } $this->configSet('default_channel', $savechannel); // Register that the package is no longer installed return $this->_registry->deletePackage($package, $channel); } /** * Sort a list of arrays of array(downloaded packagefilename) by dependency. * * It also removes duplicate dependencies * @param array an array of PEAR_PackageFile_v[1/2] objects * @return array|PEAR_Error array of array(packagefilename, package.xml contents) */ function sortPackagesForUninstall(&$packages) { $this->_dependencyDB = &PEAR_DependencyDB::singleton($this->config); if (PEAR::isError($this->_dependencyDB)) { return $this->_dependencyDB; } usort($packages, array(&$this, '_sortUninstall')); } function _sortUninstall($a, $b) { if (!$a->getDeps() && !$b->getDeps()) { return 0; // neither package has dependencies, order is insignificant } if ($a->getDeps() && !$b->getDeps()) { return -1; // $a must be installed after $b because $a has dependencies } if (!$a->getDeps() && $b->getDeps()) { return 1; // $b must be installed after $a because $b has dependencies } // both packages have dependencies if ($this->_dependencyDB->dependsOn($a, $b)) { return -1; } if ($this->_dependencyDB->dependsOn($b, $a)) { return 1; } return 0; } // }}} // {{{ _sortDirs() function _sortDirs($a, $b) { if (strnatcmp($a, $b) == -1) return 1; if (strnatcmp($a, $b) == 1) return -1; return 0; } // }}} // {{{ _buildCallback() function _buildCallback($what, $data) { if (($what == 'cmdoutput' && $this->debug > 1) || ($what == 'output' && $this->debug > 0)) { $this->ui->outputData(rtrim($data), 'build'); } } // }}} } PKu]l(ePEAR/Downloader.phpnu[ * @author Stig Bakken * @author Tomas V. V. Cox * @author Martin Jansen * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 1.3.0 */ /** * Needed for constants, extending */ require_once 'PEAR/Common.php'; require_once 'PEAR/Proxy.php'; define('PEAR_INSTALLER_OK', 1); define('PEAR_INSTALLER_FAILED', 0); define('PEAR_INSTALLER_SKIPPED', -1); define('PEAR_INSTALLER_ERROR_NO_PREF_STATE', 2); /** * Administration class used to download anything from the internet (PEAR Packages, * static URLs, xml files) * * @category pear * @package PEAR * @author Greg Beaver * @author Stig Bakken * @author Tomas V. V. Cox * @author Martin Jansen * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.3.0 */ class PEAR_Downloader extends PEAR_Common { /** * @var PEAR_Registry * @access private */ var $_registry; /** * Preferred Installation State (snapshot, devel, alpha, beta, stable) * @var string|null * @access private */ var $_preferredState; /** * Options from command-line passed to Install. * * Recognized options:
* - onlyreqdeps : install all required dependencies as well * - alldeps : install all dependencies, including optional * - installroot : base relative path to install files in * - force : force a download even if warnings would prevent it * - nocompress : download uncompressed tarballs * - configureoptions : additional configure options * @see PEAR_Command_Install * @access private * @var array */ var $_options; /** * Downloaded Packages after a call to download(). * * Format of each entry: * * * array('pkg' => 'package_name', 'file' => '/path/to/local/file', * 'info' => array() // parsed package.xml * ); * * @access private * @var array */ var $_downloadedPackages = array(); /** * Packages slated for download. * * This is used to prevent downloading a package more than once should it be a dependency * for two packages to be installed. * Format of each entry: * *
     * array('package_name1' => parsed package.xml, 'package_name2' => parsed package.xml,
     * );
     * 
* @access private * @var array */ var $_toDownload = array(); /** * Array of every package installed, with names lower-cased. * * Format: * * array('package1' => 0, 'package2' => 1, ); * * @var array */ var $_installed = array(); /** * @var array * @access private */ var $_errorStack = array(); /** * @var boolean * @access private */ var $_internalDownload = false; /** * Temporary variable used in sorting packages by dependency in {@link sortPkgDeps()} * @var array * @access private */ var $_packageSortTree; /** * Temporary directory, or configuration value where downloads will occur * @var string */ var $_downloadDir; /** * List of methods that can be called both statically and non-statically. * @var array */ protected static $bivalentMethods = array( 'setErrorHandling' => true, 'raiseError' => true, 'throwError' => true, 'pushErrorHandling' => true, 'popErrorHandling' => true, 'downloadHttp' => true, ); /** * @param PEAR_Frontend_* * @param array * @param PEAR_Config */ function __construct($ui = null, $options = array(), $config = null) { parent::__construct(); $this->_options = $options; if ($config !== null) { $this->config = &$config; $this->_preferredState = $this->config->get('preferred_state'); } $this->ui = &$ui; if (!$this->_preferredState) { // don't inadvertently use a non-set preferred_state $this->_preferredState = null; } if ($config !== null) { if (isset($this->_options['installroot'])) { $this->config->setInstallRoot($this->_options['installroot']); } $this->_registry = &$config->getRegistry(); } if (isset($this->_options['alldeps']) || isset($this->_options['onlyreqdeps'])) { $this->_installed = $this->_registry->listAllPackages(); foreach ($this->_installed as $key => $unused) { if (!count($unused)) { continue; } $strtolower = function($a) { return strtolower($a); }; array_walk($this->_installed[$key], $strtolower); } } } /** * Attempt to discover a channel's remote capabilities from * its server name * @param string * @return boolean */ function discover($channel) { $this->log(1, 'Attempting to discover channel "' . $channel . '"...'); PEAR::pushErrorHandling(PEAR_ERROR_RETURN); $callback = $this->ui ? array(&$this, '_downloadCallback') : null; if (!class_exists('System')) { require_once 'System.php'; } $tmpdir = $this->config->get('temp_dir'); $tmp = System::mktemp('-d -t "' . $tmpdir . '"'); $a = $this->downloadHttp('http://' . $channel . '/channel.xml', $this->ui, $tmp, $callback, false); PEAR::popErrorHandling(); if (PEAR::isError($a)) { // Attempt to fallback to https automatically. PEAR::pushErrorHandling(PEAR_ERROR_RETURN); $this->log(1, 'Attempting fallback to https instead of http on channel "' . $channel . '"...'); $a = $this->downloadHttp('https://' . $channel . '/channel.xml', $this->ui, $tmp, $callback, false); PEAR::popErrorHandling(); if (PEAR::isError($a)) { return false; } } list($a, $lastmodified) = $a; if (!class_exists('PEAR_ChannelFile')) { require_once 'PEAR/ChannelFile.php'; } $b = new PEAR_ChannelFile; if ($b->fromXmlFile($a)) { unlink($a); if ($this->config->get('auto_discover')) { $this->_registry->addChannel($b, $lastmodified); $alias = $b->getName(); if ($b->getName() == $this->_registry->channelName($b->getAlias())) { $alias = $b->getAlias(); } $this->log(1, 'Auto-discovered channel "' . $channel . '", alias "' . $alias . '", adding to registry'); } return true; } unlink($a); return false; } /** * For simpler unit-testing * @param PEAR_Downloader * @return PEAR_Downloader_Package */ function newDownloaderPackage(&$t) { if (!class_exists('PEAR_Downloader_Package')) { require_once 'PEAR/Downloader/Package.php'; } $a = new PEAR_Downloader_Package($t); return $a; } /** * For simpler unit-testing * @param PEAR_Config * @param array * @param array * @param int */ function &getDependency2Object(&$c, $i, $p, $s) { if (!class_exists('PEAR_Dependency2')) { require_once 'PEAR/Dependency2.php'; } $z = new PEAR_Dependency2($c, $i, $p, $s); return $z; } function &download($params) { if (!count($params)) { $a = array(); return $a; } if (!isset($this->_registry)) { $this->_registry = &$this->config->getRegistry(); } $channelschecked = array(); // convert all parameters into PEAR_Downloader_Package objects foreach ($params as $i => $param) { $params[$i] = $this->newDownloaderPackage($this); PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); $err = $params[$i]->initialize($param); PEAR::staticPopErrorHandling(); if (!$err) { // skip parameters that were missed by preferred_state continue; } if (PEAR::isError($err)) { if (!isset($this->_options['soft']) && $err->getMessage() !== '') { $this->log(0, $err->getMessage()); } $params[$i] = false; if (is_object($param)) { $param = $param->getChannel() . '/' . $param->getPackage(); } if (!isset($this->_options['soft'])) { $this->log(2, 'Package "' . $param . '" is not valid'); } // Message logged above in a specific verbose mode, passing null to not show up on CLI $this->pushError(null, PEAR_INSTALLER_SKIPPED); } else { do { if ($params[$i] && $params[$i]->getType() == 'local') { // bug #7090 skip channel.xml check for local packages break; } if ($params[$i] && !isset($channelschecked[$params[$i]->getChannel()]) && !isset($this->_options['offline']) ) { $channelschecked[$params[$i]->getChannel()] = true; PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); if (!class_exists('System')) { require_once 'System.php'; } $curchannel = $this->_registry->getChannel($params[$i]->getChannel()); if (PEAR::isError($curchannel)) { PEAR::staticPopErrorHandling(); return $this->raiseError($curchannel); } if (PEAR::isError($dir = $this->getDownloadDir())) { PEAR::staticPopErrorHandling(); break; } $mirror = $this->config->get('preferred_mirror', null, $params[$i]->getChannel()); $url = 'http://' . $mirror . '/channel.xml'; $a = $this->downloadHttp($url, $this->ui, $dir, null, $curchannel->lastModified()); PEAR::staticPopErrorHandling(); if ($a === false) { //channel.xml not modified break; } else if (PEAR::isError($a)) { // Attempt fallback to https automatically PEAR::pushErrorHandling(PEAR_ERROR_RETURN); $a = $this->downloadHttp('https://' . $mirror . '/channel.xml', $this->ui, $dir, null, $curchannel->lastModified()); PEAR::staticPopErrorHandling(); if (PEAR::isError($a) || !$a) { break; } } $this->log(0, 'WARNING: channel "' . $params[$i]->getChannel() . '" has ' . 'updated its protocols, use "' . PEAR_RUNTYPE . ' channel-update ' . $params[$i]->getChannel() . '" to update'); } } while (false); if ($params[$i] && !isset($this->_options['downloadonly'])) { if (isset($this->_options['packagingroot'])) { $checkdir = $this->_prependPath( $this->config->get('php_dir', null, $params[$i]->getChannel()), $this->_options['packagingroot']); } else { $checkdir = $this->config->get('php_dir', null, $params[$i]->getChannel()); } while ($checkdir && $checkdir != '/' && !file_exists($checkdir)) { $checkdir = dirname($checkdir); } if ($checkdir == '.') { $checkdir = '/'; } if (!is_writeable($checkdir)) { return PEAR::raiseError('Cannot install, php_dir for channel "' . $params[$i]->getChannel() . '" is not writeable by the current user'); } } } } unset($channelschecked); PEAR_Downloader_Package::removeDuplicates($params); if (!count($params)) { $a = array(); return $a; } if (!isset($this->_options['nodeps']) && !isset($this->_options['offline'])) { $reverify = true; while ($reverify) { $reverify = false; foreach ($params as $i => $param) { //PHP Bug 40768 / PEAR Bug #10944 //Nested foreaches fail in PHP 5.2.1 key($params); $ret = $params[$i]->detectDependencies($params); if (PEAR::isError($ret)) { $reverify = true; $params[$i] = false; PEAR_Downloader_Package::removeDuplicates($params); if (!isset($this->_options['soft'])) { $this->log(0, $ret->getMessage()); } continue 2; } } } } if (isset($this->_options['offline'])) { $this->log(3, 'Skipping dependency download check, --offline specified'); } if (!count($params)) { $a = array(); return $a; } while (PEAR_Downloader_Package::mergeDependencies($params)); PEAR_Downloader_Package::removeDuplicates($params, true); $errorparams = array(); if (PEAR_Downloader_Package::detectStupidDuplicates($params, $errorparams)) { if (count($errorparams)) { foreach ($errorparams as $param) { $name = $this->_registry->parsedPackageNameToString($param->getParsedPackage()); $this->pushError('Duplicate package ' . $name . ' found', PEAR_INSTALLER_FAILED); } $a = array(); return $a; } } PEAR_Downloader_Package::removeInstalled($params); if (!count($params)) { $this->pushError('No valid packages found', PEAR_INSTALLER_FAILED); $a = array(); return $a; } PEAR::pushErrorHandling(PEAR_ERROR_RETURN); $err = $this->analyzeDependencies($params); PEAR::popErrorHandling(); if (!count($params)) { $this->pushError('No valid packages found', PEAR_INSTALLER_FAILED); $a = array(); return $a; } $ret = array(); $newparams = array(); if (isset($this->_options['pretend'])) { return $params; } $somefailed = false; foreach ($params as $i => $package) { PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); $pf = &$params[$i]->download(); PEAR::staticPopErrorHandling(); if (PEAR::isError($pf)) { if (!isset($this->_options['soft'])) { $this->log(1, $pf->getMessage()); $this->log(0, 'Error: cannot download "' . $this->_registry->parsedPackageNameToString($package->getParsedPackage(), true) . '"'); } $somefailed = true; continue; } $newparams[] = &$params[$i]; $ret[] = array( 'file' => $pf->getArchiveFile(), 'info' => &$pf, 'pkg' => $pf->getPackage() ); } if ($somefailed) { // remove params that did not download successfully PEAR::pushErrorHandling(PEAR_ERROR_RETURN); $err = $this->analyzeDependencies($newparams, true); PEAR::popErrorHandling(); if (!count($newparams)) { $this->pushError('Download failed', PEAR_INSTALLER_FAILED); $a = array(); return $a; } } $this->_downloadedPackages = $ret; return $newparams; } /** * @param array all packages to be installed */ function analyzeDependencies(&$params, $force = false) { if (isset($this->_options['downloadonly'])) { return; } PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); $redo = true; $reset = $hasfailed = $failed = false; while ($redo) { $redo = false; foreach ($params as $i => $param) { $deps = $param->getDeps(); if (!$deps) { $depchecker = &$this->getDependency2Object($this->config, $this->getOptions(), $param->getParsedPackage(), PEAR_VALIDATE_DOWNLOADING); $send = $param->getPackageFile(); $installcheck = $depchecker->validatePackage($send, $this, $params); if (PEAR::isError($installcheck)) { if (!isset($this->_options['soft'])) { $this->log(0, $installcheck->getMessage()); } $hasfailed = true; $params[$i] = false; $reset = true; $redo = true; $failed = false; PEAR_Downloader_Package::removeDuplicates($params); continue 2; } continue; } if (!$reset && $param->alreadyValidated() && !$force) { continue; } if (count($deps)) { $depchecker = &$this->getDependency2Object($this->config, $this->getOptions(), $param->getParsedPackage(), PEAR_VALIDATE_DOWNLOADING); $send = $param->getPackageFile(); if ($send === null) { $send = $param->getDownloadURL(); } $installcheck = $depchecker->validatePackage($send, $this, $params); if (PEAR::isError($installcheck)) { if (!isset($this->_options['soft'])) { $this->log(0, $installcheck->getMessage()); } $hasfailed = true; $params[$i] = false; $reset = true; $redo = true; $failed = false; PEAR_Downloader_Package::removeDuplicates($params); continue 2; } $failed = false; if (isset($deps['required']) && is_array($deps['required'])) { foreach ($deps['required'] as $type => $dep) { // note: Dependency2 will never return a PEAR_Error if ignore-errors // is specified, so soft is needed to turn off logging if (!isset($dep[0])) { if (PEAR::isError($e = $depchecker->{"validate{$type}Dependency"}($dep, true, $params))) { $failed = true; if (!isset($this->_options['soft'])) { $this->log(0, $e->getMessage()); } } elseif (is_array($e) && !$param->alreadyValidated()) { if (!isset($this->_options['soft'])) { $this->log(0, $e[0]); } } } else { foreach ($dep as $d) { if (PEAR::isError($e = $depchecker->{"validate{$type}Dependency"}($d, true, $params))) { $failed = true; if (!isset($this->_options['soft'])) { $this->log(0, $e->getMessage()); } } elseif (is_array($e) && !$param->alreadyValidated()) { if (!isset($this->_options['soft'])) { $this->log(0, $e[0]); } } } } } if (isset($deps['optional']) && is_array($deps['optional'])) { foreach ($deps['optional'] as $type => $dep) { if (!isset($dep[0])) { if (PEAR::isError($e = $depchecker->{"validate{$type}Dependency"}($dep, false, $params))) { $failed = true; if (!isset($this->_options['soft'])) { $this->log(0, $e->getMessage()); } } elseif (is_array($e) && !$param->alreadyValidated()) { if (!isset($this->_options['soft'])) { $this->log(0, $e[0]); } } } else { foreach ($dep as $d) { if (PEAR::isError($e = $depchecker->{"validate{$type}Dependency"}($d, false, $params))) { $failed = true; if (!isset($this->_options['soft'])) { $this->log(0, $e->getMessage()); } } elseif (is_array($e) && !$param->alreadyValidated()) { if (!isset($this->_options['soft'])) { $this->log(0, $e[0]); } } } } } } $groupname = $param->getGroup(); if (isset($deps['group']) && $groupname) { if (!isset($deps['group'][0])) { $deps['group'] = array($deps['group']); } $found = false; foreach ($deps['group'] as $group) { if ($group['attribs']['name'] == $groupname) { $found = true; break; } } if ($found) { unset($group['attribs']); foreach ($group as $type => $dep) { if (!isset($dep[0])) { if (PEAR::isError($e = $depchecker->{"validate{$type}Dependency"}($dep, false, $params))) { $failed = true; if (!isset($this->_options['soft'])) { $this->log(0, $e->getMessage()); } } elseif (is_array($e) && !$param->alreadyValidated()) { if (!isset($this->_options['soft'])) { $this->log(0, $e[0]); } } } else { foreach ($dep as $d) { if (PEAR::isError($e = $depchecker->{"validate{$type}Dependency"}($d, false, $params))) { $failed = true; if (!isset($this->_options['soft'])) { $this->log(0, $e->getMessage()); } } elseif (is_array($e) && !$param->alreadyValidated()) { if (!isset($this->_options['soft'])) { $this->log(0, $e[0]); } } } } } } } } else { foreach ($deps as $dep) { if (PEAR::isError($e = $depchecker->validateDependency1($dep, $params))) { $failed = true; if (!isset($this->_options['soft'])) { $this->log(0, $e->getMessage()); } } elseif (is_array($e) && !$param->alreadyValidated()) { if (!isset($this->_options['soft'])) { $this->log(0, $e[0]); } } } } $params[$i]->setValidated(); } if ($failed) { $hasfailed = true; $params[$i] = false; $reset = true; $redo = true; $failed = false; PEAR_Downloader_Package::removeDuplicates($params); continue 2; } } } PEAR::staticPopErrorHandling(); if ($hasfailed && (isset($this->_options['ignore-errors']) || isset($this->_options['nodeps']))) { // this is probably not needed, but just in case if (!isset($this->_options['soft'])) { $this->log(0, 'WARNING: dependencies failed'); } } } /** * Retrieve the directory that downloads will happen in * @access private * @return string */ function getDownloadDir() { if (isset($this->_downloadDir)) { return $this->_downloadDir; } $downloaddir = $this->config->get('download_dir'); if (empty($downloaddir) || (is_dir($downloaddir) && !is_writable($downloaddir))) { if (is_dir($downloaddir) && !is_writable($downloaddir)) { $this->log(0, 'WARNING: configuration download directory "' . $downloaddir . '" is not writeable. Change download_dir config variable to ' . 'a writeable dir to avoid this warning'); } if (!class_exists('System')) { require_once 'System.php'; } if (PEAR::isError($downloaddir = System::mktemp('-d'))) { return $downloaddir; } $this->log(3, '+ tmp dir created at ' . $downloaddir); } if (!is_writable($downloaddir)) { if (PEAR::isError(System::mkdir(array('-p', $downloaddir))) || !is_writable($downloaddir)) { return PEAR::raiseError('download directory "' . $downloaddir . '" is not writeable. Change download_dir config variable to ' . 'a writeable dir'); } } return $this->_downloadDir = $downloaddir; } function setDownloadDir($dir) { if (!@is_writable($dir)) { if (PEAR::isError(System::mkdir(array('-p', $dir)))) { return PEAR::raiseError('download directory "' . $dir . '" is not writeable. Change download_dir config variable to ' . 'a writeable dir'); } } $this->_downloadDir = $dir; } function configSet($key, $value, $layer = 'user', $channel = false) { $this->config->set($key, $value, $layer, $channel); $this->_preferredState = $this->config->get('preferred_state', null, $channel); if (!$this->_preferredState) { // don't inadvertently use a non-set preferred_state $this->_preferredState = null; } } function setOptions($options) { $this->_options = $options; } function getOptions() { return $this->_options; } /** * @param array output of {@link parsePackageName()} * @access private */ function _getPackageDownloadUrl($parr) { $curchannel = $this->config->get('default_channel'); $this->configSet('default_channel', $parr['channel']); // getDownloadURL returns an array. On error, it only contains information // on the latest release as array(version, info). On success it contains // array(version, info, download url string) $state = isset($parr['state']) ? $parr['state'] : $this->config->get('preferred_state'); if (!$this->_registry->channelExists($parr['channel'])) { do { if ($this->config->get('auto_discover') && $this->discover($parr['channel'])) { break; } $this->configSet('default_channel', $curchannel); return PEAR::raiseError('Unknown remote channel: ' . $parr['channel']); } while (false); } $chan = $this->_registry->getChannel($parr['channel']); if (PEAR::isError($chan)) { return $chan; } PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); $version = $this->_registry->packageInfo($parr['package'], 'version', $parr['channel']); $stability = $this->_registry->packageInfo($parr['package'], 'stability', $parr['channel']); // package is installed - use the installed release stability level if (!isset($parr['state']) && $stability !== null) { $state = $stability['release']; } PEAR::staticPopErrorHandling(); $base2 = false; $preferred_mirror = $this->config->get('preferred_mirror'); if (!$chan->supportsREST($preferred_mirror) || ( !($base2 = $chan->getBaseURL('REST1.3', $preferred_mirror)) && !($base = $chan->getBaseURL('REST1.0', $preferred_mirror)) ) ) { return $this->raiseError($parr['channel'] . ' is using an unsupported protocol - This should never happen. Use --force to continue'); } if ($base2) { $rest = &$this->config->getREST('1.3', $this->_options); $base = $base2; } else { $rest = &$this->config->getREST('1.0', $this->_options); } $downloadVersion = false; if (!isset($parr['version']) && !isset($parr['state']) && $version && !PEAR::isError($version) && !isset($this->_options['downloadonly']) ) { $downloadVersion = $version; } $url = $rest->getDownloadURL($base, $parr, $state, $downloadVersion, $chan->getName()); if (PEAR::isError($url)) { $this->configSet('default_channel', $curchannel); return $url; } if ($parr['channel'] != $curchannel) { $this->configSet('default_channel', $curchannel); } if (!is_array($url)) { return $url; } $url['raw'] = false; // no checking is necessary for REST if (!is_array($url['info'])) { return PEAR::raiseError('Invalid remote dependencies retrieved from REST - ' . 'this should never happen'); } if (!isset($this->_options['force']) && !isset($this->_options['downloadonly']) && $version && !PEAR::isError($version) && !isset($parr['group']) ) { if (version_compare($version, $url['version'], '=')) { return PEAR::raiseError($this->_registry->parsedPackageNameToString( $parr, true) . ' is already installed and is the same as the ' . 'released version ' . $url['version'], -976); } if (version_compare($version, $url['version'], '>')) { return PEAR::raiseError($this->_registry->parsedPackageNameToString( $parr, true) . ' is already installed and is newer than detected ' . 'released version ' . $url['version'], -976); } } if (isset($url['info']['required']) || $url['compatible']) { require_once 'PEAR/PackageFile/v2.php'; $pf = new PEAR_PackageFile_v2; $pf->setRawChannel($parr['channel']); if ($url['compatible']) { $pf->setRawCompatible($url['compatible']); } } else { require_once 'PEAR/PackageFile/v1.php'; $pf = new PEAR_PackageFile_v1; } $pf->setRawPackage($url['package']); $pf->setDeps($url['info']); if ($url['compatible']) { $pf->setCompatible($url['compatible']); } $pf->setRawState($url['stability']); $url['info'] = &$pf; if (!extension_loaded("zlib") || isset($this->_options['nocompress'])) { $ext = '.tar'; } else { $ext = '.tgz'; } if (is_array($url) && isset($url['url'])) { $url['url'] .= $ext; } return $url; } /** * @param array dependency array * @access private */ function _getDepPackageDownloadUrl($dep, $parr) { $xsdversion = isset($dep['rel']) ? '1.0' : '2.0'; $curchannel = $this->config->get('default_channel'); if (isset($dep['uri'])) { $xsdversion = '2.0'; $chan = $this->_registry->getChannel('__uri'); if (PEAR::isError($chan)) { return $chan; } $version = $this->_registry->packageInfo($dep['name'], 'version', '__uri'); $this->configSet('default_channel', '__uri'); } else { if (isset($dep['channel'])) { $remotechannel = $dep['channel']; } else { $remotechannel = 'pear.php.net'; } if (!$this->_registry->channelExists($remotechannel)) { do { if ($this->config->get('auto_discover')) { if ($this->discover($remotechannel)) { break; } } return PEAR::raiseError('Unknown remote channel: ' . $remotechannel); } while (false); } $chan = $this->_registry->getChannel($remotechannel); if (PEAR::isError($chan)) { return $chan; } $version = $this->_registry->packageInfo($dep['name'], 'version', $remotechannel); $this->configSet('default_channel', $remotechannel); } $state = isset($parr['state']) ? $parr['state'] : $this->config->get('preferred_state'); if (isset($parr['state']) && isset($parr['version'])) { unset($parr['state']); } if (isset($dep['uri'])) { $info = $this->newDownloaderPackage($this); PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); $err = $info->initialize($dep); PEAR::staticPopErrorHandling(); if (!$err) { // skip parameters that were missed by preferred_state return PEAR::raiseError('Cannot initialize dependency'); } if (PEAR::isError($err)) { if (!isset($this->_options['soft'])) { $this->log(0, $err->getMessage()); } if (is_object($info)) { $param = $info->getChannel() . '/' . $info->getPackage(); } return PEAR::raiseError('Package "' . $param . '" is not valid'); } return $info; } elseif ($chan->supportsREST($this->config->get('preferred_mirror')) && ( ($base2 = $chan->getBaseURL('REST1.3', $this->config->get('preferred_mirror'))) || ($base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) ) ) { if ($base2) { $base = $base2; $rest = &$this->config->getREST('1.3', $this->_options); } else { $rest = &$this->config->getREST('1.0', $this->_options); } $url = $rest->getDepDownloadURL($base, $xsdversion, $dep, $parr, $state, $version, $chan->getName()); if (PEAR::isError($url)) { return $url; } if ($parr['channel'] != $curchannel) { $this->configSet('default_channel', $curchannel); } if (!is_array($url)) { return $url; } $url['raw'] = false; // no checking is necessary for REST if (!is_array($url['info'])) { return PEAR::raiseError('Invalid remote dependencies retrieved from REST - ' . 'this should never happen'); } if (isset($url['info']['required'])) { if (!class_exists('PEAR_PackageFile_v2')) { require_once 'PEAR/PackageFile/v2.php'; } $pf = new PEAR_PackageFile_v2; $pf->setRawChannel($remotechannel); } else { if (!class_exists('PEAR_PackageFile_v1')) { require_once 'PEAR/PackageFile/v1.php'; } $pf = new PEAR_PackageFile_v1; } $pf->setRawPackage($url['package']); $pf->setDeps($url['info']); if ($url['compatible']) { $pf->setCompatible($url['compatible']); } $pf->setRawState($url['stability']); $url['info'] = &$pf; if (!extension_loaded("zlib") || isset($this->_options['nocompress'])) { $ext = '.tar'; } else { $ext = '.tgz'; } if (is_array($url) && isset($url['url'])) { $url['url'] .= $ext; } return $url; } return $this->raiseError($parr['channel'] . ' is using a unsupported protocol - This should never happen.'); } /** * @deprecated in favor of _getPackageDownloadUrl */ function getPackageDownloadUrl($package, $version = null, $channel = false) { if ($version) { $package .= "-$version"; } if ($this === null || $this->_registry === null) { $package = "http://pear.php.net/get/$package"; } else { $chan = $this->_registry->getChannel($channel); if (PEAR::isError($chan)) { return ''; } $package = "http://" . $chan->getServer() . "/get/$package"; } if (!extension_loaded("zlib")) { $package .= '?uncompress=yes'; } return $package; } /** * Retrieve a list of downloaded packages after a call to {@link download()}. * * Also resets the list of downloaded packages. * @return array */ function getDownloadedPackages() { $ret = $this->_downloadedPackages; $this->_downloadedPackages = array(); $this->_toDownload = array(); return $ret; } function _downloadCallback($msg, $params = null) { switch ($msg) { case 'saveas': $this->log(1, "downloading $params ..."); break; case 'done': $this->log(1, '...done: ' . number_format($params, 0, '', ',') . ' bytes'); break; case 'bytesread': static $bytes; if (empty($bytes)) { $bytes = 0; } if (!($bytes % 10240)) { $this->log(1, '.', false); } $bytes += $params; break; case 'start': if($params[1] == -1) { $length = "Unknown size"; } else { $length = number_format($params[1], 0, '', ',')." bytes"; } $this->log(1, "Starting to download {$params[0]} ($length)"); break; } if (method_exists($this->ui, '_downloadCallback')) $this->ui->_downloadCallback($msg, $params); } function _prependPath($path, $prepend) { if (strlen($prepend) > 0) { if (OS_WINDOWS && preg_match('/^[a-z]:/i', $path)) { if (preg_match('/^[a-z]:/i', $prepend)) { $prepend = substr($prepend, 2); } elseif ($prepend[0] != '\\') { $prepend = "\\$prepend"; } $path = substr($path, 0, 2) . $prepend . substr($path, 2); } else { $path = $prepend . $path; } } return $path; } /** * @param string * @param integer */ function pushError($errmsg, $code = -1) { array_push($this->_errorStack, array($errmsg, $code)); } function getErrorMsgs() { $msgs = array(); $errs = $this->_errorStack; foreach ($errs as $err) { $msgs[] = $err[0]; } $this->_errorStack = array(); return $msgs; } /** * for BC * * @deprecated */ function sortPkgDeps(&$packages, $uninstall = false) { $uninstall ? $this->sortPackagesForUninstall($packages) : $this->sortPackagesForInstall($packages); } /** * Sort a list of arrays of array(downloaded packagefilename) by dependency. * * This uses the topological sort method from graph theory, and the * Structures_Graph package to properly sort dependencies for installation. * @param array an array of downloaded PEAR_Downloader_Packages * @return array array of array(packagefilename, package.xml contents) */ function sortPackagesForInstall(&$packages) { require_once 'Structures/Graph.php'; require_once 'Structures/Graph/Node.php'; require_once 'Structures/Graph/Manipulator/TopologicalSorter.php'; $depgraph = new Structures_Graph(true); $nodes = array(); $reg = &$this->config->getRegistry(); foreach ($packages as $i => $package) { $pname = $reg->parsedPackageNameToString( array( 'channel' => $package->getChannel(), 'package' => strtolower($package->getPackage()), )); $nodes[$pname] = new Structures_Graph_Node; $nodes[$pname]->setData($packages[$i]); $depgraph->addNode($nodes[$pname]); } $deplinks = array(); foreach ($nodes as $package => $node) { $pf = &$node->getData(); $pdeps = $pf->getDeps(true); if (!$pdeps) { continue; } if ($pf->getPackagexmlVersion() == '1.0') { foreach ($pdeps as $dep) { if ($dep['type'] != 'pkg' || (isset($dep['optional']) && $dep['optional'] == 'yes')) { continue; } $dname = $reg->parsedPackageNameToString( array( 'channel' => 'pear.php.net', 'package' => strtolower($dep['name']), )); if (isset($nodes[$dname])) { if (!isset($deplinks[$dname])) { $deplinks[$dname] = array(); } $deplinks[$dname][$package] = 1; // dependency is in installed packages continue; } $dname = $reg->parsedPackageNameToString( array( 'channel' => 'pecl.php.net', 'package' => strtolower($dep['name']), )); if (isset($nodes[$dname])) { if (!isset($deplinks[$dname])) { $deplinks[$dname] = array(); } $deplinks[$dname][$package] = 1; // dependency is in installed packages continue; } } } else { // the only ordering we care about is: // 1) subpackages must be installed before packages that depend on them // 2) required deps must be installed before packages that depend on them if (isset($pdeps['required']['subpackage'])) { $t = $pdeps['required']['subpackage']; if (!isset($t[0])) { $t = array($t); } $this->_setupGraph($t, $reg, $deplinks, $nodes, $package); } if (isset($pdeps['group'])) { if (!isset($pdeps['group'][0])) { $pdeps['group'] = array($pdeps['group']); } foreach ($pdeps['group'] as $group) { if (isset($group['subpackage'])) { $t = $group['subpackage']; if (!isset($t[0])) { $t = array($t); } $this->_setupGraph($t, $reg, $deplinks, $nodes, $package); } } } if (isset($pdeps['optional']['subpackage'])) { $t = $pdeps['optional']['subpackage']; if (!isset($t[0])) { $t = array($t); } $this->_setupGraph($t, $reg, $deplinks, $nodes, $package); } if (isset($pdeps['required']['package'])) { $t = $pdeps['required']['package']; if (!isset($t[0])) { $t = array($t); } $this->_setupGraph($t, $reg, $deplinks, $nodes, $package); } if (isset($pdeps['group'])) { if (!isset($pdeps['group'][0])) { $pdeps['group'] = array($pdeps['group']); } foreach ($pdeps['group'] as $group) { if (isset($group['package'])) { $t = $group['package']; if (!isset($t[0])) { $t = array($t); } $this->_setupGraph($t, $reg, $deplinks, $nodes, $package); } } } } } $this->_detectDepCycle($deplinks); foreach ($deplinks as $dependent => $parents) { foreach ($parents as $parent => $unused) { $nodes[$dependent]->connectTo($nodes[$parent]); } } $installOrder = Structures_Graph_Manipulator_TopologicalSorter::sort($depgraph); $ret = array(); for ($i = 0, $count = count($installOrder); $i < $count; $i++) { foreach ($installOrder[$i] as $index => $sortedpackage) { $data = &$installOrder[$i][$index]->getData(); $ret[] = &$nodes[$reg->parsedPackageNameToString( array( 'channel' => $data->getChannel(), 'package' => strtolower($data->getPackage()), ))]->getData(); } } $packages = $ret; return; } /** * Detect recursive links between dependencies and break the cycles * * @param array * @access private */ function _detectDepCycle(&$deplinks) { do { $keepgoing = false; foreach ($deplinks as $dep => $parents) { foreach ($parents as $parent => $unused) { // reset the parent cycle detector $this->_testCycle(null, null, null); if ($this->_testCycle($dep, $deplinks, $parent)) { $keepgoing = true; unset($deplinks[$dep][$parent]); if (count($deplinks[$dep]) == 0) { unset($deplinks[$dep]); } continue 3; } } } } while ($keepgoing); } function _testCycle($test, $deplinks, $dep) { static $visited = array(); if ($test === null) { $visited = array(); return; } // this happens when a parent has a dep cycle on another dependency // but the child is not part of the cycle if (isset($visited[$dep])) { return false; } $visited[$dep] = 1; if ($test == $dep) { return true; } if (isset($deplinks[$dep])) { if (in_array($test, array_keys($deplinks[$dep]), true)) { return true; } foreach ($deplinks[$dep] as $parent => $unused) { if ($this->_testCycle($test, $deplinks, $parent)) { return true; } } } return false; } /** * Set up the dependency for installation parsing * * @param array $t dependency information * @param PEAR_Registry $reg * @param array $deplinks list of dependency links already established * @param array $nodes all existing package nodes * @param string $package parent package name * @access private */ function _setupGraph($t, $reg, &$deplinks, &$nodes, $package) { foreach ($t as $dep) { $depchannel = !isset($dep['channel']) ? '__uri': $dep['channel']; $dname = $reg->parsedPackageNameToString( array( 'channel' => $depchannel, 'package' => strtolower($dep['name']), )); if (isset($nodes[$dname])) { if (!isset($deplinks[$dname])) { $deplinks[$dname] = array(); } $deplinks[$dname][$package] = 1; } } } function _dependsOn($a, $b) { return $this->_checkDepTree(strtolower($a->getChannel()), strtolower($a->getPackage()), $b); } function _checkDepTree($channel, $package, $b, $checked = array()) { $checked[$channel][$package] = true; if (!isset($this->_depTree[$channel][$package])) { return false; } if (isset($this->_depTree[$channel][$package][strtolower($b->getChannel())] [strtolower($b->getPackage())])) { return true; } foreach ($this->_depTree[$channel][$package] as $ch => $packages) { foreach ($packages as $pa => $true) { if ($this->_checkDepTree($ch, $pa, $b, $checked)) { return true; } } } return false; } function _sortInstall($a, $b) { if (!$a->getDeps() && !$b->getDeps()) { return 0; // neither package has dependencies, order is insignificant } if ($a->getDeps() && !$b->getDeps()) { return 1; // $a must be installed after $b because $a has dependencies } if (!$a->getDeps() && $b->getDeps()) { return -1; // $b must be installed after $a because $b has dependencies } // both packages have dependencies if ($this->_dependsOn($a, $b)) { return 1; } if ($this->_dependsOn($b, $a)) { return -1; } return 0; } /** * Download a file through HTTP. Considers suggested file name in * Content-disposition: header and can run a callback function for * different events. The callback will be called with two * parameters: the callback type, and parameters. The implemented * callback types are: * * 'setup' called at the very beginning, parameter is a UI object * that should be used for all output * 'message' the parameter is a string with an informational message * 'saveas' may be used to save with a different file name, the * parameter is the filename that is about to be used. * If a 'saveas' callback returns a non-empty string, * that file name will be used as the filename instead. * Note that $save_dir will not be affected by this, only * the basename of the file. * 'start' download is starting, parameter is number of bytes * that are expected, or -1 if unknown * 'bytesread' parameter is the number of bytes read so far * 'done' download is complete, parameter is the total number * of bytes read * 'connfailed' if the TCP/SSL connection fails, this callback is called * with array(host,port,errno,errmsg) * 'writefailed' if writing to disk fails, this callback is called * with array(destfile,errmsg) * * If an HTTP proxy has been configured (http_proxy PEAR_Config * setting), the proxy will be used. * * @param string $url the URL to download * @param object $ui PEAR_Frontend_* instance * @param object $config PEAR_Config instance * @param string $save_dir directory to save file in * @param mixed $callback function/method to call for status * updates * @param false|string|array $lastmodified header values to check against for caching * use false to return the header values from this download * @param false|array $accept Accept headers to send * @param false|string $channel Channel to use for retrieving authentication * @return mixed Returns the full path of the downloaded file or a PEAR * error on failure. If the error is caused by * socket-related errors, the error object will * have the fsockopen error code available through * getCode(). If caching is requested, then return the header * values. * If $lastmodified was given and the there are no changes, * boolean false is returned. * * @access public */ public static function _downloadHttp( $object, $url, &$ui, $save_dir = '.', $callback = null, $lastmodified = null, $accept = false, $channel = false ) { static $redirect = 0; // always reset , so we are clean case of error $wasredirect = $redirect; $redirect = 0; if ($callback) { call_user_func($callback, 'setup', array(&$ui)); } $info = parse_url($url); if (!isset($info['scheme']) || !in_array($info['scheme'], array('http', 'https'))) { return PEAR::raiseError('Cannot download non-http URL "' . $url . '"'); } if (!isset($info['host'])) { return PEAR::raiseError('Cannot download from non-URL "' . $url . '"'); } $host = isset($info['host']) ? $info['host'] : null; $port = isset($info['port']) ? $info['port'] : null; $path = isset($info['path']) ? $info['path'] : null; if ($object !== null) { $config = $object->config; } else { $config = &PEAR_Config::singleton(); } $proxy = new PEAR_Proxy($config); if ($proxy->isProxyConfigured() && $callback) { call_user_func($callback, 'message', "Using HTTP proxy $host:$port"); } if (empty($port)) { $port = (isset($info['scheme']) && $info['scheme'] == 'https') ? 443 : 80; } $scheme = (isset($info['scheme']) && $info['scheme'] == 'https') ? 'https' : 'http'; $secure = ($scheme == 'https'); $fp = $proxy->openSocket($host, $port, $secure); if (PEAR::isError($fp)) { if ($callback) { $errno = $fp->getCode(); $errstr = $fp->getMessage(); call_user_func($callback, 'connfailed', array($host, $port, $errno, $errstr)); } return $fp; } $requestPath = $path; if ($proxy->isProxyConfigured()) { $requestPath = $url; } if ($lastmodified === false || $lastmodified) { $request = "GET $requestPath HTTP/1.1\r\n"; } else { $request = "GET $requestPath HTTP/1.0\r\n"; } $request .= "Host: $host\r\n"; $ifmodifiedsince = ''; if (is_array($lastmodified)) { if (isset($lastmodified['Last-Modified'])) { $ifmodifiedsince = 'If-Modified-Since: ' . $lastmodified['Last-Modified'] . "\r\n"; } if (isset($lastmodified['ETag'])) { $ifmodifiedsince .= "If-None-Match: $lastmodified[ETag]\r\n"; } } else { $ifmodifiedsince = ($lastmodified ? "If-Modified-Since: $lastmodified\r\n" : ''); } $request .= $ifmodifiedsince . "User-Agent: PEAR/1.10.16/PHP/" . PHP_VERSION . "\r\n"; if ($object !== null) { // only pass in authentication for non-static calls $username = $config->get('username', null, $channel); $password = $config->get('password', null, $channel); if ($username && $password) { $tmp = base64_encode("$username:$password"); $request .= "Authorization: Basic $tmp\r\n"; } } $proxyAuth = $proxy->getProxyAuth(); if ($proxyAuth) { $request .= 'Proxy-Authorization: Basic ' . $proxyAuth . "\r\n"; } if ($accept) { $request .= 'Accept: ' . implode(', ', $accept) . "\r\n"; } $request .= "Connection: close\r\n"; $request .= "\r\n"; fwrite($fp, $request); $headers = array(); $reply = 0; while (trim($line = fgets($fp, 1024))) { if (preg_match('/^([^:]+):\s+(.*)\s*\\z/', $line, $matches)) { $headers[strtolower($matches[1])] = trim($matches[2]); } elseif (preg_match('|^HTTP/1.[01] ([0-9]{3}) |', $line, $matches)) { $reply = (int)$matches[1]; if ($reply == 304 && ($lastmodified || ($lastmodified === false))) { return false; } if (!in_array($reply, array(200, 301, 302, 303, 305, 307))) { return PEAR::raiseError("File $scheme://$host:$port$path not valid (received: $line)"); } } } if ($reply != 200) { if (!isset($headers['location'])) { return PEAR::raiseError("File $scheme://$host:$port$path not valid (redirected but no location)"); } if ($wasredirect > 4) { return PEAR::raiseError("File $scheme://$host:$port$path not valid (redirection looped more than 5 times)"); } $redirect = $wasredirect + 1; return static::_downloadHttp($object, $headers['location'], $ui, $save_dir, $callback, $lastmodified, $accept); } if (isset($headers['content-disposition']) && preg_match('/\sfilename=\"([^;]*\S)\"\s*(;|\\z)/', $headers['content-disposition'], $matches)) { $save_as = basename($matches[1]); } else { $save_as = basename($url); } if ($callback) { $tmp = call_user_func($callback, 'saveas', $save_as); if ($tmp) { $save_as = $tmp; } } $dest_file = $save_dir . DIRECTORY_SEPARATOR . $save_as; if (is_link($dest_file)) { return PEAR::raiseError('SECURITY ERROR: Will not write to ' . $dest_file . ' as it is symlinked to ' . readlink($dest_file) . ' - Possible symlink attack'); } if (!$wp = @fopen($dest_file, 'wb')) { fclose($fp); if ($callback) { call_user_func($callback, 'writefailed', array($dest_file, error_get_last()["message"])); } return PEAR::raiseError("could not open $dest_file for writing"); } $length = isset($headers['content-length']) ? $headers['content-length'] : -1; $bytes = 0; if ($callback) { call_user_func($callback, 'start', array(basename($dest_file), $length)); } while ($data = fread($fp, 1024)) { $bytes += strlen($data); if ($callback) { call_user_func($callback, 'bytesread', $bytes); } if (!@fwrite($wp, $data)) { fclose($fp); if ($callback) { call_user_func($callback, 'writefailed', array($dest_file, error_get_last()["message"])); } return PEAR::raiseError( "$dest_file: write failed (" . error_get_last()["message"] . ")"); } } fclose($fp); fclose($wp); if ($callback) { call_user_func($callback, 'done', $bytes); } if ($lastmodified === false || $lastmodified) { if (isset($headers['etag'])) { $lastmodified = array('ETag' => $headers['etag']); } if (isset($headers['last-modified'])) { if (is_array($lastmodified)) { $lastmodified['Last-Modified'] = $headers['last-modified']; } else { $lastmodified = $headers['last-modified']; } } return array($dest_file, $lastmodified, $headers); } return $dest_file; } } PKu]r"PEAR/ChannelFile.phpnu[ * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ /** * Needed for error handling */ require_once 'PEAR/ErrorStack.php'; require_once 'PEAR/XMLParser.php'; require_once 'PEAR/Common.php'; /** * Error code if the channel.xml tag does not contain a valid version */ define('PEAR_CHANNELFILE_ERROR_NO_VERSION', 1); /** * Error code if the channel.xml tag version is not supported (version 1.0 is the only supported version, * currently */ define('PEAR_CHANNELFILE_ERROR_INVALID_VERSION', 2); /** * Error code if parsing is attempted with no xml extension */ define('PEAR_CHANNELFILE_ERROR_NO_XML_EXT', 3); /** * Error code if creating the xml parser resource fails */ define('PEAR_CHANNELFILE_ERROR_CANT_MAKE_PARSER', 4); /** * Error code used for all sax xml parsing errors */ define('PEAR_CHANNELFILE_ERROR_PARSER_ERROR', 5); /**#@+ * Validation errors */ /** * Error code when channel name is missing */ define('PEAR_CHANNELFILE_ERROR_NO_NAME', 6); /** * Error code when channel name is invalid */ define('PEAR_CHANNELFILE_ERROR_INVALID_NAME', 7); /** * Error code when channel summary is missing */ define('PEAR_CHANNELFILE_ERROR_NO_SUMMARY', 8); /** * Error code when channel summary is multi-line */ define('PEAR_CHANNELFILE_ERROR_MULTILINE_SUMMARY', 9); /** * Error code when channel server is missing for protocol */ define('PEAR_CHANNELFILE_ERROR_NO_HOST', 10); /** * Error code when channel server is invalid for protocol */ define('PEAR_CHANNELFILE_ERROR_INVALID_HOST', 11); /** * Error code when a mirror name is invalid */ define('PEAR_CHANNELFILE_ERROR_INVALID_MIRROR', 21); /** * Error code when a mirror type is invalid */ define('PEAR_CHANNELFILE_ERROR_INVALID_MIRRORTYPE', 22); /** * Error code when an attempt is made to generate xml, but the parsed content is invalid */ define('PEAR_CHANNELFILE_ERROR_INVALID', 23); /** * Error code when an empty package name validate regex is passed in */ define('PEAR_CHANNELFILE_ERROR_EMPTY_REGEX', 24); /** * Error code when a tag has no version */ define('PEAR_CHANNELFILE_ERROR_NO_FUNCTIONVERSION', 25); /** * Error code when a tag has no name */ define('PEAR_CHANNELFILE_ERROR_NO_FUNCTIONNAME', 26); /** * Error code when a tag has no name */ define('PEAR_CHANNELFILE_ERROR_NOVALIDATE_NAME', 27); /** * Error code when a tag has no version attribute */ define('PEAR_CHANNELFILE_ERROR_NOVALIDATE_VERSION', 28); /** * Error code when a mirror does not exist but is called for in one of the set* * methods. */ define('PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND', 32); /** * Error code when a server port is not numeric */ define('PEAR_CHANNELFILE_ERROR_INVALID_PORT', 33); /** * Error code when contains no version attribute */ define('PEAR_CHANNELFILE_ERROR_NO_STATICVERSION', 34); /** * Error code when contains no type attribute in a protocol definition */ define('PEAR_CHANNELFILE_ERROR_NOBASEURLTYPE', 35); /** * Error code when a mirror is defined and the channel.xml represents the __uri pseudo-channel */ define('PEAR_CHANNELFILE_URI_CANT_MIRROR', 36); /** * Error code when ssl attribute is present and is not "yes" */ define('PEAR_CHANNELFILE_ERROR_INVALID_SSL', 37); /**#@-*/ /** * Mirror types allowed. Currently only internet servers are recognized. */ $GLOBALS['_PEAR_CHANNELS_MIRROR_TYPES'] = array('server'); /** * The Channel handling class * * @category pear * @package PEAR * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ class PEAR_ChannelFile { /** * @access private * @var PEAR_ErrorStack * @access private */ var $_stack; /** * Supported channel.xml versions, for parsing * @var array * @access private */ var $_supportedVersions = array('1.0'); /** * Parsed channel information * @var array * @access private */ var $_channelInfo; /** * index into the subchannels array, used for parsing xml * @var int * @access private */ var $_subchannelIndex; /** * index into the mirrors array, used for parsing xml * @var int * @access private */ var $_mirrorIndex; /** * Flag used to determine the validity of parsed content * @var boolean * @access private */ var $_isValid = false; function __construct() { $this->_stack = new PEAR_ErrorStack('PEAR_ChannelFile'); $this->_stack->setErrorMessageTemplate($this->_getErrorMessage()); $this->_isValid = false; } /** * @return array * @access protected */ function _getErrorMessage() { return array( PEAR_CHANNELFILE_ERROR_INVALID_VERSION => 'While parsing channel.xml, an invalid version number "%version% was passed in, expecting one of %versions%', PEAR_CHANNELFILE_ERROR_NO_VERSION => 'No version number found in tag', PEAR_CHANNELFILE_ERROR_NO_XML_EXT => '%error%', PEAR_CHANNELFILE_ERROR_CANT_MAKE_PARSER => 'Unable to create XML parser', PEAR_CHANNELFILE_ERROR_PARSER_ERROR => '%error%', PEAR_CHANNELFILE_ERROR_NO_NAME => 'Missing channel name', PEAR_CHANNELFILE_ERROR_INVALID_NAME => 'Invalid channel %tag% "%name%"', PEAR_CHANNELFILE_ERROR_NO_SUMMARY => 'Missing channel summary', PEAR_CHANNELFILE_ERROR_MULTILINE_SUMMARY => 'Channel summary should be on one line, but is multi-line', PEAR_CHANNELFILE_ERROR_NO_HOST => 'Missing channel server for %type% server', PEAR_CHANNELFILE_ERROR_INVALID_HOST => 'Server name "%server%" is invalid for %type% server', PEAR_CHANNELFILE_ERROR_INVALID_MIRROR => 'Invalid mirror name "%name%", mirror type %type%', PEAR_CHANNELFILE_ERROR_INVALID_MIRRORTYPE => 'Invalid mirror type "%type%"', PEAR_CHANNELFILE_ERROR_INVALID => 'Cannot generate xml, contents are invalid', PEAR_CHANNELFILE_ERROR_EMPTY_REGEX => 'packagenameregex cannot be empty', PEAR_CHANNELFILE_ERROR_NO_FUNCTIONVERSION => '%parent% %protocol% function has no version', PEAR_CHANNELFILE_ERROR_NO_FUNCTIONNAME => '%parent% %protocol% function has no name', PEAR_CHANNELFILE_ERROR_NOBASEURLTYPE => '%parent% rest baseurl has no type', PEAR_CHANNELFILE_ERROR_NOVALIDATE_NAME => 'Validation package has no name in tag', PEAR_CHANNELFILE_ERROR_NOVALIDATE_VERSION => 'Validation package "%package%" has no version', PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND => 'Mirror "%mirror%" does not exist', PEAR_CHANNELFILE_ERROR_INVALID_PORT => 'Port "%port%" must be numeric', PEAR_CHANNELFILE_ERROR_NO_STATICVERSION => ' tag must contain version attribute', PEAR_CHANNELFILE_URI_CANT_MIRROR => 'The __uri pseudo-channel cannot have mirrors', PEAR_CHANNELFILE_ERROR_INVALID_SSL => '%server% has invalid ssl attribute "%ssl%" can only be yes or not present', ); } /** * @param string contents of package.xml file * @return bool success of parsing */ function fromXmlString($data) { if (preg_match('/_supportedVersions)) { $this->_stack->push(PEAR_CHANNELFILE_ERROR_INVALID_VERSION, 'error', array('version' => $channelversion[1])); return false; } $parser = new PEAR_XMLParser; $result = $parser->parse($data); if ($result !== true) { if ($result->getCode() == 1) { $this->_stack->push(PEAR_CHANNELFILE_ERROR_NO_XML_EXT, 'error', array('error' => $result->getMessage())); } else { $this->_stack->push(PEAR_CHANNELFILE_ERROR_CANT_MAKE_PARSER, 'error'); } return false; } $this->_channelInfo = $parser->getData(); return true; } else { $this->_stack->push(PEAR_CHANNELFILE_ERROR_NO_VERSION, 'error', array('xml' => $data)); return false; } } /** * @return array */ function toArray() { if (!$this->_isValid && !$this->validate()) { return false; } return $this->_channelInfo; } /** * @param array * * @return PEAR_ChannelFile|false false if invalid */ public static function &fromArray( $data, $compatibility = false, $stackClass = 'PEAR_ErrorStack' ) { $a = new PEAR_ChannelFile($compatibility, $stackClass); $a->_fromArray($data); if (!$a->validate()) { $a = false; return $a; } return $a; } /** * Unlike {@link fromArray()} this does not do any validation * * @param array * * @return PEAR_ChannelFile */ public static function &fromArrayWithErrors( $data, $compatibility = false, $stackClass = 'PEAR_ErrorStack' ) { $a = new PEAR_ChannelFile($compatibility, $stackClass); $a->_fromArray($data); return $a; } /** * @param array * @access private */ function _fromArray($data) { $this->_channelInfo = $data; } /** * Wrapper to {@link PEAR_ErrorStack::getErrors()} * @param boolean determines whether to purge the error stack after retrieving * @return array */ function getErrors($purge = false) { return $this->_stack->getErrors($purge); } /** * Unindent given string (?) * * @param string $str The string that has to be unindented. * @return string * @access private */ function _unIndent($str) { // remove leading newlines $str = preg_replace('/^[\r\n]+/', '', $str); // find whitespace at the beginning of the first line $indent_len = strspn($str, " \t"); $indent = substr($str, 0, $indent_len); $data = ''; // remove the same amount of whitespace from following lines foreach (explode("\n", $str) as $line) { if (substr($line, 0, $indent_len) == $indent) { $data .= substr($line, $indent_len) . "\n"; } } return $data; } /** * Parse a channel.xml file. Expects the name of * a channel xml file as input. * * @param string $descfile name of channel xml file * @return bool success of parsing */ function fromXmlFile($descfile) { if (!file_exists($descfile) || !is_file($descfile) || !is_readable($descfile) || (!$fp = fopen($descfile, 'r'))) { require_once 'PEAR.php'; return PEAR::raiseError("Unable to open $descfile"); } // read the whole thing so we only get one cdata callback // for each block of cdata fclose($fp); $data = file_get_contents($descfile); return $this->fromXmlString($data); } /** * Parse channel information from different sources * * This method is able to extract information about a channel * from an .xml file or a string * * @access public * @param string Filename of the source or the source itself * @return bool */ function fromAny($info) { if (is_string($info) && file_exists($info) && strlen($info) < 255) { $tmp = substr($info, -4); if ($tmp == '.xml') { $info = $this->fromXmlFile($info); } else { $fp = fopen($info, "r"); $test = fread($fp, 5); fclose($fp); if ($test == "fromXmlFile($info); } } if (PEAR::isError($info)) { require_once 'PEAR.php'; return PEAR::raiseError($info); } } if (is_string($info)) { $info = $this->fromXmlString($info); } return $info; } /** * Return an XML document based on previous parsing and modifications * * @return string XML data * * @access public */ function toXml() { if (!$this->_isValid && !$this->validate()) { $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID); return false; } if (!isset($this->_channelInfo['attribs']['version'])) { $this->_channelInfo['attribs']['version'] = '1.0'; } $channelInfo = $this->_channelInfo; $ret = "\n"; $ret .= " $channelInfo[name] " . htmlspecialchars($channelInfo['summary'])." "; if (isset($channelInfo['suggestedalias'])) { $ret .= ' ' . $channelInfo['suggestedalias'] . "\n"; } if (isset($channelInfo['validatepackage'])) { $ret .= ' ' . htmlspecialchars($channelInfo['validatepackage']['_content']) . "\n"; } $ret .= " \n"; $ret .= ' _makeRestXml($channelInfo['servers']['primary']['rest'], ' '); } $ret .= " \n"; if (isset($channelInfo['servers']['mirror'])) { $ret .= $this->_makeMirrorsXml($channelInfo); } $ret .= " \n"; $ret .= ""; return str_replace("\r", "\n", str_replace("\r\n", "\n", $ret)); } /** * Generate the tag * @access private */ function _makeRestXml($info, $indent) { $ret = $indent . "\n"; if (isset($info['baseurl']) && !isset($info['baseurl'][0])) { $info['baseurl'] = array($info['baseurl']); } if (isset($info['baseurl'])) { foreach ($info['baseurl'] as $url) { $ret .= "$indent \n"; } } $ret .= $indent . "\n"; return $ret; } /** * Generate the tag * @access private */ function _makeMirrorsXml($channelInfo) { $ret = ""; if (!isset($channelInfo['servers']['mirror'][0])) { $channelInfo['servers']['mirror'] = array($channelInfo['servers']['mirror']); } foreach ($channelInfo['servers']['mirror'] as $mirror) { $ret .= ' _makeRestXml($mirror['rest'], ' '); } $ret .= " \n"; } else { $ret .= "/>\n"; } } return $ret; } /** * Generate the tag * @access private */ function _makeFunctionsXml($functions, $indent, $rest = false) { $ret = ''; if (!isset($functions[0])) { $functions = array($functions); } foreach ($functions as $function) { $ret .= "$indent\n"; } return $ret; } /** * Validation error. Also marks the object contents as invalid * @param error code * @param array error information * @access private */ function _validateError($code, $params = array()) { $this->_stack->push($code, 'error', $params); $this->_isValid = false; } /** * Validation warning. Does not mark the object contents invalid. * @param error code * @param array error information * @access private */ function _validateWarning($code, $params = array()) { $this->_stack->push($code, 'warning', $params); } /** * Validate parsed file. * * @access public * @return boolean */ function validate() { $this->_isValid = true; $info = $this->_channelInfo; if (empty($info['name'])) { $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_NAME); } elseif (!$this->validChannelServer($info['name'])) { if ($info['name'] != '__uri') { $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_NAME, array('tag' => 'name', 'name' => $info['name'])); } } if (empty($info['summary'])) { $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_SUMMARY); } elseif (strpos(trim($info['summary']), "\n") !== false) { $this->_validateWarning(PEAR_CHANNELFILE_ERROR_MULTILINE_SUMMARY, array('summary' => $info['summary'])); } if (isset($info['suggestedalias'])) { if (!$this->validChannelServer($info['suggestedalias'])) { $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_NAME, array('tag' => 'suggestedalias', 'name' =>$info['suggestedalias'])); } } if (isset($info['localalias'])) { if (!$this->validChannelServer($info['localalias'])) { $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_NAME, array('tag' => 'localalias', 'name' =>$info['localalias'])); } } if (isset($info['validatepackage'])) { if (!isset($info['validatepackage']['_content'])) { $this->_validateError(PEAR_CHANNELFILE_ERROR_NOVALIDATE_NAME); } if (!isset($info['validatepackage']['attribs']['version'])) { $content = isset($info['validatepackage']['_content']) ? $info['validatepackage']['_content'] : null; $this->_validateError(PEAR_CHANNELFILE_ERROR_NOVALIDATE_VERSION, array('package' => $content)); } } if (isset($info['servers']['primary']['attribs'], $info['servers']['primary']['attribs']['port']) && !is_numeric($info['servers']['primary']['attribs']['port'])) { $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_PORT, array('port' => $info['servers']['primary']['attribs']['port'])); } if (isset($info['servers']['primary']['attribs'], $info['servers']['primary']['attribs']['ssl']) && $info['servers']['primary']['attribs']['ssl'] != 'yes') { $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_SSL, array('ssl' => $info['servers']['primary']['attribs']['ssl'], 'server' => $info['name'])); } if (isset($info['servers']['primary']['rest']) && isset($info['servers']['primary']['rest']['baseurl'])) { $this->_validateFunctions('rest', $info['servers']['primary']['rest']['baseurl']); } if (isset($info['servers']['mirror'])) { if ($this->_channelInfo['name'] == '__uri') { $this->_validateError(PEAR_CHANNELFILE_URI_CANT_MIRROR); } if (!isset($info['servers']['mirror'][0])) { $info['servers']['mirror'] = array($info['servers']['mirror']); } foreach ($info['servers']['mirror'] as $mirror) { if (!isset($mirror['attribs']['host'])) { $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_HOST, array('type' => 'mirror')); } elseif (!$this->validChannelServer($mirror['attribs']['host'])) { $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_HOST, array('server' => $mirror['attribs']['host'], 'type' => 'mirror')); } if (isset($mirror['attribs']['ssl']) && $mirror['attribs']['ssl'] != 'yes') { $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_SSL, array('ssl' => $info['ssl'], 'server' => $mirror['attribs']['host'])); } if (isset($mirror['rest'])) { $this->_validateFunctions('rest', $mirror['rest']['baseurl'], $mirror['attribs']['host']); } } } return $this->_isValid; } /** * @param string rest - protocol name this function applies to * @param array the functions * @param string the name of the parent element (mirror name, for instance) */ function _validateFunctions($protocol, $functions, $parent = '') { if (!isset($functions[0])) { $functions = array($functions); } foreach ($functions as $function) { if (!isset($function['_content']) || empty($function['_content'])) { $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_FUNCTIONNAME, array('parent' => $parent, 'protocol' => $protocol)); } if ($protocol == 'rest') { if (!isset($function['attribs']['type']) || empty($function['attribs']['type'])) { $this->_validateError(PEAR_CHANNELFILE_ERROR_NOBASEURLTYPE, array('parent' => $parent, 'protocol' => $protocol)); } } else { if (!isset($function['attribs']['version']) || empty($function['attribs']['version'])) { $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_FUNCTIONVERSION, array('parent' => $parent, 'protocol' => $protocol)); } } } } /** * Test whether a string contains a valid channel server. * @param string $ver the package version to test * @return bool */ function validChannelServer($server) { if ($server == '__uri') { return true; } return (bool) preg_match(PEAR_CHANNELS_SERVER_PREG, $server); } /** * @return string|false */ function getName() { if (isset($this->_channelInfo['name'])) { return $this->_channelInfo['name']; } return false; } /** * @return string|false */ function getServer() { if (isset($this->_channelInfo['name'])) { return $this->_channelInfo['name']; } return false; } /** * @return int|80 port number to connect to */ function getPort($mirror = false) { if ($mirror) { if ($mir = $this->getMirror($mirror)) { if (isset($mir['attribs']['port'])) { return $mir['attribs']['port']; } if ($this->getSSL($mirror)) { return 443; } return 80; } return false; } if (isset($this->_channelInfo['servers']['primary']['attribs']['port'])) { return $this->_channelInfo['servers']['primary']['attribs']['port']; } if ($this->getSSL()) { return 443; } return 80; } /** * @return bool Determines whether secure sockets layer (SSL) is used to connect to this channel */ function getSSL($mirror = false) { if ($mirror) { if ($mir = $this->getMirror($mirror)) { if (isset($mir['attribs']['ssl'])) { return true; } return false; } return false; } if (isset($this->_channelInfo['servers']['primary']['attribs']['ssl'])) { return true; } return false; } /** * @return string|false */ function getSummary() { if (isset($this->_channelInfo['summary'])) { return $this->_channelInfo['summary']; } return false; } /** * @param string protocol type * @param string Mirror name * @return array|false */ function getFunctions($protocol, $mirror = false) { if ($this->getName() == '__uri') { return false; } $function = $protocol == 'rest' ? 'baseurl' : 'function'; if ($mirror) { if ($mir = $this->getMirror($mirror)) { if (isset($mir[$protocol][$function])) { return $mir[$protocol][$function]; } } return false; } if (isset($this->_channelInfo['servers']['primary'][$protocol][$function])) { return $this->_channelInfo['servers']['primary'][$protocol][$function]; } return false; } /** * @param string Protocol type * @param string Function name (null to return the * first protocol of the type requested) * @param string Mirror name, if any * @return array */ function getFunction($type, $name = null, $mirror = false) { $protocols = $this->getFunctions($type, $mirror); if (!$protocols) { return false; } foreach ($protocols as $protocol) { if ($name === null) { return $protocol; } if ($protocol['_content'] != $name) { continue; } return $protocol; } return false; } /** * @param string protocol type * @param string protocol name * @param string version * @param string mirror name * @return boolean */ function supports($type, $name = null, $mirror = false, $version = '1.0') { $protocols = $this->getFunctions($type, $mirror); if (!$protocols) { return false; } foreach ($protocols as $protocol) { if ($protocol['attribs']['version'] != $version) { continue; } if ($name === null) { return true; } if ($protocol['_content'] != $name) { continue; } return true; } return false; } /** * Determines whether a channel supports Representational State Transfer (REST) protocols * for retrieving channel information * @param string * @return bool */ function supportsREST($mirror = false) { if ($mirror == $this->_channelInfo['name']) { $mirror = false; } if ($mirror) { if ($mir = $this->getMirror($mirror)) { return isset($mir['rest']); } return false; } return isset($this->_channelInfo['servers']['primary']['rest']); } /** * Get the URL to access a base resource. * * Hyperlinks in the returned xml will be used to retrieve the proper information * needed. This allows extreme extensibility and flexibility in implementation * @param string Resource Type to retrieve */ function getBaseURL($resourceType, $mirror = false) { if ($mirror == $this->_channelInfo['name']) { $mirror = false; } if ($mirror) { $mir = $this->getMirror($mirror); if (!$mir) { return false; } $rest = $mir['rest']; } else { $rest = $this->_channelInfo['servers']['primary']['rest']; } if (!isset($rest['baseurl'][0])) { $rest['baseurl'] = array($rest['baseurl']); } foreach ($rest['baseurl'] as $baseurl) { if (strtolower($baseurl['attribs']['type']) == strtolower($resourceType)) { return $baseurl['_content']; } } return false; } /** * Since REST does not implement RPC, provide this as a logical wrapper around * resetFunctions for REST * @param string|false mirror name, if any */ function resetREST($mirror = false) { return $this->resetFunctions('rest', $mirror); } /** * Empty all protocol definitions * @param string protocol type * @param string|false mirror name, if any */ function resetFunctions($type, $mirror = false) { if ($mirror) { if (isset($this->_channelInfo['servers']['mirror'])) { $mirrors = $this->_channelInfo['servers']['mirror']; if (!isset($mirrors[0])) { $mirrors = array($mirrors); } foreach ($mirrors as $i => $mir) { if ($mir['attribs']['host'] == $mirror) { if (isset($this->_channelInfo['servers']['mirror'][$i][$type])) { unset($this->_channelInfo['servers']['mirror'][$i][$type]); } return true; } } return false; } return false; } if (isset($this->_channelInfo['servers']['primary'][$type])) { unset($this->_channelInfo['servers']['primary'][$type]); } return true; } /** * Set a channel's protocols to the protocols supported by pearweb */ function setDefaultPEARProtocols($version = '1.0', $mirror = false) { switch ($version) { case '1.0' : $this->resetREST($mirror); if (!isset($this->_channelInfo['servers'])) { $this->_channelInfo['servers'] = array('primary' => array('rest' => array())); } elseif (!isset($this->_channelInfo['servers']['primary'])) { $this->_channelInfo['servers']['primary'] = array('rest' => array()); } return true; break; default : return false; break; } } /** * @return array */ function getMirrors() { if (isset($this->_channelInfo['servers']['mirror'])) { $mirrors = $this->_channelInfo['servers']['mirror']; if (!isset($mirrors[0])) { $mirrors = array($mirrors); } return $mirrors; } return array(); } /** * Get the unserialized XML representing a mirror * @return array|false */ function getMirror($server) { foreach ($this->getMirrors() as $mirror) { if ($mirror['attribs']['host'] == $server) { return $mirror; } } return false; } /** * @param string * @return string|false * @error PEAR_CHANNELFILE_ERROR_NO_NAME * @error PEAR_CHANNELFILE_ERROR_INVALID_NAME */ function setName($name) { return $this->setServer($name); } /** * Set the socket number (port) that is used to connect to this channel * @param integer * @param string|false name of the mirror server, or false for the primary */ function setPort($port, $mirror = false) { if ($mirror) { if (!isset($this->_channelInfo['servers']['mirror'])) { $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND, array('mirror' => $mirror)); return false; } if (isset($this->_channelInfo['servers']['mirror'][0])) { foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) { if ($mirror == $mir['attribs']['host']) { $this->_channelInfo['servers']['mirror'][$i]['attribs']['port'] = $port; return true; } } return false; } elseif ($this->_channelInfo['servers']['mirror']['attribs']['host'] == $mirror) { $this->_channelInfo['servers']['mirror']['attribs']['port'] = $port; $this->_isValid = false; return true; } } $this->_channelInfo['servers']['primary']['attribs']['port'] = $port; $this->_isValid = false; return true; } /** * Set the socket number (port) that is used to connect to this channel * @param bool Determines whether to turn on SSL support or turn it off * @param string|false name of the mirror server, or false for the primary */ function setSSL($ssl = true, $mirror = false) { if ($mirror) { if (!isset($this->_channelInfo['servers']['mirror'])) { $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND, array('mirror' => $mirror)); return false; } if (isset($this->_channelInfo['servers']['mirror'][0])) { foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) { if ($mirror == $mir['attribs']['host']) { if (!$ssl) { if (isset($this->_channelInfo['servers']['mirror'][$i] ['attribs']['ssl'])) { unset($this->_channelInfo['servers']['mirror'][$i]['attribs']['ssl']); } } else { $this->_channelInfo['servers']['mirror'][$i]['attribs']['ssl'] = 'yes'; } return true; } } return false; } elseif ($this->_channelInfo['servers']['mirror']['attribs']['host'] == $mirror) { if (!$ssl) { if (isset($this->_channelInfo['servers']['mirror']['attribs']['ssl'])) { unset($this->_channelInfo['servers']['mirror']['attribs']['ssl']); } } else { $this->_channelInfo['servers']['mirror']['attribs']['ssl'] = 'yes'; } $this->_isValid = false; return true; } } if ($ssl) { $this->_channelInfo['servers']['primary']['attribs']['ssl'] = 'yes'; } else { if (isset($this->_channelInfo['servers']['primary']['attribs']['ssl'])) { unset($this->_channelInfo['servers']['primary']['attribs']['ssl']); } } $this->_isValid = false; return true; } /** * @param string * @return string|false * @error PEAR_CHANNELFILE_ERROR_NO_SERVER * @error PEAR_CHANNELFILE_ERROR_INVALID_SERVER */ function setServer($server, $mirror = false) { if (empty($server)) { $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_SERVER); return false; } elseif (!$this->validChannelServer($server)) { $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_NAME, array('tag' => 'name', 'name' => $server)); return false; } if ($mirror) { $found = false; foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) { if ($mirror == $mir['attribs']['host']) { $found = true; break; } } if (!$found) { $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND, array('mirror' => $mirror)); return false; } $this->_channelInfo['mirror'][$i]['attribs']['host'] = $server; return true; } $this->_channelInfo['name'] = $server; return true; } /** * @param string * @return boolean success * @error PEAR_CHANNELFILE_ERROR_NO_SUMMARY * @warning PEAR_CHANNELFILE_ERROR_MULTILINE_SUMMARY */ function setSummary($summary) { if (empty($summary)) { $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_SUMMARY); return false; } elseif (strpos(trim($summary), "\n") !== false) { $this->_validateWarning(PEAR_CHANNELFILE_ERROR_MULTILINE_SUMMARY, array('summary' => $summary)); } $this->_channelInfo['summary'] = $summary; return true; } /** * @param string * @param boolean determines whether the alias is in channel.xml or local * @return boolean success */ function setAlias($alias, $local = false) { if (!$this->validChannelServer($alias)) { $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_NAME, array('tag' => 'suggestedalias', 'name' => $alias)); return false; } if ($local) { $this->_channelInfo['localalias'] = $alias; } else { $this->_channelInfo['suggestedalias'] = $alias; } return true; } /** * @return string */ function getAlias() { if (isset($this->_channelInfo['localalias'])) { return $this->_channelInfo['localalias']; } if (isset($this->_channelInfo['suggestedalias'])) { return $this->_channelInfo['suggestedalias']; } if (isset($this->_channelInfo['name'])) { return $this->_channelInfo['name']; } return ''; } /** * Set the package validation object if it differs from PEAR's default * The class must be includeable via changing _ in the classname to path separator, * but no checking of this is made. * @param string|false pass in false to reset to the default packagename regex * @return boolean success */ function setValidationPackage($validateclass, $version) { if (empty($validateclass)) { unset($this->_channelInfo['validatepackage']); } $this->_channelInfo['validatepackage'] = array('_content' => $validateclass); $this->_channelInfo['validatepackage']['attribs'] = array('version' => $version); } /** * Add a protocol to the provides section * @param string protocol type * @param string protocol version * @param string protocol name, if any * @param string mirror name, if this is a mirror's protocol * @return bool */ function addFunction($type, $version, $name = '', $mirror = false) { if ($mirror) { return $this->addMirrorFunction($mirror, $type, $version, $name); } $set = array('attribs' => array('version' => $version), '_content' => $name); if (!isset($this->_channelInfo['servers']['primary'][$type]['function'])) { if (!isset($this->_channelInfo['servers'])) { $this->_channelInfo['servers'] = array('primary' => array($type => array())); } elseif (!isset($this->_channelInfo['servers']['primary'])) { $this->_channelInfo['servers']['primary'] = array($type => array()); } $this->_channelInfo['servers']['primary'][$type]['function'] = $set; $this->_isValid = false; return true; } elseif (!isset($this->_channelInfo['servers']['primary'][$type]['function'][0])) { $this->_channelInfo['servers']['primary'][$type]['function'] = array( $this->_channelInfo['servers']['primary'][$type]['function']); } $this->_channelInfo['servers']['primary'][$type]['function'][] = $set; return true; } /** * Add a protocol to a mirror's provides section * @param string mirror name (server) * @param string protocol type * @param string protocol version * @param string protocol name, if any */ function addMirrorFunction($mirror, $type, $version, $name = '') { if (!isset($this->_channelInfo['servers']['mirror'])) { $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND, array('mirror' => $mirror)); return false; } $setmirror = false; if (isset($this->_channelInfo['servers']['mirror'][0])) { foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) { if ($mirror == $mir['attribs']['host']) { $setmirror = &$this->_channelInfo['servers']['mirror'][$i]; break; } } } else { if ($this->_channelInfo['servers']['mirror']['attribs']['host'] == $mirror) { $setmirror = &$this->_channelInfo['servers']['mirror']; } } if (!$setmirror) { $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND, array('mirror' => $mirror)); return false; } $set = array('attribs' => array('version' => $version), '_content' => $name); if (!isset($setmirror[$type]['function'])) { $setmirror[$type]['function'] = $set; $this->_isValid = false; return true; } elseif (!isset($setmirror[$type]['function'][0])) { $setmirror[$type]['function'] = array($setmirror[$type]['function']); } $setmirror[$type]['function'][] = $set; $this->_isValid = false; return true; } /** * @param string Resource Type this url links to * @param string URL * @param string|false mirror name, if this is not a primary server REST base URL */ function setBaseURL($resourceType, $url, $mirror = false) { if ($mirror) { if (!isset($this->_channelInfo['servers']['mirror'])) { $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND, array('mirror' => $mirror)); return false; } $setmirror = false; if (isset($this->_channelInfo['servers']['mirror'][0])) { foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) { if ($mirror == $mir['attribs']['host']) { $setmirror = &$this->_channelInfo['servers']['mirror'][$i]; break; } } } else { if ($this->_channelInfo['servers']['mirror']['attribs']['host'] == $mirror) { $setmirror = &$this->_channelInfo['servers']['mirror']; } } } else { $setmirror = &$this->_channelInfo['servers']['primary']; } $set = array('attribs' => array('type' => $resourceType), '_content' => $url); if (!isset($setmirror['rest'])) { $setmirror['rest'] = array(); } if (!isset($setmirror['rest']['baseurl'])) { $setmirror['rest']['baseurl'] = $set; $this->_isValid = false; return true; } elseif (!isset($setmirror['rest']['baseurl'][0])) { $setmirror['rest']['baseurl'] = array($setmirror['rest']['baseurl']); } foreach ($setmirror['rest']['baseurl'] as $i => $url) { if ($url['attribs']['type'] == $resourceType) { $this->_isValid = false; $setmirror['rest']['baseurl'][$i] = $set; return true; } } $setmirror['rest']['baseurl'][] = $set; $this->_isValid = false; return true; } /** * @param string mirror server * @param int mirror http port * @return boolean */ function addMirror($server, $port = null) { if ($this->_channelInfo['name'] == '__uri') { return false; // the __uri channel cannot have mirrors by definition } $set = array('attribs' => array('host' => $server)); if (is_numeric($port)) { $set['attribs']['port'] = $port; } if (!isset($this->_channelInfo['servers']['mirror'])) { $this->_channelInfo['servers']['mirror'] = $set; return true; } if (!isset($this->_channelInfo['servers']['mirror'][0])) { $this->_channelInfo['servers']['mirror'] = array($this->_channelInfo['servers']['mirror']); } $this->_channelInfo['servers']['mirror'][] = $set; return true; } /** * Retrieve the name of the validation package for this channel * @return string|false */ function getValidationPackage() { if (!$this->_isValid && !$this->validate()) { return false; } if (!isset($this->_channelInfo['validatepackage'])) { return array('attribs' => array('version' => 'default'), '_content' => 'PEAR_Validate'); } return $this->_channelInfo['validatepackage']; } /** * Retrieve the object that can be used for custom validation * @param string|false the name of the package to validate. If the package is * the channel validation package, PEAR_Validate is returned * @return PEAR_Validate|false false is returned if the validation package * cannot be located */ function &getValidationObject($package = false) { if (!class_exists('PEAR_Validate')) { require_once 'PEAR/Validate.php'; } if (!$this->_isValid) { if (!$this->validate()) { $a = false; return $a; } } if (isset($this->_channelInfo['validatepackage'])) { if ($package == $this->_channelInfo['validatepackage']) { // channel validation packages are always validated by PEAR_Validate $val = new PEAR_Validate; return $val; } if (!class_exists(str_replace('.', '_', $this->_channelInfo['validatepackage']['_content']))) { if ($this->isIncludeable(str_replace('_', '/', $this->_channelInfo['validatepackage']['_content']) . '.php')) { include_once str_replace('_', '/', $this->_channelInfo['validatepackage']['_content']) . '.php'; $vclass = str_replace('.', '_', $this->_channelInfo['validatepackage']['_content']); $val = new $vclass; } else { $a = false; return $a; } } else { $vclass = str_replace('.', '_', $this->_channelInfo['validatepackage']['_content']); $val = new $vclass; } } else { $val = new PEAR_Validate; } return $val; } function isIncludeable($path) { $possibilities = explode(PATH_SEPARATOR, ini_get('include_path')); foreach ($possibilities as $dir) { if (file_exists($dir . DIRECTORY_SEPARATOR . $path) && is_readable($dir . DIRECTORY_SEPARATOR . $path)) { return true; } } return false; } /** * This function is used by the channel updater and retrieves a value set by * the registry, or the current time if it has not been set * @return string */ function lastModified() { if (isset($this->_channelInfo['_lastmodified'])) { return $this->_channelInfo['_lastmodified']; } return time(); } } PKu]$((PEAR/Registry.phpnu[ * @author Tomas V. V. Cox * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 0.1 */ /** * for PEAR_Error */ require_once 'PEAR.php'; require_once 'PEAR/DependencyDB.php'; define('PEAR_REGISTRY_ERROR_LOCK', -2); define('PEAR_REGISTRY_ERROR_FORMAT', -3); define('PEAR_REGISTRY_ERROR_FILE', -4); define('PEAR_REGISTRY_ERROR_CONFLICT', -5); define('PEAR_REGISTRY_ERROR_CHANNEL_FILE', -6); /** * Administration class used to maintain the installed package database. * @category pear * @package PEAR * @author Stig Bakken * @author Tomas V. V. Cox * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ class PEAR_Registry extends PEAR { /** * File containing all channel information. * @var string */ var $channels = ''; /** Directory where registry files are stored. * @var string */ var $statedir = ''; /** File where the file map is stored * @var string */ var $filemap = ''; /** Directory where registry files for channels are stored. * @var string */ var $channelsdir = ''; /** Name of file used for locking the registry * @var string */ var $lockfile = ''; /** File descriptor used during locking * @var resource */ var $lock_fp = null; /** Mode used during locking * @var int */ var $lock_mode = 0; // XXX UNUSED /** Cache of package information. Structure: * array( * 'package' => array('id' => ... ), * ... ) * @var array */ var $pkginfo_cache = array(); /** Cache of file map. Structure: * array( '/path/to/file' => 'package', ... ) * @var array */ var $filemap_cache = array(); /** * @var false|PEAR_ChannelFile */ var $_pearChannel; /** * @var false|PEAR_ChannelFile */ var $_peclChannel; /** * @var false|PEAR_ChannelFile */ var $_docChannel; /** * @var PEAR_DependencyDB */ var $_dependencyDB; /** * @var PEAR_Config */ var $_config; /** * PEAR_Registry constructor. * * @param string (optional) PEAR install directory (for .php files) * @param PEAR_ChannelFile PEAR_ChannelFile object representing the PEAR channel, if * default values are not desired. Only used the very first time a PEAR * repository is initialized * @param PEAR_ChannelFile PEAR_ChannelFile object representing the PECL channel, if * default values are not desired. Only used the very first time a PEAR * repository is initialized * * @access public */ function __construct($pear_install_dir = PEAR_INSTALL_DIR, $pear_channel = false, $pecl_channel = false, $pear_metadata_dir = '') { parent::__construct(); $this->setInstallDir($pear_install_dir, $pear_metadata_dir); $this->_pearChannel = $pear_channel; $this->_peclChannel = $pecl_channel; $this->_config = false; } function setInstallDir($pear_install_dir = PEAR_INSTALL_DIR, $pear_metadata_dir = '') { $ds = DIRECTORY_SEPARATOR; $this->install_dir = $pear_install_dir; if (!$pear_metadata_dir) { $pear_metadata_dir = $pear_install_dir; } $this->channelsdir = $pear_metadata_dir.$ds.'.channels'; $this->statedir = $pear_metadata_dir.$ds.'.registry'; $this->filemap = $pear_metadata_dir.$ds.'.filemap'; $this->lockfile = $pear_metadata_dir.$ds.'.lock'; } function hasWriteAccess() { if (!file_exists($this->install_dir)) { $dir = $this->install_dir; while ($dir && $dir != '.') { $olddir = $dir; $dir = dirname($dir); if ($dir != '.' && file_exists($dir)) { if (is_writeable($dir)) { return true; } return false; } if ($dir == $olddir) { // this can happen in safe mode return @is_writable($dir); } } return false; } return is_writeable($this->install_dir); } function setConfig(&$config, $resetInstallDir = true) { $this->_config = &$config; if ($resetInstallDir) { $this->setInstallDir($config->get('php_dir'), $config->get('metadata_dir')); } } function _initializeChannelDirs() { static $running = false; if (!$running) { $running = true; $ds = DIRECTORY_SEPARATOR; if (!is_dir($this->channelsdir) || !file_exists($this->channelsdir . $ds . 'pear.php.net.reg') || !file_exists($this->channelsdir . $ds . 'pecl.php.net.reg') || !file_exists($this->channelsdir . $ds . 'doc.php.net.reg') || !file_exists($this->channelsdir . $ds . '__uri.reg')) { if (!file_exists($this->channelsdir . $ds . 'pear.php.net.reg')) { $pear_channel = $this->_pearChannel; if (!is_a($pear_channel, 'PEAR_ChannelFile') || !$pear_channel->validate()) { if (!class_exists('PEAR_ChannelFile')) { require_once 'PEAR/ChannelFile.php'; } $pear_channel = new PEAR_ChannelFile; $pear_channel->setAlias('pear'); $pear_channel->setServer('pear.php.net'); $pear_channel->setSummary('PHP Extension and Application Repository'); $pear_channel->setDefaultPEARProtocols(); $pear_channel->setBaseURL('REST1.0', 'http://pear.php.net/rest/'); $pear_channel->setBaseURL('REST1.1', 'http://pear.php.net/rest/'); $pear_channel->setBaseURL('REST1.3', 'http://pear.php.net/rest/'); //$pear_channel->setBaseURL('REST1.4', 'http://pear.php.net/rest/'); } else { $pear_channel->setServer('pear.php.net'); $pear_channel->setAlias('pear'); } $pear_channel->validate(); $this->_addChannel($pear_channel); } if (!file_exists($this->channelsdir . $ds . 'pecl.php.net.reg')) { $pecl_channel = $this->_peclChannel; if (!is_a($pecl_channel, 'PEAR_ChannelFile') || !$pecl_channel->validate()) { if (!class_exists('PEAR_ChannelFile')) { require_once 'PEAR/ChannelFile.php'; } $pecl_channel = new PEAR_ChannelFile; $pecl_channel->setAlias('pecl'); $pecl_channel->setServer('pecl.php.net'); $pecl_channel->setSummary('PHP Extension Community Library'); $pecl_channel->setDefaultPEARProtocols(); $pecl_channel->setBaseURL('REST1.0', 'http://pecl.php.net/rest/'); $pecl_channel->setBaseURL('REST1.1', 'http://pecl.php.net/rest/'); $pecl_channel->setValidationPackage('PEAR_Validator_PECL', '1.0'); } else { $pecl_channel->setServer('pecl.php.net'); $pecl_channel->setAlias('pecl'); } $pecl_channel->validate(); $this->_addChannel($pecl_channel); } if (!file_exists($this->channelsdir . $ds . 'doc.php.net.reg')) { $doc_channel = $this->_docChannel; if (!is_a($doc_channel, 'PEAR_ChannelFile') || !$doc_channel->validate()) { if (!class_exists('PEAR_ChannelFile')) { require_once 'PEAR/ChannelFile.php'; } $doc_channel = new PEAR_ChannelFile; $doc_channel->setAlias('phpdocs'); $doc_channel->setServer('doc.php.net'); $doc_channel->setSummary('PHP Documentation Team'); $doc_channel->setDefaultPEARProtocols(); $doc_channel->setBaseURL('REST1.0', 'http://doc.php.net/rest/'); $doc_channel->setBaseURL('REST1.1', 'http://doc.php.net/rest/'); $doc_channel->setBaseURL('REST1.3', 'http://doc.php.net/rest/'); } else { $doc_channel->setServer('doc.php.net'); $doc_channel->setAlias('doc'); } $doc_channel->validate(); $this->_addChannel($doc_channel); } if (!file_exists($this->channelsdir . $ds . '__uri.reg')) { if (!class_exists('PEAR_ChannelFile')) { require_once 'PEAR/ChannelFile.php'; } $private = new PEAR_ChannelFile; $private->setName('__uri'); $private->setDefaultPEARProtocols(); $private->setBaseURL('REST1.0', '****'); $private->setSummary('Pseudo-channel for static packages'); $this->_addChannel($private); } $this->_rebuildFileMap(); } $running = false; } } function _initializeDirs() { $ds = DIRECTORY_SEPARATOR; // XXX Compatibility code should be removed in the future // rename all registry files if any to lowercase if (!OS_WINDOWS && file_exists($this->statedir) && is_dir($this->statedir) && $handle = opendir($this->statedir)) { $dest = $this->statedir . $ds; while (false !== ($file = readdir($handle))) { if (preg_match('/^.*[A-Z].*\.reg\\z/', $file)) { rename($dest . $file, $dest . strtolower($file)); } } closedir($handle); } $this->_initializeChannelDirs(); if (!file_exists($this->filemap)) { $this->_rebuildFileMap(); } $this->_initializeDepDB(); } function _initializeDepDB() { if (!isset($this->_dependencyDB)) { static $initializing = false; if (!$initializing) { $initializing = true; if (!$this->_config) { // never used? $file = OS_WINDOWS ? 'pear.ini' : '.pearrc'; $this->_config = new PEAR_Config($this->statedir . DIRECTORY_SEPARATOR . $file); $this->_config->setRegistry($this); $this->_config->set('php_dir', $this->install_dir); } $this->_dependencyDB = &PEAR_DependencyDB::singleton($this->_config); if (PEAR::isError($this->_dependencyDB)) { // attempt to recover by removing the dep db if (file_exists($this->_config->get('metadata_dir', null, 'pear.php.net') . DIRECTORY_SEPARATOR . '.depdb')) { @unlink($this->_config->get('metadata_dir', null, 'pear.php.net') . DIRECTORY_SEPARATOR . '.depdb'); } $this->_dependencyDB = &PEAR_DependencyDB::singleton($this->_config); if (PEAR::isError($this->_dependencyDB)) { echo $this->_dependencyDB->getMessage(); echo 'Unrecoverable error'; exit(1); } } $initializing = false; } } } /** * PEAR_Registry destructor. Makes sure no locks are forgotten. * * @access private */ function _PEAR_Registry() { parent::_PEAR(); if (is_resource($this->lock_fp)) { $this->_unlock(); } } /** * Make sure the directory where we keep registry files exists. * * @return bool TRUE if directory exists, FALSE if it could not be * created * * @access private */ function _assertStateDir($channel = false) { if ($channel && $this->_getChannelFromAlias($channel) != 'pear.php.net') { return $this->_assertChannelStateDir($channel); } static $init = false; if (!file_exists($this->statedir)) { if (!$this->hasWriteAccess()) { return false; } require_once 'System.php'; if (!System::mkdir(array('-p', $this->statedir))) { return $this->raiseError("could not create directory '{$this->statedir}'"); } $init = true; } elseif (!is_dir($this->statedir)) { return $this->raiseError('Cannot create directory ' . $this->statedir . ', ' . 'it already exists and is not a directory'); } $ds = DIRECTORY_SEPARATOR; if (!file_exists($this->channelsdir)) { if (!file_exists($this->channelsdir . $ds . 'pear.php.net.reg') || !file_exists($this->channelsdir . $ds . 'pecl.php.net.reg') || !file_exists($this->channelsdir . $ds . 'doc.php.net.reg') || !file_exists($this->channelsdir . $ds . '__uri.reg')) { $init = true; } } elseif (!is_dir($this->channelsdir)) { return $this->raiseError('Cannot create directory ' . $this->channelsdir . ', ' . 'it already exists and is not a directory'); } if ($init) { static $running = false; if (!$running) { $running = true; $this->_initializeDirs(); $running = false; $init = false; } } else { $this->_initializeDepDB(); } return true; } /** * Make sure the directory where we keep registry files exists for a non-standard channel. * * @param string channel name * @return bool TRUE if directory exists, FALSE if it could not be * created * * @access private */ function _assertChannelStateDir($channel) { $ds = DIRECTORY_SEPARATOR; if (!$channel || $this->_getChannelFromAlias($channel) == 'pear.php.net') { if (!file_exists($this->channelsdir . $ds . 'pear.php.net.reg')) { $this->_initializeChannelDirs(); } return $this->_assertStateDir($channel); } $channelDir = $this->_channelDirectoryName($channel); if (!is_dir($this->channelsdir) || !file_exists($this->channelsdir . $ds . 'pear.php.net.reg')) { $this->_initializeChannelDirs(); } if (!file_exists($channelDir)) { if (!$this->hasWriteAccess()) { return false; } require_once 'System.php'; if (!System::mkdir(array('-p', $channelDir))) { return $this->raiseError("could not create directory '" . $channelDir . "'"); } } elseif (!is_dir($channelDir)) { return $this->raiseError("could not create directory '" . $channelDir . "', already exists and is not a directory"); } return true; } /** * Make sure the directory where we keep registry files for channels exists * * @return bool TRUE if directory exists, FALSE if it could not be * created * * @access private */ function _assertChannelDir() { if (!file_exists($this->channelsdir)) { if (!$this->hasWriteAccess()) { return false; } require_once 'System.php'; if (!System::mkdir(array('-p', $this->channelsdir))) { return $this->raiseError("could not create directory '{$this->channelsdir}'"); } } elseif (!is_dir($this->channelsdir)) { return $this->raiseError("could not create directory '{$this->channelsdir}" . "', it already exists and is not a directory"); } if (!file_exists($this->channelsdir . DIRECTORY_SEPARATOR . '.alias')) { if (!$this->hasWriteAccess()) { return false; } require_once 'System.php'; if (!System::mkdir(array('-p', $this->channelsdir . DIRECTORY_SEPARATOR . '.alias'))) { return $this->raiseError("could not create directory '{$this->channelsdir}/.alias'"); } } elseif (!is_dir($this->channelsdir . DIRECTORY_SEPARATOR . '.alias')) { return $this->raiseError("could not create directory '{$this->channelsdir}" . "/.alias', it already exists and is not a directory"); } return true; } /** * Get the name of the file where data for a given package is stored. * * @param string channel name, or false if this is a PEAR package * @param string package name * * @return string registry file name * * @access public */ function _packageFileName($package, $channel = false) { if ($channel && $this->_getChannelFromAlias($channel) != 'pear.php.net') { return $this->_channelDirectoryName($channel) . DIRECTORY_SEPARATOR . strtolower($package) . '.reg'; } return $this->statedir . DIRECTORY_SEPARATOR . strtolower($package) . '.reg'; } /** * Get the name of the file where data for a given channel is stored. * @param string channel name * @return string registry file name */ function _channelFileName($channel, $noaliases = false) { if (!$noaliases) { if (file_exists($this->_getChannelAliasFileName($channel))) { $channel = implode('', file($this->_getChannelAliasFileName($channel))); } } return $this->channelsdir . DIRECTORY_SEPARATOR . str_replace('/', '_', strtolower($channel)) . '.reg'; } /** * @param string * @return string */ function _getChannelAliasFileName($alias) { return $this->channelsdir . DIRECTORY_SEPARATOR . '.alias' . DIRECTORY_SEPARATOR . str_replace('/', '_', strtolower($alias)) . '.txt'; } /** * Get the name of a channel from its alias */ function _getChannelFromAlias($channel) { if (!$this->_channelExists($channel)) { if ($channel == 'pear.php.net') { return 'pear.php.net'; } if ($channel == 'pecl.php.net') { return 'pecl.php.net'; } if ($channel == 'doc.php.net') { return 'doc.php.net'; } if ($channel == '__uri') { return '__uri'; } return false; } $channel = strtolower($channel); if (file_exists($this->_getChannelAliasFileName($channel))) { // translate an alias to an actual channel return implode('', file($this->_getChannelAliasFileName($channel))); } return $channel; } /** * Get the alias of a channel from its alias or its name */ function _getAlias($channel) { if (!$this->_channelExists($channel)) { if ($channel == 'pear.php.net') { return 'pear'; } if ($channel == 'pecl.php.net') { return 'pecl'; } if ($channel == 'doc.php.net') { return 'phpdocs'; } return false; } $channel = $this->_getChannel($channel); if (PEAR::isError($channel)) { return $channel; } return $channel->getAlias(); } /** * Get the name of the file where data for a given package is stored. * * @param string channel name, or false if this is a PEAR package * @param string package name * * @return string registry file name * * @access public */ function _channelDirectoryName($channel) { if (!$channel || $this->_getChannelFromAlias($channel) == 'pear.php.net') { return $this->statedir; } $ch = $this->_getChannelFromAlias($channel); if (!$ch) { $ch = $channel; } return $this->statedir . DIRECTORY_SEPARATOR . strtolower('.channel.' . str_replace('/', '_', $ch)); } function _openPackageFile($package, $mode, $channel = false) { if (!$this->_assertStateDir($channel)) { return null; } if (!in_array($mode, array('r', 'rb')) && !$this->hasWriteAccess()) { return null; } $file = $this->_packageFileName($package, $channel); if (!file_exists($file) && $mode == 'r' || $mode == 'rb') { return null; } $fp = @fopen($file, $mode); if (!$fp) { return null; } return $fp; } function _closePackageFile($fp) { fclose($fp); } function _openChannelFile($channel, $mode) { if (!$this->_assertChannelDir()) { return null; } if (!in_array($mode, array('r', 'rb')) && !$this->hasWriteAccess()) { return null; } $file = $this->_channelFileName($channel); if (!file_exists($file) && $mode == 'r' || $mode == 'rb') { return null; } $fp = @fopen($file, $mode); if (!$fp) { return null; } return $fp; } function _closeChannelFile($fp) { fclose($fp); } function _rebuildFileMap() { if (!class_exists('PEAR_Installer_Role')) { require_once 'PEAR/Installer/Role.php'; } $channels = $this->_listAllPackages(); $files = array(); foreach ($channels as $channel => $packages) { foreach ($packages as $package) { $version = $this->_packageInfo($package, 'version', $channel); $filelist = $this->_packageInfo($package, 'filelist', $channel); if (!is_array($filelist)) { continue; } foreach ($filelist as $name => $attrs) { if (isset($attrs['attribs'])) { $attrs = $attrs['attribs']; } // it is possible for conflicting packages in different channels to // conflict with data files/doc files if ($name == 'dirtree') { continue; } if (isset($attrs['role']) && !in_array($attrs['role'], PEAR_Installer_Role::getInstallableRoles())) { // these are not installed continue; } if (isset($attrs['role']) && !in_array($attrs['role'], PEAR_Installer_Role::getBaseinstallRoles())) { $attrs['baseinstalldir'] = $package; } if (isset($attrs['baseinstalldir'])) { $file = $attrs['baseinstalldir'].DIRECTORY_SEPARATOR.$name; } else { $file = $name; } $file = preg_replace(',^/+,', '', $file); if ($channel != 'pear.php.net') { if (!isset($files[$attrs['role']])) { $files[$attrs['role']] = array(); } $files[$attrs['role']][$file] = array(strtolower($channel), strtolower($package)); } else { if (!isset($files[$attrs['role']])) { $files[$attrs['role']] = array(); } $files[$attrs['role']][$file] = strtolower($package); } } } } $this->_assertStateDir(); if (!$this->hasWriteAccess()) { return false; } $fp = @fopen($this->filemap, 'wb'); if (!$fp) { return false; } $this->filemap_cache = $files; fwrite($fp, serialize($files)); fclose($fp); return true; } function _readFileMap() { if (!file_exists($this->filemap)) { return array(); } $fp = @fopen($this->filemap, 'r'); if (!$fp) { $last_errormsg = ''; $last_error = error_get_last(); if (!empty($last_error['message'])) { $last_errormsg = $last_error['message']; } return $this->raiseError('PEAR_Registry: could not open filemap "' . $this->filemap . '"', PEAR_REGISTRY_ERROR_FILE, null, null, $last_errormsg); } clearstatcache(); $fsize = filesize($this->filemap); fclose($fp); $data = file_get_contents($this->filemap); $tmp = unserialize($data); if (!$tmp && $fsize > 7) { return $this->raiseError('PEAR_Registry: invalid filemap data', PEAR_REGISTRY_ERROR_FORMAT, null, null, $data); } $this->filemap_cache = $tmp; return true; } /** * Lock the registry. * * @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). * * @access private */ function _lock($mode = LOCK_EX) { if (stristr(php_uname(), 'Windows 9')) { return true; } if ($mode != LOCK_UN && is_resource($this->lock_fp)) { // XXX does not check type of lock (LOCK_SH/LOCK_EX) return true; } if (!$this->_assertStateDir()) { if ($mode == LOCK_EX) { return $this->raiseError('Registry directory is not writeable by the current user'); } return true; } $open_mode = 'w'; // XXX People reported problems with LOCK_SH and 'w' if ($mode === LOCK_SH || $mode === LOCK_UN) { if (!file_exists($this->lockfile)) { touch($this->lockfile); } $open_mode = 'r'; } if (!is_resource($this->lock_fp)) { $this->lock_fp = @fopen($this->lockfile, $open_mode); } if (!is_resource($this->lock_fp)) { $this->lock_fp = null; return $this->raiseError("could not create lock file" . (isset($php_errormsg) ? ": " . $php_errormsg : "")); } if (!(int)flock($this->lock_fp, $mode)) { switch ($mode) { case LOCK_SH: $str = 'shared'; break; case LOCK_EX: $str = 'exclusive'; break; case LOCK_UN: $str = 'unlock'; break; default: $str = 'unknown'; break; } //is resource at this point, close it on error. fclose($this->lock_fp); $this->lock_fp = null; return $this->raiseError("could not acquire $str lock ($this->lockfile)", PEAR_REGISTRY_ERROR_LOCK); } return true; } function _unlock() { $ret = $this->_lock(LOCK_UN); if (is_resource($this->lock_fp)) { fclose($this->lock_fp); } $this->lock_fp = null; return $ret; } function _packageExists($package, $channel = false) { return file_exists($this->_packageFileName($package, $channel)); } /** * Determine whether a channel exists in the registry * * @param string Channel name * @param bool if true, then aliases will be ignored * @return boolean */ function _channelExists($channel, $noaliases = false) { $a = file_exists($this->_channelFileName($channel, $noaliases)); if (!$a && $channel == 'pear.php.net') { return true; } if (!$a && $channel == 'pecl.php.net') { return true; } if (!$a && $channel == 'doc.php.net') { return true; } return $a; } /** * Determine whether a mirror exists within the default channel in the registry * * @param string Channel name * @param string Mirror name * * @return boolean */ function _mirrorExists($channel, $mirror) { $data = $this->_channelInfo($channel); if (!isset($data['servers']['mirror'])) { return false; } foreach ($data['servers']['mirror'] as $m) { if ($m['attribs']['host'] == $mirror) { return true; } } return false; } /** * @param PEAR_ChannelFile Channel object * @param donotuse * @param string Last-Modified HTTP tag from remote request * @return boolean|PEAR_Error True on creation, false if it already exists */ function _addChannel($channel, $update = false, $lastmodified = false) { if (!is_a($channel, 'PEAR_ChannelFile')) { return false; } if (!$channel->validate()) { return false; } if (file_exists($this->_channelFileName($channel->getName()))) { if (!$update) { return false; } $checker = $this->_getChannel($channel->getName()); if (PEAR::isError($checker)) { return $checker; } if ($channel->getAlias() != $checker->getAlias()) { if (file_exists($this->_getChannelAliasFileName($checker->getAlias()))) { @unlink($this->_getChannelAliasFileName($checker->getAlias())); } } } else { if ($update && !in_array($channel->getName(), array('pear.php.net', 'pecl.php.net', 'doc.php.net'))) { return false; } } $ret = $this->_assertChannelDir(); if (PEAR::isError($ret)) { return $ret; } $ret = $this->_assertChannelStateDir($channel->getName()); if (PEAR::isError($ret)) { return $ret; } if ($channel->getAlias() != $channel->getName()) { if (file_exists($this->_getChannelAliasFileName($channel->getAlias())) && $this->_getChannelFromAlias($channel->getAlias()) != $channel->getName()) { $channel->setAlias($channel->getName()); } if (!$this->hasWriteAccess()) { return false; } $fp = @fopen($this->_getChannelAliasFileName($channel->getAlias()), 'w'); if (!$fp) { return false; } fwrite($fp, $channel->getName()); fclose($fp); } if (!$this->hasWriteAccess()) { return false; } $fp = @fopen($this->_channelFileName($channel->getName()), 'wb'); if (!$fp) { return false; } $info = $channel->toArray(); if ($lastmodified) { $info['_lastmodified'] = $lastmodified; } else { $info['_lastmodified'] = self::getSourceDateEpoch(); } fwrite($fp, serialize($info)); fclose($fp); return true; } /** * Deletion fails if there are any packages installed from the channel * @param string|PEAR_ChannelFile channel name * @return boolean|PEAR_Error True on deletion, false if it doesn't exist */ function _deleteChannel($channel) { if (!is_string($channel)) { if (!is_a($channel, 'PEAR_ChannelFile')) { return false; } if (!$channel->validate()) { return false; } $channel = $channel->getName(); } if ($this->_getChannelFromAlias($channel) == '__uri') { return false; } if ($this->_getChannelFromAlias($channel) == 'pecl.php.net') { return false; } if ($this->_getChannelFromAlias($channel) == 'doc.php.net') { return false; } if (!$this->_channelExists($channel)) { return false; } if (!$channel || $this->_getChannelFromAlias($channel) == 'pear.php.net') { return false; } $channel = $this->_getChannelFromAlias($channel); if ($channel == 'pear.php.net') { return false; } $test = $this->_listChannelPackages($channel); if (count($test)) { return false; } $test = @rmdir($this->_channelDirectoryName($channel)); if (!$test) { return false; } $file = $this->_getChannelAliasFileName($this->_getAlias($channel)); if (file_exists($file)) { $test = @unlink($file); if (!$test) { return false; } } $file = $this->_channelFileName($channel); $ret = true; if (file_exists($file)) { $ret = @unlink($file); } return $ret; } /** * Determine whether a channel exists in the registry * @param string Channel Alias * @return boolean */ function _isChannelAlias($alias) { return file_exists($this->_getChannelAliasFileName($alias)); } /** * @param string|null * @param string|null * @param string|null * @return array|null * @access private */ function _packageInfo($package = null, $key = null, $channel = 'pear.php.net') { if ($package === null) { if ($channel === null) { $channels = $this->_listChannels(); $ret = array(); foreach ($channels as $channel) { $channel = strtolower($channel); $ret[$channel] = array(); $packages = $this->_listPackages($channel); foreach ($packages as $package) { $ret[$channel][] = $this->_packageInfo($package, null, $channel); } } return $ret; } $ps = $this->_listPackages($channel); if (!count($ps)) { return array(); } return array_map(array(&$this, '_packageInfo'), $ps, array_fill(0, count($ps), null), array_fill(0, count($ps), $channel)); } $fp = $this->_openPackageFile($package, 'r', $channel); if ($fp === null) { return null; } clearstatcache(); $this->_closePackageFile($fp); $data = file_get_contents($this->_packageFileName($package, $channel)); $data = @unserialize($data); if ($key === null) { return $data; } // compatibility for package.xml version 2.0 if (isset($data['old'][$key])) { return $data['old'][$key]; } if (isset($data[$key])) { return $data[$key]; } return null; } /** * @param string Channel name * @param bool whether to strictly retrieve info of channels, not just aliases * @return array|null */ function _channelInfo($channel, $noaliases = false) { if (!$this->_channelExists($channel, $noaliases)) { return null; } $fp = $this->_openChannelFile($channel, 'r'); if ($fp === null) { return null; } clearstatcache(); $this->_closeChannelFile($fp); $data = file_get_contents($this->_channelFileName($channel)); $data = unserialize($data); return $data; } function _listChannels() { $channellist = array(); if (!file_exists($this->channelsdir) || !is_dir($this->channelsdir)) { return array('pear.php.net', 'pecl.php.net', 'doc.php.net', '__uri'); } $dp = opendir($this->channelsdir); while ($ent = readdir($dp)) { if ($ent[0] == '.' || substr($ent, -4) != '.reg') { continue; } if ($ent == '__uri.reg') { $channellist[] = '__uri'; continue; } $channellist[] = str_replace('_', '/', substr($ent, 0, -4)); } closedir($dp); if (!in_array('pear.php.net', $channellist)) { $channellist[] = 'pear.php.net'; } if (!in_array('pecl.php.net', $channellist)) { $channellist[] = 'pecl.php.net'; } if (!in_array('doc.php.net', $channellist)) { $channellist[] = 'doc.php.net'; } if (!in_array('__uri', $channellist)) { $channellist[] = '__uri'; } natsort($channellist); return $channellist; } function _listPackages($channel = false) { if ($channel && $this->_getChannelFromAlias($channel) != 'pear.php.net') { return $this->_listChannelPackages($channel); } if (!file_exists($this->statedir) || !is_dir($this->statedir)) { return array(); } $pkglist = array(); $dp = opendir($this->statedir); if (!$dp) { return $pkglist; } while ($ent = readdir($dp)) { if ($ent[0] == '.' || substr($ent, -4) != '.reg') { continue; } $pkglist[] = substr($ent, 0, -4); } closedir($dp); sort($pkglist); return $pkglist; } function _listChannelPackages($channel) { $pkglist = array(); if (!file_exists($this->_channelDirectoryName($channel)) || !is_dir($this->_channelDirectoryName($channel))) { return array(); } $dp = opendir($this->_channelDirectoryName($channel)); if (!$dp) { return $pkglist; } while ($ent = readdir($dp)) { if ($ent[0] == '.' || substr($ent, -4) != '.reg') { continue; } $pkglist[] = substr($ent, 0, -4); } closedir($dp); return $pkglist; } function _listAllPackages() { $ret = array(); foreach ($this->_listChannels() as $channel) { $ret[$channel] = $this->_listPackages($channel); } return $ret; } /** * Add an installed package to the registry * @param string package name * @param array package info (parsed by PEAR_Common::infoFrom*() methods) * @return bool success of saving * @access private */ function _addPackage($package, $info) { if ($this->_packageExists($package)) { return false; } $fp = $this->_openPackageFile($package, 'wb'); if ($fp === null) { return false; } $info['_lastmodified'] = self::getSourceDateEpoch(); fwrite($fp, serialize($info)); $this->_closePackageFile($fp); if (isset($info['filelist'])) { $this->_rebuildFileMap(); } return true; } /** * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 * @return bool * @access private */ function _addPackage2($info) { if (!is_a($info, 'PEAR_PackageFile_v1') && !is_a($info, 'PEAR_PackageFile_v2')) { return false; } if (!$info->validate()) { if (class_exists('PEAR_Common')) { $ui = PEAR_Frontend::singleton(); if ($ui) { foreach ($info->getValidationWarnings() as $err) { $ui->log($err['message'], true); } } } return false; } $channel = $info->getChannel(); $package = $info->getPackage(); $save = $info; if ($this->_packageExists($package, $channel)) { return false; } if (!$this->_channelExists($channel, true)) { return false; } $info = $info->toArray(true); if (!$info) { return false; } $fp = $this->_openPackageFile($package, 'wb', $channel); if ($fp === null) { return false; } $info['_lastmodified'] = self::getSourceDateEpoch(); fwrite($fp, serialize($info)); $this->_closePackageFile($fp); $this->_rebuildFileMap(); return true; } /** * @param string Package name * @param array parsed package.xml 1.0 * @param bool this parameter is only here for BC. Don't use it. * @access private */ function _updatePackage($package, $info, $merge = true) { $oldinfo = $this->_packageInfo($package); if (empty($oldinfo)) { return false; } $fp = $this->_openPackageFile($package, 'w'); if ($fp === null) { return false; } if (is_object($info)) { $info = $info->toArray(); } $info['_lastmodified'] = self::getSourceDateEpoch(); $newinfo = $info; if ($merge) { $info = array_merge($oldinfo, $info); } else { $diff = $info; } fwrite($fp, serialize($info)); $this->_closePackageFile($fp); if (isset($newinfo['filelist'])) { $this->_rebuildFileMap(); } return true; } /** * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 * @return bool * @access private */ function _updatePackage2($info) { if (!$this->_packageExists($info->getPackage(), $info->getChannel())) { return false; } $fp = $this->_openPackageFile($info->getPackage(), 'w', $info->getChannel()); if ($fp === null) { return false; } $save = $info; $info = $save->getArray(true); $info['_lastmodified'] = self::getSourceDateEpoch(); fwrite($fp, serialize($info)); $this->_closePackageFile($fp); $this->_rebuildFileMap(); return true; } /** * @param string Package name * @param string Channel name * @return PEAR_PackageFile_v1|PEAR_PackageFile_v2|null * @access private */ function &_getPackage($package, $channel = 'pear.php.net') { $info = $this->_packageInfo($package, null, $channel); if ($info === null) { return $info; } $a = $this->_config; if (!$a) { $this->_config = new PEAR_Config; $this->_config->set('php_dir', $this->statedir); } if (!class_exists('PEAR_PackageFile')) { require_once 'PEAR/PackageFile.php'; } $pkg = new PEAR_PackageFile($this->_config); $pf = &$pkg->fromArray($info); return $pf; } /** * @param string channel name * @param bool whether to strictly retrieve channel names * @return PEAR_ChannelFile|PEAR_Error * @access private */ function &_getChannel($channel, $noaliases = false) { $ch = false; if ($this->_channelExists($channel, $noaliases)) { $chinfo = $this->_channelInfo($channel, $noaliases); if ($chinfo) { if (!class_exists('PEAR_ChannelFile')) { require_once 'PEAR/ChannelFile.php'; } $ch = &PEAR_ChannelFile::fromArrayWithErrors($chinfo); } } if ($ch) { if ($ch->validate()) { return $ch; } foreach ($ch->getErrors(true) as $err) { $message = $err['message'] . "\n"; } $ch = PEAR::raiseError($message); return $ch; } if ($this->_getChannelFromAlias($channel) == 'pear.php.net') { // the registry is not properly set up, so use defaults if (!class_exists('PEAR_ChannelFile')) { require_once 'PEAR/ChannelFile.php'; } $pear_channel = new PEAR_ChannelFile; $pear_channel->setServer('pear.php.net'); $pear_channel->setAlias('pear'); $pear_channel->setSummary('PHP Extension and Application Repository'); $pear_channel->setDefaultPEARProtocols(); $pear_channel->setBaseURL('REST1.0', 'http://pear.php.net/rest/'); $pear_channel->setBaseURL('REST1.1', 'http://pear.php.net/rest/'); $pear_channel->setBaseURL('REST1.3', 'http://pear.php.net/rest/'); return $pear_channel; } if ($this->_getChannelFromAlias($channel) == 'pecl.php.net') { // the registry is not properly set up, so use defaults if (!class_exists('PEAR_ChannelFile')) { require_once 'PEAR/ChannelFile.php'; } $pear_channel = new PEAR_ChannelFile; $pear_channel->setServer('pecl.php.net'); $pear_channel->setAlias('pecl'); $pear_channel->setSummary('PHP Extension Community Library'); $pear_channel->setDefaultPEARProtocols(); $pear_channel->setBaseURL('REST1.0', 'http://pecl.php.net/rest/'); $pear_channel->setBaseURL('REST1.1', 'http://pecl.php.net/rest/'); $pear_channel->setValidationPackage('PEAR_Validator_PECL', '1.0'); return $pear_channel; } if ($this->_getChannelFromAlias($channel) == 'doc.php.net') { // the registry is not properly set up, so use defaults if (!class_exists('PEAR_ChannelFile')) { require_once 'PEAR/ChannelFile.php'; } $doc_channel = new PEAR_ChannelFile; $doc_channel->setServer('doc.php.net'); $doc_channel->setAlias('phpdocs'); $doc_channel->setSummary('PHP Documentation Team'); $doc_channel->setDefaultPEARProtocols(); $doc_channel->setBaseURL('REST1.0', 'http://doc.php.net/rest/'); $doc_channel->setBaseURL('REST1.1', 'http://doc.php.net/rest/'); $doc_channel->setBaseURL('REST1.3', 'http://doc.php.net/rest/'); return $doc_channel; } if ($this->_getChannelFromAlias($channel) == '__uri') { // the registry is not properly set up, so use defaults if (!class_exists('PEAR_ChannelFile')) { require_once 'PEAR/ChannelFile.php'; } $private = new PEAR_ChannelFile; $private->setName('__uri'); $private->setDefaultPEARProtocols(); $private->setBaseURL('REST1.0', '****'); $private->setSummary('Pseudo-channel for static packages'); return $private; } return $ch; } /** * @param string Package name * @param string Channel name * @return bool */ function packageExists($package, $channel = 'pear.php.net') { if (PEAR::isError($e = $this->_lock(LOCK_SH))) { return $e; } $ret = $this->_packageExists($package, $channel); $this->_unlock(); return $ret; } // }}} // {{{ channelExists() /** * @param string channel name * @param bool if true, then aliases will be ignored * @return bool */ function channelExists($channel, $noaliases = false) { if (PEAR::isError($e = $this->_lock(LOCK_SH))) { return $e; } $ret = $this->_channelExists($channel, $noaliases); $this->_unlock(); return $ret; } // }}} /** * @param string channel name mirror is in * @param string mirror name * * @return bool */ function mirrorExists($channel, $mirror) { if (PEAR::isError($e = $this->_lock(LOCK_SH))) { return $e; } $ret = $this->_mirrorExists($channel, $mirror); $this->_unlock(); return $ret; } // {{{ isAlias() /** * Determines whether the parameter is an alias of a channel * @param string * @return bool */ function isAlias($alias) { if (PEAR::isError($e = $this->_lock(LOCK_SH))) { return $e; } $ret = $this->_isChannelAlias($alias); $this->_unlock(); return $ret; } // }}} // {{{ packageInfo() /** * @param string|null * @param string|null * @param string * @return array|null */ function packageInfo($package = null, $key = null, $channel = 'pear.php.net') { if (PEAR::isError($e = $this->_lock(LOCK_SH))) { return $e; } $ret = $this->_packageInfo($package, $key, $channel); $this->_unlock(); return $ret; } // }}} // {{{ channelInfo() /** * Retrieve a raw array of channel data. * * Do not use this, instead use {@link getChannel()} for normal * operations. Array structure is undefined in this method * @param string channel name * @param bool whether to strictly retrieve information only on non-aliases * @return array|null|PEAR_Error */ function channelInfo($channel = null, $noaliases = false) { if (PEAR::isError($e = $this->_lock(LOCK_SH))) { return $e; } $ret = $this->_channelInfo($channel, $noaliases); $this->_unlock(); return $ret; } // }}} /** * @param string */ function channelName($channel) { if (PEAR::isError($e = $this->_lock(LOCK_SH))) { return $e; } $ret = $this->_getChannelFromAlias($channel); $this->_unlock(); return $ret; } /** * @param string */ function channelAlias($channel) { if (PEAR::isError($e = $this->_lock(LOCK_SH))) { return $e; } $ret = $this->_getAlias($channel); $this->_unlock(); return $ret; } // {{{ listPackages() function listPackages($channel = false) { if (PEAR::isError($e = $this->_lock(LOCK_SH))) { return $e; } $ret = $this->_listPackages($channel); $this->_unlock(); return $ret; } // }}} // {{{ listAllPackages() function listAllPackages() { if (PEAR::isError($e = $this->_lock(LOCK_SH))) { return $e; } $ret = $this->_listAllPackages(); $this->_unlock(); return $ret; } // }}} // {{{ listChannel() function listChannels() { if (PEAR::isError($e = $this->_lock(LOCK_SH))) { return $e; } $ret = $this->_listChannels(); $this->_unlock(); return $ret; } // }}} // {{{ addPackage() /** * Add an installed package to the registry * @param string|PEAR_PackageFile_v1|PEAR_PackageFile_v2 package name or object * that will be passed to {@link addPackage2()} * @param array package info (parsed by PEAR_Common::infoFrom*() methods) * @return bool success of saving */ function addPackage($package, $info) { if (is_object($info)) { return $this->addPackage2($info); } if (PEAR::isError($e = $this->_lock(LOCK_EX))) { return $e; } $ret = $this->_addPackage($package, $info); $this->_unlock(); if ($ret) { if (!class_exists('PEAR_PackageFile_v1')) { require_once 'PEAR/PackageFile/v1.php'; } $pf = new PEAR_PackageFile_v1; $pf->setConfig($this->_config); $pf->fromArray($info); $this->_dependencyDB->uninstallPackage($pf); $this->_dependencyDB->installPackage($pf); } return $ret; } // }}} // {{{ addPackage2() function addPackage2($info) { if (!is_object($info)) { return $this->addPackage($info['package'], $info); } if (PEAR::isError($e = $this->_lock(LOCK_EX))) { return $e; } $ret = $this->_addPackage2($info); $this->_unlock(); if ($ret) { $this->_dependencyDB->uninstallPackage($info); $this->_dependencyDB->installPackage($info); } return $ret; } // }}} // {{{ updateChannel() /** * For future expandibility purposes, separate this * @param PEAR_ChannelFile */ function updateChannel($channel, $lastmodified = null) { if ($channel->getName() == '__uri') { return false; } return $this->addChannel($channel, $lastmodified, true); } // }}} // {{{ deleteChannel() /** * Deletion fails if there are any packages installed from the channel * @param string|PEAR_ChannelFile channel name * @return boolean|PEAR_Error True on deletion, false if it doesn't exist */ function deleteChannel($channel) { if (PEAR::isError($e = $this->_lock(LOCK_EX))) { return $e; } $ret = $this->_deleteChannel($channel); $this->_unlock(); if ($ret && is_a($this->_config, 'PEAR_Config')) { $this->_config->setChannels($this->listChannels()); } return $ret; } // }}} // {{{ addChannel() /** * @param PEAR_ChannelFile Channel object * @param string Last-Modified header from HTTP for caching * @return boolean|PEAR_Error True on creation, false if it already exists */ function addChannel($channel, $lastmodified = false, $update = false) { if (!is_a($channel, 'PEAR_ChannelFile') || !$channel->validate()) { return false; } if (PEAR::isError($e = $this->_lock(LOCK_EX))) { return $e; } $ret = $this->_addChannel($channel, $update, $lastmodified); $this->_unlock(); if (!$update && $ret && is_a($this->_config, 'PEAR_Config')) { $this->_config->setChannels($this->listChannels()); } return $ret; } // }}} // {{{ deletePackage() function deletePackage($package, $channel = 'pear.php.net') { if (PEAR::isError($e = $this->_lock(LOCK_EX))) { return $e; } $file = $this->_packageFileName($package, $channel); $ret = file_exists($file) ? @unlink($file) : false; $this->_rebuildFileMap(); $this->_unlock(); $p = array('channel' => $channel, 'package' => $package); $this->_dependencyDB->uninstallPackage($p); return $ret; } // }}} // {{{ updatePackage() function updatePackage($package, $info, $merge = true) { if (is_object($info)) { return $this->updatePackage2($info, $merge); } if (PEAR::isError($e = $this->_lock(LOCK_EX))) { return $e; } $ret = $this->_updatePackage($package, $info, $merge); $this->_unlock(); if ($ret) { if (!class_exists('PEAR_PackageFile_v1')) { require_once 'PEAR/PackageFile/v1.php'; } $pf = new PEAR_PackageFile_v1; $pf->setConfig($this->_config); $pf->fromArray($this->packageInfo($package)); $this->_dependencyDB->uninstallPackage($pf); $this->_dependencyDB->installPackage($pf); } return $ret; } // }}} // {{{ updatePackage2() function updatePackage2($info) { if (!is_object($info)) { return $this->updatePackage($info['package'], $info, $merge); } if (!$info->validate(PEAR_VALIDATE_DOWNLOADING)) { return false; } if (PEAR::isError($e = $this->_lock(LOCK_EX))) { return $e; } $ret = $this->_updatePackage2($info); $this->_unlock(); if ($ret) { $this->_dependencyDB->uninstallPackage($info); $this->_dependencyDB->installPackage($info); } return $ret; } // }}} // {{{ getChannel() /** * @param string channel name * @param bool whether to strictly return raw channels (no aliases) * @return PEAR_ChannelFile|PEAR_Error */ function getChannel($channel, $noaliases = false) { if (PEAR::isError($e = $this->_lock(LOCK_SH))) { return $e; } $ret = $this->_getChannel($channel, $noaliases); $this->_unlock(); if (!$ret) { return PEAR::raiseError('Unknown channel: ' . $channel); } return $ret; } // }}} // {{{ getPackage() /** * @param string package name * @param string channel name * @return PEAR_PackageFile_v1|PEAR_PackageFile_v2|null */ function &getPackage($package, $channel = 'pear.php.net') { if (PEAR::isError($e = $this->_lock(LOCK_SH))) { return $e; } $pf = &$this->_getPackage($package, $channel); $this->_unlock(); return $pf; } // }}} /** * Get PEAR_PackageFile_v[1/2] objects representing the contents of * a dependency group that are installed. * * This is used at uninstall-time * @param array * @return array|false */ function getInstalledGroup($group) { $ret = array(); if (isset($group['package'])) { if (!isset($group['package'][0])) { $group['package'] = array($group['package']); } foreach ($group['package'] as $package) { $depchannel = isset($package['channel']) ? $package['channel'] : '__uri'; $p = &$this->getPackage($package['name'], $depchannel); if ($p) { $save = &$p; $ret[] = &$save; } } } if (isset($group['subpackage'])) { if (!isset($group['subpackage'][0])) { $group['subpackage'] = array($group['subpackage']); } foreach ($group['subpackage'] as $package) { $depchannel = isset($package['channel']) ? $package['channel'] : '__uri'; $p = &$this->getPackage($package['name'], $depchannel); if ($p) { $save = &$p; $ret[] = &$save; } } } if (!count($ret)) { return false; } return $ret; } // {{{ getChannelValidator() /** * @param string channel name * @return PEAR_Validate|false */ function &getChannelValidator($channel) { $chan = $this->getChannel($channel); if (PEAR::isError($chan)) { return $chan; } $val = $chan->getValidationObject(); return $val; } // }}} // {{{ getChannels() /** * @param string channel name * @return array an array of PEAR_ChannelFile objects representing every installed channel */ function &getChannels() { $ret = array(); if (PEAR::isError($e = $this->_lock(LOCK_SH))) { return $e; } foreach ($this->_listChannels() as $channel) { $e = &$this->_getChannel($channel); if (!$e || PEAR::isError($e)) { continue; } $ret[] = $e; } $this->_unlock(); return $ret; } // }}} // {{{ checkFileMap() /** * Test whether a file or set of files belongs to a package. * * If an array is passed in * @param string|array file path, absolute or relative to the pear * install dir * @param string|array name of PEAR package or array('package' => name, 'channel' => * channel) of a package that will be ignored * @param string API version - 1.1 will exclude any files belonging to a package * @param array private recursion variable * @return array|false which package and channel the file belongs to, or an empty * string if the file does not belong to an installed package, * or belongs to the second parameter's package */ function checkFileMap($path, $package = false, $api = '1.0', $attrs = false) { if (is_array($path)) { static $notempty; if (empty($notempty)) { if (!class_exists('PEAR_Installer_Role')) { require_once 'PEAR/Installer/Role.php'; } $notempty = function($a) { return !empty($a); }; } $package = is_array($package) ? array(strtolower($package[0]), strtolower($package[1])) : strtolower($package); $pkgs = array(); foreach ($path as $name => $attrs) { if (is_array($attrs)) { if (isset($attrs['install-as'])) { $name = $attrs['install-as']; } if (!in_array($attrs['role'], PEAR_Installer_Role::getInstallableRoles())) { // these are not installed continue; } if (!in_array($attrs['role'], PEAR_Installer_Role::getBaseinstallRoles())) { $attrs['baseinstalldir'] = is_array($package) ? $package[1] : $package; } if (isset($attrs['baseinstalldir'])) { $name = $attrs['baseinstalldir'] . DIRECTORY_SEPARATOR . $name; } } $pkgs[$name] = $this->checkFileMap($name, $package, $api, $attrs); if (PEAR::isError($pkgs[$name])) { return $pkgs[$name]; } } return array_filter($pkgs, $notempty); } if (empty($this->filemap_cache)) { if (PEAR::isError($e = $this->_lock(LOCK_SH))) { return $e; } $err = $this->_readFileMap(); $this->_unlock(); if (PEAR::isError($err)) { return $err; } } if (!$attrs) { $attrs = array('role' => 'php'); // any old call would be for PHP role only } if (isset($this->filemap_cache[$attrs['role']][$path])) { if ($api >= '1.1' && $this->filemap_cache[$attrs['role']][$path] == $package) { return false; } return $this->filemap_cache[$attrs['role']][$path]; } $l = strlen($this->install_dir); if (substr($path, 0, $l) == $this->install_dir) { $path = preg_replace('!^'.DIRECTORY_SEPARATOR.'+!', '', substr($path, $l)); } if (isset($this->filemap_cache[$attrs['role']][$path])) { if ($api >= '1.1' && $this->filemap_cache[$attrs['role']][$path] == $package) { return false; } return $this->filemap_cache[$attrs['role']][$path]; } return false; } // }}} // {{{ flush() /** * Force a reload of the filemap * @since 1.5.0RC3 */ function flushFileMap() { $this->filemap_cache = null; clearstatcache(); // ensure that the next read gets the full, current filemap } // }}} // {{{ apiVersion() /** * Get the expected API version. Channels API is version 1.1, as it is backwards * compatible with 1.0 * @return string */ function apiVersion() { return '1.1'; } // }}} /** * Parse a package name, or validate a parsed package name array * @param string|array pass in an array of format * array( * 'package' => 'pname', * ['channel' => 'channame',] * ['version' => 'version',] * ['state' => 'state',] * ['group' => 'groupname']) * or a string of format * [channel://][channame/]pname[-version|-state][/group=groupname] * @return array|PEAR_Error */ function parsePackageName($param, $defaultchannel = 'pear.php.net') { $saveparam = $param; if (is_array($param)) { // convert to string for error messages $saveparam = $this->parsedPackageNameToString($param); // process the array if (!isset($param['package'])) { return PEAR::raiseError('parsePackageName(): array $param ' . 'must contain a valid package name in index "param"', 'package', null, null, $param); } if (!isset($param['uri'])) { if (!isset($param['channel'])) { $param['channel'] = $defaultchannel; } } else { $param['channel'] = '__uri'; } } else { $components = @parse_url((string) $param); if (isset($components['scheme'])) { if ($components['scheme'] == 'http') { // uri package $param = array('uri' => $param, 'channel' => '__uri'); } elseif($components['scheme'] != 'channel') { return PEAR::raiseError('parsePackageName(): only channel:// uris may ' . 'be downloaded, not "' . $param . '"', 'invalid', null, null, $param); } } if (!isset($components['path'])) { return PEAR::raiseError('parsePackageName(): array $param ' . 'must contain a valid package name in "' . $param . '"', 'package', null, null, $param); } if (isset($components['host'])) { // remove the leading "/" $components['path'] = substr($components['path'], 1); } if (!isset($components['scheme'])) { if (strpos($components['path'], '/') !== false) { if ($components['path'][0] == '/') { return PEAR::raiseError('parsePackageName(): this is not ' . 'a package name, it begins with "/" in "' . $param . '"', 'invalid', null, null, $param); } $parts = explode('/', $components['path']); $components['host'] = array_shift($parts); if (count($parts) > 1) { $components['path'] = array_pop($parts); $components['host'] .= '/' . implode('/', $parts); } else { $components['path'] = implode('/', $parts); } } else { $components['host'] = $defaultchannel; } } else { if (strpos($components['path'], '/')) { $parts = explode('/', $components['path']); $components['path'] = array_pop($parts); $components['host'] .= '/' . implode('/', $parts); } } if (is_array($param)) { $param['package'] = $components['path']; } else { $param = array( 'package' => $components['path'] ); if (isset($components['host'])) { $param['channel'] = $components['host']; } } if (isset($components['fragment'])) { $param['group'] = $components['fragment']; } if (isset($components['user'])) { $param['user'] = $components['user']; } if (isset($components['pass'])) { $param['pass'] = $components['pass']; } if (isset($components['query'])) { parse_str($components['query'], $param['opts']); } // check for extension $pathinfo = pathinfo($param['package']); if (isset($pathinfo['extension']) && in_array(strtolower($pathinfo['extension']), array('tgz', 'tar'))) { $param['extension'] = $pathinfo['extension']; $param['package'] = substr($pathinfo['basename'], 0, strlen($pathinfo['basename']) - 4); } // check for version if (strpos($param['package'], '-')) { $test = explode('-', $param['package']); if (count($test) != 2) { return PEAR::raiseError('parsePackageName(): only one version/state ' . 'delimiter "-" is allowed in "' . $saveparam . '"', 'version', null, null, $param); } list($param['package'], $param['version']) = $test; } } // validation $info = $this->channelExists($param['channel']); if (PEAR::isError($info)) { return $info; } if (!$info) { return PEAR::raiseError('unknown channel "' . $param['channel'] . '" in "' . $saveparam . '"', 'channel', null, null, $param); } $chan = $this->getChannel($param['channel']); if (PEAR::isError($chan)) { return $chan; } if (!$chan) { return PEAR::raiseError("Exception: corrupt registry, could not " . "retrieve channel " . $param['channel'] . " information", 'registry', null, null, $param); } $param['channel'] = $chan->getName(); $validate = $chan->getValidationObject(); $vpackage = $chan->getValidationPackage(); // validate package name if (!$validate->validPackageName($param['package'], $vpackage['_content'])) { return PEAR::raiseError('parsePackageName(): invalid package name "' . $param['package'] . '" in "' . $saveparam . '"', 'package', null, null, $param); } if (isset($param['group'])) { if (!PEAR_Validate::validGroupName($param['group'])) { return PEAR::raiseError('parsePackageName(): dependency group "' . $param['group'] . '" is not a valid group name in "' . $saveparam . '"', 'group', null, null, $param); } } if (isset($param['state'])) { if (!in_array(strtolower($param['state']), $validate->getValidStates())) { return PEAR::raiseError('parsePackageName(): state "' . $param['state'] . '" is not a valid state in "' . $saveparam . '"', 'state', null, null, $param); } } if (isset($param['version'])) { if (isset($param['state'])) { return PEAR::raiseError('parsePackageName(): cannot contain both ' . 'a version and a stability (state) in "' . $saveparam . '"', 'version/state', null, null, $param); } // check whether version is actually a state if (in_array(strtolower($param['version']), $validate->getValidStates())) { $param['state'] = strtolower($param['version']); unset($param['version']); } else { if (!$validate->validVersion($param['version'])) { return PEAR::raiseError('parsePackageName(): "' . $param['version'] . '" is neither a valid version nor a valid state in "' . $saveparam . '"', 'version/state', null, null, $param); } } } return $param; } /** * @param array * @return string */ function parsedPackageNameToString($parsed, $brief = false) { if (is_string($parsed)) { return $parsed; } if (is_object($parsed)) { $p = $parsed; $parsed = array( 'package' => $p->getPackage(), 'channel' => $p->getChannel(), 'version' => $p->getVersion(), ); } if (isset($parsed['uri'])) { return $parsed['uri']; } if ($brief) { if ($channel = $this->channelAlias($parsed['channel'])) { return $channel . '/' . $parsed['package']; } } $upass = ''; if (isset($parsed['user'])) { $upass = $parsed['user']; if (isset($parsed['pass'])) { $upass .= ':' . $parsed['pass']; } $upass = "$upass@"; } $ret = 'channel://' . $upass . $parsed['channel'] . '/' . $parsed['package']; if (isset($parsed['version']) || isset($parsed['state'])) { $ver = isset($parsed['version']) ? $parsed['version'] : ''; $ver .= isset($parsed['state']) ? $parsed['state'] : ''; $ret .= '-' . $ver; } if (isset($parsed['extension'])) { $ret .= '.' . $parsed['extension']; } if (isset($parsed['opts'])) { $ret .= '?'; foreach ($parsed['opts'] as $name => $value) { $parsed['opts'][$name] = "$name=$value"; } $ret .= implode('&', $parsed['opts']); } if (isset($parsed['group'])) { $ret .= '#' . $parsed['group']; } return $ret; } } PKu].4PEAR/Frontend.phpnu[ * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ /** * Include error handling */ //require_once 'PEAR.php'; /** * Which user interface class is being used. * @var string class name */ $GLOBALS['_PEAR_FRONTEND_CLASS'] = 'PEAR_Frontend_CLI'; /** * Instance of $_PEAR_Command_uiclass. * @var object */ $GLOBALS['_PEAR_FRONTEND_SINGLETON'] = null; /** * Singleton-based frontend for PEAR user input/output * * @category pear * @package PEAR * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ class PEAR_Frontend extends PEAR { /** * Retrieve the frontend object * @return PEAR_Frontend_CLI|PEAR_Frontend_Web|PEAR_Frontend_Gtk */ public static function &singleton($type = null) { if ($type === null) { if (!isset($GLOBALS['_PEAR_FRONTEND_SINGLETON'])) { $a = false; return $a; } return $GLOBALS['_PEAR_FRONTEND_SINGLETON']; } $a = PEAR_Frontend::setFrontendClass($type); return $a; } /** * Set the frontend class that will be used by calls to {@link singleton()} * * Frontends are expected to conform to the PEAR naming standard of * _ => DIRECTORY_SEPARATOR (PEAR_Frontend_CLI is in PEAR/Frontend/CLI.php) * @param string $uiclass full class name * @return PEAR_Frontend */ public static function &setFrontendClass($uiclass) { if (is_object($GLOBALS['_PEAR_FRONTEND_SINGLETON']) && is_a($GLOBALS['_PEAR_FRONTEND_SINGLETON'], $uiclass)) { return $GLOBALS['_PEAR_FRONTEND_SINGLETON']; } if (!class_exists($uiclass)) { $file = str_replace('_', '/', $uiclass) . '.php'; if (PEAR_Frontend::isIncludeable($file)) { include_once $file; } } if (class_exists($uiclass)) { $obj = new $uiclass; // quick test to see if this class implements a few of the most // important frontend methods if (is_a($obj, 'PEAR_Frontend')) { $GLOBALS['_PEAR_FRONTEND_SINGLETON'] = &$obj; $GLOBALS['_PEAR_FRONTEND_CLASS'] = $uiclass; return $obj; } $err = PEAR::raiseError("not a frontend class: $uiclass"); return $err; } $err = PEAR::raiseError("no such class: $uiclass"); return $err; } /** * Set the frontend class that will be used by calls to {@link singleton()} * * Frontends are expected to be a descendant of PEAR_Frontend * @param PEAR_Frontend * @return PEAR_Frontend */ public static function &setFrontendObject($uiobject) { if (is_object($GLOBALS['_PEAR_FRONTEND_SINGLETON']) && is_a($GLOBALS['_PEAR_FRONTEND_SINGLETON'], get_class($uiobject))) { return $GLOBALS['_PEAR_FRONTEND_SINGLETON']; } if (!is_a($uiobject, 'PEAR_Frontend')) { $err = PEAR::raiseError('not a valid frontend class: (' . get_class($uiobject) . ')'); return $err; } $GLOBALS['_PEAR_FRONTEND_SINGLETON'] = &$uiobject; $GLOBALS['_PEAR_FRONTEND_CLASS'] = get_class($uiobject); return $uiobject; } /** * @param string $path relative or absolute include path * @return boolean */ public static function isIncludeable($path) { if (file_exists($path) && is_readable($path)) { return true; } $fp = @fopen($path, 'r', true); if ($fp) { fclose($fp); return true; } return false; } /** * @param PEAR_Config */ function setConfig(&$config) { } /** * This can be overridden to allow session-based temporary file management * * By default, all files are deleted at the end of a session. The web installer * needs to be able to sustain a list over many sessions in order to support * user interaction with install scripts */ static function addTempFile($file) { $GLOBALS['_PEAR_Common_tempfiles'][] = $file; } /** * Log an action * * @param string $msg the message to log * @param boolean $append_crlf * @return boolean true * @abstract */ function log($msg, $append_crlf = true) { } /** * Run a post-installation script * * @param array $scripts array of post-install scripts * @abstract */ function runPostinstallScripts(&$scripts) { } /** * Display human-friendly output formatted depending on the * $command parameter. * * This should be able to handle basic output data with no command * @param mixed $data data structure containing the information to display * @param string $command command from which this method was called * @abstract */ function outputData($data, $command = '_default') { } /** * Display a modal form dialog and return the given input * * A frontend that requires multiple requests to retrieve and process * data must take these needs into account, and implement the request * handling code. * @param string $command command from which this method was called * @param array $prompts associative array. keys are the input field names * and values are the description * @param array $types array of input field types (text, password, * etc.) keys have to be the same like in $prompts * @param array $defaults array of default values. again keys have * to be the same like in $prompts. Do not depend * on a default value being set. * @return array input sent by the user * @abstract */ function userDialog($command, $prompts, $types = array(), $defaults = array()) { } } PKu]c__PEAR/DependencyDB.phpnu[ * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ /** * Needed for error handling */ require_once 'PEAR.php'; require_once 'PEAR/Config.php'; $GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE'] = array(); /** * Track dependency relationships between installed packages * @category pear * @package PEAR * @author Greg Beaver * @author Tomas V.V.Cox * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ class PEAR_DependencyDB { // {{{ properties /** * This is initialized by {@link setConfig()} * @var PEAR_Config * @access private */ var $_config; /** * This is initialized by {@link setConfig()} * @var PEAR_Registry * @access private */ var $_registry; /** * Filename of the dependency DB (usually .depdb) * @var string * @access private */ var $_depdb = false; /** * File name of the lockfile (usually .depdblock) * @var string * @access private */ var $_lockfile = false; /** * Open file resource for locking the lockfile * @var resource|false * @access private */ var $_lockFp = false; /** * API version of this class, used to validate a file on-disk * @var string * @access private */ var $_version = '1.0'; /** * Cached dependency database file * @var array|null * @access private */ var $_cache; // }}} // {{{ & singleton() /** * Get a raw dependency database. Calls setConfig() and assertDepsDB() * @param PEAR_Config * @param string|false full path to the dependency database, or false to use default * @return PEAR_DependencyDB|PEAR_Error */ public static function &singleton(&$config, $depdb = false) { $phpdir = $config->get('php_dir', null, 'pear.php.net'); if (!isset($GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE'][$phpdir])) { $a = new PEAR_DependencyDB; $GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE'][$phpdir] = &$a; $a->setConfig($config, $depdb); $e = $a->assertDepsDB(); if (PEAR::isError($e)) { return $e; } } return $GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE'][$phpdir]; } /** * Set up the registry/location of dependency DB * @param PEAR_Config|false * @param string|false full path to the dependency database, or false to use default */ function setConfig(&$config, $depdb = false) { if (!$config) { $this->_config = &PEAR_Config::singleton(); } else { $this->_config = &$config; } $this->_registry = &$this->_config->getRegistry(); if (!$depdb) { $dir = $this->_config->get('metadata_dir', null, 'pear.php.net'); if (!$dir) { $dir = $this->_config->get('php_dir', null, 'pear.php.net'); } $this->_depdb = $dir . DIRECTORY_SEPARATOR . '.depdb'; } else { $this->_depdb = $depdb; } $this->_lockfile = dirname($this->_depdb) . DIRECTORY_SEPARATOR . '.depdblock'; } // }}} function hasWriteAccess() { if (!file_exists($this->_depdb)) { $dir = $this->_depdb; while ($dir && $dir != '.') { $dir = dirname($dir); // cd .. if ($dir != '.' && file_exists($dir)) { if (is_writeable($dir)) { return true; } return false; } } return false; } return is_writeable($this->_depdb); } // {{{ assertDepsDB() /** * Create the dependency database, if it doesn't exist. Error if the database is * newer than the code reading it. * @return void|PEAR_Error */ function assertDepsDB() { if (!is_file($this->_depdb)) { $this->rebuildDB(); return; } $depdb = $this->_getDepDB(); // Datatype format has been changed, rebuild the Deps DB if ($depdb['_version'] < $this->_version) { $this->rebuildDB(); } if ($depdb['_version'][0] > $this->_version[0]) { return PEAR::raiseError('Dependency database is version ' . $depdb['_version'] . ', and we are version ' . $this->_version . ', cannot continue'); } } /** * Get a list of installed packages that depend on this package * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2|array * @return array|false */ function getDependentPackages(&$pkg) { $data = $this->_getDepDB(); if (is_object($pkg)) { $channel = strtolower($pkg->getChannel()); $package = strtolower($pkg->getPackage()); } else { $channel = strtolower($pkg['channel']); $package = strtolower($pkg['package']); } if (isset($data['packages'][$channel][$package])) { return $data['packages'][$channel][$package]; } return false; } /** * Get a list of the actual dependencies of installed packages that depend on * a package. * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2|array * @return array|false */ function getDependentPackageDependencies(&$pkg) { $data = $this->_getDepDB(); if (is_object($pkg)) { $channel = strtolower($pkg->getChannel()); $package = strtolower($pkg->getPackage()); } else if (is_array($pkg)) { $channel = strtolower($pkg['channel']); $package = strtolower($pkg['package']); } else { return false; } $depend = $this->getDependentPackages($pkg); if (!$depend) { return false; } $dependencies = array(); foreach ($depend as $info) { $temp = $this->getDependencies($info); foreach ($temp as $dep) { if ( isset($dep['dep'], $dep['dep']['channel'], $dep['dep']['name']) && strtolower($dep['dep']['channel']) == $channel && strtolower($dep['dep']['name']) == $package ) { if (!isset($dependencies[$info['channel']])) { $dependencies[$info['channel']] = array(); } if (!isset($dependencies[$info['channel']][$info['package']])) { $dependencies[$info['channel']][$info['package']] = array(); } $dependencies[$info['channel']][$info['package']][] = $dep; } } } return $dependencies; } /** * Get a list of dependencies of this installed package * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2|array * @return array|false */ function getDependencies(&$pkg) { if (is_object($pkg)) { $channel = strtolower($pkg->getChannel()); $package = strtolower($pkg->getPackage()); } else { $channel = strtolower($pkg['channel']); $package = strtolower($pkg['package']); } $data = $this->_getDepDB(); if (isset($data['dependencies'][$channel][$package])) { return $data['dependencies'][$channel][$package]; } return false; } /** * Determine whether $parent depends on $child, near or deep * @param array|PEAR_PackageFile_v2|PEAR_PackageFile_v2 * @param array|PEAR_PackageFile_v2|PEAR_PackageFile_v2 */ function dependsOn($parent, $child) { $c = array(); $this->_getDepDB(); return $this->_dependsOn($parent, $child, $c); } function _dependsOn($parent, $child, &$checked) { if (is_object($parent)) { $channel = strtolower($parent->getChannel()); $package = strtolower($parent->getPackage()); } else { $channel = strtolower($parent['channel']); $package = strtolower($parent['package']); } if (is_object($child)) { $depchannel = strtolower($child->getChannel()); $deppackage = strtolower($child->getPackage()); } else { $depchannel = strtolower($child['channel']); $deppackage = strtolower($child['package']); } if (isset($checked[$channel][$package][$depchannel][$deppackage])) { return false; // avoid endless recursion } $checked[$channel][$package][$depchannel][$deppackage] = true; if (!isset($this->_cache['dependencies'][$channel][$package])) { return false; } foreach ($this->_cache['dependencies'][$channel][$package] as $info) { if (isset($info['dep']['uri'])) { if (is_object($child)) { if ($info['dep']['uri'] == $child->getURI()) { return true; } } elseif (isset($child['uri'])) { if ($info['dep']['uri'] == $child['uri']) { return true; } } return false; } if (strtolower($info['dep']['channel']) == $depchannel && strtolower($info['dep']['name']) == $deppackage) { return true; } } foreach ($this->_cache['dependencies'][$channel][$package] as $info) { if (isset($info['dep']['uri'])) { if ($this->_dependsOn(array( 'uri' => $info['dep']['uri'], 'package' => $info['dep']['name']), $child, $checked)) { return true; } } else { if ($this->_dependsOn(array( 'channel' => $info['dep']['channel'], 'package' => $info['dep']['name']), $child, $checked)) { return true; } } } return false; } /** * Register dependencies of a package that is being installed or upgraded * @param PEAR_PackageFile_v2|PEAR_PackageFile_v2 */ function installPackage(&$package) { $data = $this->_getDepDB(); unset($this->_cache); $this->_setPackageDeps($data, $package); $this->_writeDepDB($data); } /** * Remove dependencies of a package that is being uninstalled, or upgraded. * * Upgraded packages first uninstall, then install * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2|array If an array, then it must have * indices 'channel' and 'package' */ function uninstallPackage(&$pkg) { $data = $this->_getDepDB(); unset($this->_cache); if (is_object($pkg)) { $channel = strtolower($pkg->getChannel()); $package = strtolower($pkg->getPackage()); } else { $channel = strtolower($pkg['channel']); $package = strtolower($pkg['package']); } if (!isset($data['dependencies'][$channel][$package])) { return true; } foreach ($data['dependencies'][$channel][$package] as $dep) { $found = false; $depchannel = isset($dep['dep']['uri']) ? '__uri' : strtolower($dep['dep']['channel']); $depname = strtolower($dep['dep']['name']); if (isset($data['packages'][$depchannel][$depname])) { foreach ($data['packages'][$depchannel][$depname] as $i => $info) { if ($info['channel'] == $channel && $info['package'] == $package) { $found = true; break; } } } if ($found) { unset($data['packages'][$depchannel][$depname][$i]); if (!count($data['packages'][$depchannel][$depname])) { unset($data['packages'][$depchannel][$depname]); if (!count($data['packages'][$depchannel])) { unset($data['packages'][$depchannel]); } } else { $data['packages'][$depchannel][$depname] = array_values($data['packages'][$depchannel][$depname]); } } } unset($data['dependencies'][$channel][$package]); if (!count($data['dependencies'][$channel])) { unset($data['dependencies'][$channel]); } if (!count($data['dependencies'])) { unset($data['dependencies']); } if (!count($data['packages'])) { unset($data['packages']); } $this->_writeDepDB($data); } /** * Rebuild the dependency DB by reading registry entries. * @return true|PEAR_Error */ function rebuildDB() { $depdb = array('_version' => $this->_version); if (!$this->hasWriteAccess()) { // allow startup for read-only with older Registry return $depdb; } $packages = $this->_registry->listAllPackages(); if (PEAR::isError($packages)) { return $packages; } foreach ($packages as $channel => $ps) { foreach ($ps as $package) { $package = $this->_registry->getPackage($package, $channel); if (PEAR::isError($package)) { return $package; } $this->_setPackageDeps($depdb, $package); } } $error = $this->_writeDepDB($depdb); if (PEAR::isError($error)) { return $error; } $this->_cache = $depdb; return true; } /** * Register usage of the dependency DB to prevent race conditions * @param int one of the LOCK_* constants * @return true|PEAR_Error * @access private */ function _lock($mode = LOCK_EX) { if (stristr(php_uname(), 'Windows 9')) { return true; } if ($mode != LOCK_UN && is_resource($this->_lockFp)) { // XXX does not check type of lock (LOCK_SH/LOCK_EX) return true; } $open_mode = 'w'; // XXX People reported problems with LOCK_SH and 'w' if ($mode === LOCK_SH) { if (!file_exists($this->_lockfile)) { touch($this->_lockfile); } elseif (!is_file($this->_lockfile)) { return PEAR::raiseError('could not create Dependency lock file, ' . 'it exists and is not a regular file'); } $open_mode = 'r'; } if (!is_resource($this->_lockFp)) { $this->_lockFp = @fopen($this->_lockfile, $open_mode); } if (!is_resource($this->_lockFp)) { $last_errormsg = ''; $last_error = error_get_last(); if (!empty($last_error['message'])) { $last_errormsg = $last_error['message']; } return PEAR::raiseError("could not create Dependency lock file" . (isset($last_errormsg) ? ": " . $last_errormsg : "")); } if (!(int)flock($this->_lockFp, $mode)) { switch ($mode) { case LOCK_SH: $str = 'shared'; break; case LOCK_EX: $str = 'exclusive'; break; case LOCK_UN: $str = 'unlock'; break; default: $str = 'unknown'; break; } return PEAR::raiseError("could not acquire $str lock ($this->_lockfile)"); } return true; } /** * Release usage of dependency DB * @return true|PEAR_Error * @access private */ function _unlock() { $ret = $this->_lock(LOCK_UN); if (is_resource($this->_lockFp)) { fclose($this->_lockFp); } $this->_lockFp = null; return $ret; } /** * Load the dependency database from disk, or return the cache * @return array|PEAR_Error */ function _getDepDB() { if (!$this->hasWriteAccess()) { return array('_version' => $this->_version); } if (isset($this->_cache)) { return $this->_cache; } if (!$fp = fopen($this->_depdb, 'r')) { $err = PEAR::raiseError("Could not open dependencies file `".$this->_depdb."'"); return $err; } clearstatcache(); fclose($fp); $data = @unserialize(file_get_contents($this->_depdb)); $this->_cache = $data; return $data; } /** * Write out the dependency database to disk * @param array the database * @return true|PEAR_Error * @access private */ function _writeDepDB(&$deps) { if (PEAR::isError($e = $this->_lock(LOCK_EX))) { return $e; } if (!$fp = fopen($this->_depdb, 'wb')) { $this->_unlock(); return PEAR::raiseError("Could not open dependencies file `".$this->_depdb."' for writing"); } fwrite($fp, serialize($deps)); fclose($fp); $this->_unlock(); $this->_cache = $deps; return true; } /** * Register all dependencies from a package in the dependencies database, in essence * "installing" the package's dependency information * @param array the database * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 * @access private */ function _setPackageDeps(&$data, &$pkg) { $pkg->setConfig($this->_config); if ($pkg->getPackagexmlVersion() == '1.0') { $gen = &$pkg->getDefaultGenerator(); $deps = $gen->dependenciesToV2(); } else { $deps = $pkg->getDeps(true); } if (!$deps) { return; } if (!is_array($data)) { $data = array(); } if (!isset($data['dependencies'])) { $data['dependencies'] = array(); } $channel = strtolower($pkg->getChannel()); $package = strtolower($pkg->getPackage()); if (!isset($data['dependencies'][$channel])) { $data['dependencies'][$channel] = array(); } $data['dependencies'][$channel][$package] = array(); if (isset($deps['required']['package'])) { if (!isset($deps['required']['package'][0])) { $deps['required']['package'] = array($deps['required']['package']); } foreach ($deps['required']['package'] as $dep) { $this->_registerDep($data, $pkg, $dep, 'required'); } } if (isset($deps['optional']['package'])) { if (!isset($deps['optional']['package'][0])) { $deps['optional']['package'] = array($deps['optional']['package']); } foreach ($deps['optional']['package'] as $dep) { $this->_registerDep($data, $pkg, $dep, 'optional'); } } if (isset($deps['required']['subpackage'])) { if (!isset($deps['required']['subpackage'][0])) { $deps['required']['subpackage'] = array($deps['required']['subpackage']); } foreach ($deps['required']['subpackage'] as $dep) { $this->_registerDep($data, $pkg, $dep, 'required'); } } if (isset($deps['optional']['subpackage'])) { if (!isset($deps['optional']['subpackage'][0])) { $deps['optional']['subpackage'] = array($deps['optional']['subpackage']); } foreach ($deps['optional']['subpackage'] as $dep) { $this->_registerDep($data, $pkg, $dep, 'optional'); } } if (isset($deps['group'])) { if (!isset($deps['group'][0])) { $deps['group'] = array($deps['group']); } foreach ($deps['group'] as $group) { if (isset($group['package'])) { if (!isset($group['package'][0])) { $group['package'] = array($group['package']); } foreach ($group['package'] as $dep) { $this->_registerDep($data, $pkg, $dep, 'optional', $group['attribs']['name']); } } if (isset($group['subpackage'])) { if (!isset($group['subpackage'][0])) { $group['subpackage'] = array($group['subpackage']); } foreach ($group['subpackage'] as $dep) { $this->_registerDep($data, $pkg, $dep, 'optional', $group['attribs']['name']); } } } } if ($data['dependencies'][$channel][$package] == array()) { unset($data['dependencies'][$channel][$package]); if (!count($data['dependencies'][$channel])) { unset($data['dependencies'][$channel]); } } } /** * @param array the database * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 * @param array the specific dependency * @param required|optional whether this is a required or an optional dep * @param string|false dependency group this dependency is from, or false for ordinary dep */ function _registerDep(&$data, &$pkg, $dep, $type, $group = false) { $info = array( 'dep' => $dep, 'type' => $type, 'group' => $group ); $dep = array_map('strtolower', $dep); $depchannel = isset($dep['channel']) ? $dep['channel'] : '__uri'; if (!isset($data['dependencies'])) { $data['dependencies'] = array(); } $channel = strtolower($pkg->getChannel()); $package = strtolower($pkg->getPackage()); if (!isset($data['dependencies'][$channel])) { $data['dependencies'][$channel] = array(); } if (!isset($data['dependencies'][$channel][$package])) { $data['dependencies'][$channel][$package] = array(); } $data['dependencies'][$channel][$package][] = $info; if (isset($data['packages'][$depchannel][$dep['name']])) { $found = false; foreach ($data['packages'][$depchannel][$dep['name']] as $i => $p) { if ($p['channel'] == $channel && $p['package'] == $package) { $found = true; break; } } } else { if (!isset($data['packages'])) { $data['packages'] = array(); } if (!isset($data['packages'][$depchannel])) { $data['packages'][$depchannel] = array(); } if (!isset($data['packages'][$depchannel][$dep['name']])) { $data['packages'][$depchannel][$dep['name']] = array(); } $found = false; } if (!$found) { $data['packages'][$depchannel][$dep['name']][] = array( 'channel' => $channel, 'package' => $package ); } } } PKu]TIIPEAR/Builder.phpnu[ * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 0.1 * * TODO: log output parameters in PECL command line * TODO: msdev path in configuration */ /** * Needed for extending PEAR_Builder */ require_once 'PEAR/Common.php'; require_once 'PEAR/PackageFile.php'; require_once 'System.php'; /** * Class to handle building (compiling) extensions. * * @category pear * @package PEAR * @author Stig Bakken * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since PHP 4.0.2 * @see http://pear.php.net/manual/en/core.ppm.pear-builder.php */ class PEAR_Builder extends PEAR_Common { var $php_api_version = 0; var $zend_module_api_no = 0; var $zend_extension_api_no = 0; var $extensions_built = array(); /** * @var string Used for reporting when it is not possible to pass function * via extra parameter, e.g. log, msdevCallback */ var $current_callback = null; // used for msdev builds var $_lastline = null; var $_firstline = null; /** * Parsed --configureoptions. * * @var mixed[] */ var $_parsed_configure_options; /** * PEAR_Builder constructor. * * @param mixed[] $configureoptions * @param object $ui user interface object (instance of PEAR_Frontend_*) * * @access public */ function __construct($configureoptions, &$ui) { parent::__construct(); $this->setFrontendObject($ui); $this->_parseConfigureOptions($configureoptions); } /** * Parse --configureoptions string. * * @param string Options, in the form "X=1 Y=2 Z='there\'s always one'" */ function _parseConfigureOptions($options) { $data = ''; $parser = xml_parser_create('ISO-8859-1'); xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0); xml_set_element_handler( $parser, array($this, '_parseConfigureOptionsStartElement'), array($this, '_parseConfigureOptionsEndElement')); xml_parse($parser, $data, true); xml_parser_free($parser); } /** * Handle element start. * * @see PEAR_Builder::_parseConfigureOptions() * * @param resource $parser * @param string $tagName * @param mixed[] $attribs */ function _parseConfigureOptionsStartElement($parser, $tagName, $attribs) { if ($tagName !== 'PROPERTIES') { return; } $this->_parsed_configure_options = $attribs; } /** * Handle element end. * * @see PEAR_Builder::_parseConfigureOptions() * * @param resource * @param string $element */ function _parseConfigureOptionsEndElement($parser, $element) { } /** * Build an extension from source on windows. * requires msdev */ function _build_win32($descfile, $callback = null) { if (is_object($descfile)) { $pkg = $descfile; $descfile = $pkg->getPackageFile(); } else { $pf = new PEAR_PackageFile($this->config, $this->debug); $pkg = &$pf->fromPackageFile($descfile, PEAR_VALIDATE_NORMAL); if (PEAR::isError($pkg)) { return $pkg; } } $dir = dirname($descfile); $old_cwd = getcwd(); if (!file_exists($dir) || !is_dir($dir) || !chdir($dir)) { return $this->raiseError("could not chdir to $dir"); } // packages that were in a .tar have the packagefile in this directory $vdir = $pkg->getPackage() . '-' . $pkg->getVersion(); if (file_exists($dir) && is_dir($vdir)) { if (!chdir($vdir)) { return $this->raiseError("could not chdir to " . realpath($vdir)); } $dir = getcwd(); } $this->log(2, "building in $dir"); $dsp = $pkg->getPackage().'.dsp'; if (!file_exists("$dir/$dsp")) { return $this->raiseError("The DSP $dsp does not exist."); } // XXX TODO: make release build type configurable $command = 'msdev '.$dsp.' /MAKE "'.$pkg->getPackage(). ' - Release"'; $err = $this->_runCommand($command, array(&$this, 'msdevCallback')); if (PEAR::isError($err)) { return $err; } // figure out the build platform and type $platform = 'Win32'; $buildtype = 'Release'; if (preg_match('/.*?'.$pkg->getPackage().'\s-\s(\w+)\s(.*?)-+/i',$this->_firstline,$matches)) { $platform = $matches[1]; $buildtype = $matches[2]; } if (preg_match('/(.*)?\s-\s(\d+).*?(\d+)/', $this->_lastline, $matches)) { if ($matches[2]) { // there were errors in the build return $this->raiseError("There were errors during compilation."); } $out = $matches[1]; } else { return $this->raiseError("Did not understand the completion status returned from msdev.exe."); } // msdev doesn't tell us the output directory :/ // open the dsp, find /out and use that directory $dsptext = join('', file($dsp)); // this regex depends on the build platform and type having been // correctly identified above. $regex ='/.*?!IF\s+"\$\(CFG\)"\s+==\s+("'. $pkg->getPackage().'\s-\s'. $platform.'\s'. $buildtype.'").*?'. '\/out:"(.*?)"/is'; if ($dsptext && preg_match($regex, $dsptext, $matches)) { // what we get back is a relative path to the output file itself. $outfile = realpath($matches[2]); } else { return $this->raiseError("Could not retrieve output information from $dsp."); } // realpath returns false if the file doesn't exist if ($outfile && copy($outfile, "$dir/$out")) { $outfile = "$dir/$out"; } $built_files[] = array( 'file' => "$outfile", 'php_api' => $this->php_api_version, 'zend_mod_api' => $this->zend_module_api_no, 'zend_ext_api' => $this->zend_extension_api_no, ); return $built_files; } // }}} // {{{ msdevCallback() function msdevCallback($what, $data) { if (!$this->_firstline) $this->_firstline = $data; $this->_lastline = $data; call_user_func($this->current_callback, $what, $data); } /** * @param string * @param string * @param array * @access private */ function _harvestInstDir($dest_prefix, $dirname, &$built_files) { $d = opendir($dirname); if (!$d) return false; $ret = true; while (($ent = readdir($d)) !== false) { if ($ent[0] == '.') continue; $full = $dirname . DIRECTORY_SEPARATOR . $ent; if (is_dir($full)) { if (!$this->_harvestInstDir( $dest_prefix . DIRECTORY_SEPARATOR . $ent, $full, $built_files)) { $ret = false; break; } } else { $dest = $dest_prefix . DIRECTORY_SEPARATOR . $ent; $built_files[] = array( 'file' => $full, 'dest' => $dest, 'php_api' => $this->php_api_version, 'zend_mod_api' => $this->zend_module_api_no, 'zend_ext_api' => $this->zend_extension_api_no, ); } } closedir($d); return $ret; } /** * Build an extension from source. Runs "phpize" in the source * directory, but compiles in a temporary directory * (TMPDIR/pear-build-USER/PACKAGE-VERSION). * * @param string|PEAR_PackageFile_v* $descfile path to XML package description file, or * a PEAR_PackageFile object * * @param mixed $callback callback function used to report output, * see PEAR_Builder::_runCommand for details * * @return array an array of associative arrays with built files, * format: * array( array( 'file' => '/path/to/ext.so', * 'php_api' => YYYYMMDD, * 'zend_mod_api' => YYYYMMDD, * 'zend_ext_api' => YYYYMMDD ), * ... ) * * @access public * * @see PEAR_Builder::_runCommand */ function build($descfile, $callback = null) { if (preg_match('/(\\/|\\\\|^)([^\\/\\\\]+)?php([^\\/\\\\]+)?$/', $this->config->get('php_bin'), $matches)) { if (isset($matches[2]) && strlen($matches[2]) && trim($matches[2]) != trim($this->config->get('php_prefix'))) { $this->log(0, 'WARNING: php_bin ' . $this->config->get('php_bin') . ' appears to have a prefix ' . $matches[2] . ', but' . ' config variable php_prefix does not match'); } if (isset($matches[3]) && strlen($matches[3]) && trim($matches[3]) != trim($this->config->get('php_suffix'))) { $this->log(0, 'WARNING: php_bin ' . $this->config->get('php_bin') . ' appears to have a suffix ' . $matches[3] . ', but' . ' config variable php_suffix does not match'); } } $this->current_callback = $callback; if (PEAR_OS == "Windows") { return $this->_build_win32($descfile, $callback); } if (PEAR_OS != 'Unix') { return $this->raiseError("building extensions not supported on this platform"); } if (is_object($descfile)) { $pkg = $descfile; $descfile = $pkg->getPackageFile(); if (is_a($pkg, 'PEAR_PackageFile_v1')) { $dir = dirname($descfile); } else { $dir = $pkg->_config->get('temp_dir') . '/' . $pkg->getName(); // automatically delete at session end self::addTempFile($dir); } } else { $pf = new PEAR_PackageFile($this->config); $pkg = &$pf->fromPackageFile($descfile, PEAR_VALIDATE_NORMAL); if (PEAR::isError($pkg)) { return $pkg; } $dir = dirname($descfile); } // Find config. outside of normal path - e.g. config.m4 foreach (array_keys($pkg->getInstallationFileList()) as $item) { if (stristr(basename($item), 'config.m4') && dirname($item) != '.') { $dir .= DIRECTORY_SEPARATOR . dirname($item); break; } } $old_cwd = getcwd(); if (!file_exists($dir) || !is_dir($dir) || !chdir($dir)) { return $this->raiseError("could not chdir to $dir"); } $vdir = $pkg->getPackage() . '-' . $pkg->getVersion(); if (is_dir($vdir)) { chdir($vdir); } $dir = getcwd(); $this->log(2, "building in $dir"); $binDir = $this->config->get('bin_dir'); if (!preg_match('@(^|:)' . preg_quote($binDir, '@') . '(:|$)@', getenv('PATH'))) { putenv('PATH=' . $binDir . ':' . getenv('PATH')); } $err = $this->_runCommand($this->config->get('php_prefix') . "phpize" . $this->config->get('php_suffix'), array(&$this, 'phpizeCallback')); if (PEAR::isError($err)) { return $err; } if (!$err) { return $this->raiseError("`phpize' failed"); } // {{{ start of interactive part $configure_command = "$dir/configure"; $phpConfigName = $this->config->get('php_prefix') . 'php-config' . $this->config->get('php_suffix'); $phpConfigPath = System::which($phpConfigName); if ($phpConfigPath !== false) { $configure_command .= ' --with-php-config=' . $phpConfigPath; } $configure_options = $pkg->getConfigureOptions(); if ($configure_options) { foreach ($configure_options as $option) { $default = array_key_exists('default', $option) ? $option['default'] : null; if (array_key_exists($option['name'], $this->_parsed_configure_options)) { $response = $this->_parsed_configure_options[$option['name']]; } else { list($response) = $this->ui->userDialog( 'build', [$option['prompt']], ['text'], [$default]); } if (substr($option['name'], 0, 5) === 'with-' && ($response === 'yes' || $response === 'autodetect')) { $configure_command .= " --{$option['name']}"; } else { $configure_command .= " --{$option['name']}=".trim($response); } } } // }}} end of interactive part // FIXME make configurable if (!$user=getenv('USER')) { $user='defaultuser'; } $tmpdir = $this->config->get('temp_dir'); $build_basedir = System::mktemp(' -t "' . $tmpdir . '" -d "pear-build-' . $user . '"'); $build_dir = "$build_basedir/$vdir"; $inst_dir = "$build_basedir/install-$vdir"; $this->log(1, "building in $build_dir"); if (is_dir($build_dir)) { System::rm(array('-rf', $build_dir)); } if (!System::mkDir(array('-p', $build_dir))) { return $this->raiseError("could not create build dir: $build_dir"); } self::addTempFile($build_dir); if (!System::mkDir(array('-p', $inst_dir))) { return $this->raiseError("could not create temporary install dir: $inst_dir"); } self::addTempFile($inst_dir); $make_command = getenv('MAKE') ? getenv('MAKE') : 'make'; $to_run = array( $configure_command, $make_command, "$make_command INSTALL_ROOT=\"$inst_dir\" install", "find \"$inst_dir\" | xargs ls -dils" ); if (!file_exists($build_dir) || !is_dir($build_dir) || !chdir($build_dir)) { return $this->raiseError("could not chdir to $build_dir"); } putenv('PHP_PEAR_VERSION=1.10.16'); foreach ($to_run as $cmd) { $err = $this->_runCommand($cmd, $callback); if (PEAR::isError($err)) { chdir($old_cwd); return $err; } if (!$err) { chdir($old_cwd); return $this->raiseError("`$cmd' failed"); } } if (!($dp = opendir("modules"))) { chdir($old_cwd); return $this->raiseError("no `modules' directory found"); } $built_files = array(); $prefix = exec($this->config->get('php_prefix') . "php-config" . $this->config->get('php_suffix') . " --prefix"); $this->_harvestInstDir($prefix, $inst_dir . DIRECTORY_SEPARATOR . $prefix, $built_files); chdir($old_cwd); return $built_files; } /** * Message callback function used when running the "phpize" * program. Extracts the API numbers used. Ignores other message * types than "cmdoutput". * * @param string $what the type of message * @param mixed $data the message * * @return void * * @access public */ function phpizeCallback($what, $data) { if ($what != 'cmdoutput') { return; } $this->log(1, rtrim($data)); if (preg_match('/You should update your .aclocal.m4/', $data)) { return; } $matches = array(); if (preg_match('/^\s+(\S[^:]+):\s+(\d{8})/', $data, $matches)) { $member = preg_replace('/[^a-z]/', '_', strtolower($matches[1])); $apino = (int)$matches[2]; if (isset($this->$member)) { $this->$member = $apino; //$msg = sprintf("%-22s : %d", $matches[1], $apino); //$this->log(1, $msg); } } } /** * Run an external command, using a message callback to report * output. The command will be run through popen and output is * reported for every line with a "cmdoutput" message with the * line string, including newlines, as payload. * * @param string $command the command to run * * @param mixed $callback (optional) function to use as message * callback * * @return bool whether the command was successful (exit code 0 * means success, any other means failure) * * @access private */ function _runCommand($command, $callback = null) { $this->log(1, "running: $command"); $pp = popen("$command 2>&1", "r"); if (!$pp) { return $this->raiseError("failed to run `$command'"); } if ($callback && $callback[0]->debug == 1) { $olddbg = $callback[0]->debug; $callback[0]->debug = 2; } while ($line = fgets($pp, 1024)) { if ($callback) { call_user_func($callback, 'cmdoutput', $line); } else { $this->log(2, rtrim($line)); } } if ($callback && isset($olddbg)) { $callback[0]->debug = $olddbg; } $exitcode = is_resource($pp) ? pclose($pp) : -1; return ($exitcode == 0); } function log($level, $msg, $append_crlf = true) { if ($this->current_callback) { if ($this->debug >= $level) { call_user_func($this->current_callback, 'output', $msg); } return; } return parent::log($level, $msg, $append_crlf); } } PKu](PzPEAR/Proxy.phpnu[config = $config; $this->_parseProxyInfo(); } /** * @access private */ function _parseProxyInfo() { $this->proxy_host = $this->proxy_port = $this->proxy_user = $this->proxy_pass = ''; if ($this->config->get('http_proxy')&& $proxy = parse_url($this->config->get('http_proxy')) ) { $this->proxy_host = isset($proxy['host']) ? $proxy['host'] : null; $this->proxy_port = isset($proxy['port']) ? $proxy['port'] : 8080; $this->proxy_user = isset($proxy['user']) ? urldecode($proxy['user']) : null; $this->proxy_pass = isset($proxy['pass']) ? urldecode($proxy['pass']) : null; $this->proxy_schema = (isset($proxy['scheme']) && $proxy['scheme'] == 'https') ? 'https' : 'http'; } } /** * @access private */ function _httpConnect($fp, $host, $port) { fwrite($fp, "CONNECT $host:$port HTTP/1.1\r\n"); fwrite($fp, "Host: $host:$port\r\n"); if ($this->getProxyAuth()) { fwrite($fp, 'Proxy-Authorization: Basic ' . $this->getProxyAuth() . "\r\n"); } fwrite($fp, "\r\n"); while ($line = trim(fgets($fp, 1024))) { if (preg_match('|^HTTP/1.[01] ([0-9]{3}) |', $line, $matches)) { $code = (int)$matches[1]; /* as per RFC 2817 */ if ($code < 200 || $code >= 300) { return PEAR::raiseError("Establishing a CONNECT tunnel through proxy failed with response code $code"); } } } // connection was successful -- establish SSL through // the tunnel $crypto_method = STREAM_CRYPTO_METHOD_TLS_CLIENT; if (defined('STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT')) { $crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT; $crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT; } // set the correct hostname for working hostname // verification stream_context_set_option($fp, 'ssl', 'peer_name', $host); // blocking socket needed for // stream_socket_enable_crypto() // see // stream_set_blocking ($fp, true); $crypto_res = stream_socket_enable_crypto($fp, true, $crypto_method); if (!$crypto_res) { return PEAR::raiseError("Could not establish SSL connection through proxy: $crypto_res"); } return true; } /** * get the authorization information for the proxy, encoded to be * passed in the Proxy-Authentication HTTP header. * @return null|string the encoded authentication information if a * proxy and authentication is configured, null * otherwise. */ function getProxyAuth() { if ($this->isProxyConfigured() && $this->proxy_user != '') { return base64_encode($this->proxy_user . ':' . $this->proxy_pass); } return null; } function getProxyUser() { return $this->proxy_user; } /** * Check if we are configured to use a proxy. * * @return boolean true if we are configured to use a proxy, false * otherwise. * @access public */ function isProxyConfigured() { return $this->proxy_host != ''; } /** * Open a socket to a remote server, possibly involving a HTTP * proxy. * * If an HTTP proxy has been configured (http_proxy PEAR_Config * setting), the proxy will be used. * * @param string $host the host to connect to * @param string $port the port to connect to * @param boolean $secure if true, establish a secure connection * using TLS. * @access public */ function openSocket($host, $port, $secure = false) { if ($this->isProxyConfigured()) { $fp = @fsockopen( $this->proxy_host, $this->proxy_port, $errno, $errstr, 15 ); if (!$fp) { return PEAR::raiseError("Connection to the proxy failed: $errstr", -9276); } /* HTTPS is to be used and we have a proxy, use CONNECT verb */ if ($secure) { $res = $this->_httpConnect($fp, $host, $port); if (PEAR::isError($res)) { return $res; } } } else { if ($secure) { $host = 'ssl://' . $host; } $fp = @fsockopen($host, $port, $errno, $errstr); if (!$fp) { return PEAR::raiseError("Connection to `$host:$port' failed: $errstr", $errno); } } return $fp; } } PKu]pPEAR/Dependency2.phpnu[ * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ /** * Required for the PEAR_VALIDATE_* constants */ require_once 'PEAR/Validate.php'; /** * Dependency check for PEAR packages * * This class handles both version 1.0 and 2.0 dependencies * WARNING: *any* changes to this class must be duplicated in the * test_PEAR_Dependency2 class found in tests/PEAR_Dependency2/setup.php.inc, * or unit tests will not actually validate the changes * @category pear * @package PEAR * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ class PEAR_Dependency2 { /** * One of the PEAR_VALIDATE_* states * @see PEAR_VALIDATE_NORMAL * @var integer */ var $_state; /** * Command-line options to install/upgrade/uninstall commands * @param array */ var $_options; /** * @var OS_Guess */ var $_os; /** * @var PEAR_Registry */ var $_registry; /** * @var PEAR_Config */ var $_config; /** * @var PEAR_DependencyDB */ var $_dependencydb; /** * Output of PEAR_Registry::parsedPackageName() * @var array */ var $_currentPackage; /** * @param PEAR_Config * @param array installation options * @param array format of PEAR_Registry::parsedPackageName() * @param int installation state (one of PEAR_VALIDATE_*) */ function __construct(&$config, $installoptions, $package, $state = PEAR_VALIDATE_INSTALLING) { $this->_config = &$config; if (!class_exists('PEAR_DependencyDB')) { require_once 'PEAR/DependencyDB.php'; } if (isset($installoptions['packagingroot'])) { // make sure depdb is in the right location $config->setInstallRoot($installoptions['packagingroot']); } $this->_registry = &$config->getRegistry(); $this->_dependencydb = &PEAR_DependencyDB::singleton($config); if (isset($installoptions['packagingroot'])) { $config->setInstallRoot(false); } $this->_options = $installoptions; $this->_state = $state; if (!class_exists('OS_Guess')) { require_once 'OS/Guess.php'; } $this->_os = new OS_Guess; $this->_currentPackage = $package; } static function _getExtraString($dep) { $extra = ' ('; if (isset($dep['uri'])) { return ''; } if (isset($dep['recommended'])) { $extra .= 'recommended version ' . $dep['recommended']; } else { if (isset($dep['min'])) { $extra .= 'version >= ' . $dep['min']; } if (isset($dep['max'])) { if ($extra != ' (') { $extra .= ', '; } $extra .= 'version <= ' . $dep['max']; } if (isset($dep['exclude'])) { if (!is_array($dep['exclude'])) { $dep['exclude'] = array($dep['exclude']); } if ($extra != ' (') { $extra .= ', '; } $extra .= 'excluded versions: '; foreach ($dep['exclude'] as $i => $exclude) { if ($i) { $extra .= ', '; } $extra .= $exclude; } } } $extra .= ')'; if ($extra == ' ()') { $extra = ''; } return $extra; } /** * This makes unit-testing a heck of a lot easier */ function getPHP_OS() { return PHP_OS; } /** * This makes unit-testing a heck of a lot easier */ function getsysname() { return $this->_os->getSysname(); } /** * Specify a dependency on an OS. Use arch for detailed os/processor information * * There are two generic OS dependencies that will be the most common, unix and windows. * Other options are linux, freebsd, darwin (OS X), sunos, irix, hpux, aix */ function validateOsDependency($dep) { if ($this->_state != PEAR_VALIDATE_INSTALLING && $this->_state != PEAR_VALIDATE_DOWNLOADING) { return true; } if ($dep['name'] == '*') { return true; } $not = isset($dep['conflicts']) ? true : false; switch (strtolower($dep['name'])) { case 'windows' : if ($not) { if (strtolower(substr($this->getPHP_OS(), 0, 3)) == 'win') { if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { return $this->raiseError("Cannot install %s on Windows"); } return $this->warning("warning: Cannot install %s on Windows"); } } else { if (strtolower(substr($this->getPHP_OS(), 0, 3)) != 'win') { if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { return $this->raiseError("Can only install %s on Windows"); } return $this->warning("warning: Can only install %s on Windows"); } } break; case 'unix' : $unices = array('linux', 'freebsd', 'darwin', 'sunos', 'irix', 'hpux', 'aix'); if ($not) { if (in_array($this->getSysname(), $unices)) { if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { return $this->raiseError("Cannot install %s on any Unix system"); } return $this->warning( "warning: Cannot install %s on any Unix system"); } } else { if (!in_array($this->getSysname(), $unices)) { if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { return $this->raiseError("Can only install %s on a Unix system"); } return $this->warning("warning: Can only install %s on a Unix system"); } } break; default : if ($not) { if (strtolower($dep['name']) == strtolower($this->getSysname())) { if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { return $this->raiseError('Cannot install %s on ' . $dep['name'] . ' operating system'); } return $this->warning('warning: Cannot install %s on ' . $dep['name'] . ' operating system'); } } else { if (strtolower($dep['name']) != strtolower($this->getSysname())) { if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { return $this->raiseError('Cannot install %s on ' . $this->getSysname() . ' operating system, can only install on ' . $dep['name']); } return $this->warning('warning: Cannot install %s on ' . $this->getSysname() . ' operating system, can only install on ' . $dep['name']); } } } return true; } /** * This makes unit-testing a heck of a lot easier */ function matchSignature($pattern) { return $this->_os->matchSignature($pattern); } /** * Specify a complex dependency on an OS/processor/kernel version, * Use OS for simple operating system dependency. * * This is the only dependency that accepts an eregable pattern. The pattern * will be matched against the php_uname() output parsed by OS_Guess */ function validateArchDependency($dep) { if ($this->_state != PEAR_VALIDATE_INSTALLING) { return true; } $not = isset($dep['conflicts']) ? true : false; if (!$this->matchSignature($dep['pattern'])) { if (!$not) { if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { return $this->raiseError('%s Architecture dependency failed, does not ' . 'match "' . $dep['pattern'] . '"'); } return $this->warning('warning: %s Architecture dependency failed, does ' . 'not match "' . $dep['pattern'] . '"'); } return true; } if ($not) { if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { return $this->raiseError('%s Architecture dependency failed, required "' . $dep['pattern'] . '"'); } return $this->warning('warning: %s Architecture dependency failed, ' . 'required "' . $dep['pattern'] . '"'); } return true; } /** * This makes unit-testing a heck of a lot easier */ function extension_loaded($name) { return extension_loaded($name); } /** * This makes unit-testing a heck of a lot easier */ function phpversion($name = null) { if ($name !== null) { return phpversion($name); } return phpversion(); } function validateExtensionDependency($dep, $required = true) { if ($this->_state != PEAR_VALIDATE_INSTALLING && $this->_state != PEAR_VALIDATE_DOWNLOADING) { return true; } $loaded = $this->extension_loaded($dep['name']); $extra = self::_getExtraString($dep); if (isset($dep['exclude'])) { if (!is_array($dep['exclude'])) { $dep['exclude'] = array($dep['exclude']); } } if (!isset($dep['min']) && !isset($dep['max']) && !isset($dep['recommended']) && !isset($dep['exclude']) ) { if ($loaded) { if (isset($dep['conflicts'])) { if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { return $this->raiseError('%s conflicts with PHP extension "' . $dep['name'] . '"' . $extra); } return $this->warning('warning: %s conflicts with PHP extension "' . $dep['name'] . '"' . $extra); } return true; } if (isset($dep['conflicts'])) { return true; } if ($required) { if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { return $this->raiseError('%s requires PHP extension "' . $dep['name'] . '"' . $extra); } return $this->warning('warning: %s requires PHP extension "' . $dep['name'] . '"' . $extra); } return $this->warning('%s can optionally use PHP extension "' . $dep['name'] . '"' . $extra); } if (!$loaded) { if (isset($dep['conflicts'])) { return true; } if (!$required) { return $this->warning('%s can optionally use PHP extension "' . $dep['name'] . '"' . $extra); } if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { return $this->raiseError('%s requires PHP extension "' . $dep['name'] . '"' . $extra); } return $this->warning('warning: %s requires PHP extension "' . $dep['name'] . '"' . $extra); } $version = (string) $this->phpversion($dep['name']); if (empty($version)) { $version = '0'; } $fail = false; if (isset($dep['min']) && !version_compare($version, $dep['min'], '>=')) { $fail = true; } if (isset($dep['max']) && !version_compare($version, $dep['max'], '<=')) { $fail = true; } if ($fail && !isset($dep['conflicts'])) { if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { return $this->raiseError('%s requires PHP extension "' . $dep['name'] . '"' . $extra . ', installed version is ' . $version); } return $this->warning('warning: %s requires PHP extension "' . $dep['name'] . '"' . $extra . ', installed version is ' . $version); } elseif ((isset($dep['min']) || isset($dep['max'])) && !$fail && isset($dep['conflicts'])) { if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { return $this->raiseError('%s conflicts with PHP extension "' . $dep['name'] . '"' . $extra . ', installed version is ' . $version); } return $this->warning('warning: %s conflicts with PHP extension "' . $dep['name'] . '"' . $extra . ', installed version is ' . $version); } if (isset($dep['exclude'])) { foreach ($dep['exclude'] as $exclude) { if (version_compare($version, $exclude, '==')) { if (isset($dep['conflicts'])) { continue; } if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { return $this->raiseError('%s is not compatible with PHP extension "' . $dep['name'] . '" version ' . $exclude); } return $this->warning('warning: %s is not compatible with PHP extension "' . $dep['name'] . '" version ' . $exclude); } elseif (version_compare($version, $exclude, '!=') && isset($dep['conflicts'])) { if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { return $this->raiseError('%s conflicts with PHP extension "' . $dep['name'] . '"' . $extra . ', installed version is ' . $version); } return $this->warning('warning: %s conflicts with PHP extension "' . $dep['name'] . '"' . $extra . ', installed version is ' . $version); } } } if (isset($dep['recommended'])) { if (version_compare($version, $dep['recommended'], '==')) { return true; } if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { return $this->raiseError('%s dependency: PHP extension ' . $dep['name'] . ' version "' . $version . '"' . ' is not the recommended version "' . $dep['recommended'] . '", but may be compatible, use --force to install'); } return $this->warning('warning: %s dependency: PHP extension ' . $dep['name'] . ' version "' . $version . '"' . ' is not the recommended version "' . $dep['recommended'].'"'); } return true; } function validatePhpDependency($dep) { if ($this->_state != PEAR_VALIDATE_INSTALLING && $this->_state != PEAR_VALIDATE_DOWNLOADING) { return true; } $version = $this->phpversion(); $extra = self::_getExtraString($dep); if (isset($dep['exclude'])) { if (!is_array($dep['exclude'])) { $dep['exclude'] = array($dep['exclude']); } } if (isset($dep['min'])) { if (!version_compare($version, $dep['min'], '>=')) { if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { return $this->raiseError('%s requires PHP' . $extra . ', installed version is ' . $version); } return $this->warning('warning: %s requires PHP' . $extra . ', installed version is ' . $version); } } if (isset($dep['max'])) { if (!version_compare($version, $dep['max'], '<=')) { if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { return $this->raiseError('%s requires PHP' . $extra . ', installed version is ' . $version); } return $this->warning('warning: %s requires PHP' . $extra . ', installed version is ' . $version); } } if (isset($dep['exclude'])) { foreach ($dep['exclude'] as $exclude) { if (version_compare($version, $exclude, '==')) { if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { return $this->raiseError('%s is not compatible with PHP version ' . $exclude); } return $this->warning( 'warning: %s is not compatible with PHP version ' . $exclude); } } } return true; } /** * This makes unit-testing a heck of a lot easier */ function getPEARVersion() { return '1.10.16'; } function validatePearinstallerDependency($dep) { $pearversion = $this->getPEARVersion(); $extra = self::_getExtraString($dep); if (isset($dep['exclude'])) { if (!is_array($dep['exclude'])) { $dep['exclude'] = array($dep['exclude']); } } if (version_compare($pearversion, $dep['min'], '<')) { if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { return $this->raiseError('%s requires PEAR Installer' . $extra . ', installed version is ' . $pearversion); } return $this->warning('warning: %s requires PEAR Installer' . $extra . ', installed version is ' . $pearversion); } if (isset($dep['max'])) { if (version_compare($pearversion, $dep['max'], '>')) { if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { return $this->raiseError('%s requires PEAR Installer' . $extra . ', installed version is ' . $pearversion); } return $this->warning('warning: %s requires PEAR Installer' . $extra . ', installed version is ' . $pearversion); } } if (isset($dep['exclude'])) { if (!isset($dep['exclude'][0])) { $dep['exclude'] = array($dep['exclude']); } foreach ($dep['exclude'] as $exclude) { if (version_compare($exclude, $pearversion, '==')) { if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { return $this->raiseError('%s is not compatible with PEAR Installer ' . 'version ' . $exclude); } return $this->warning('warning: %s is not compatible with PEAR ' . 'Installer version ' . $exclude); } } } return true; } function validateSubpackageDependency($dep, $required, $params) { return $this->validatePackageDependency($dep, $required, $params); } /** * @param array dependency information (2.0 format) * @param boolean whether this is a required dependency * @param array a list of downloaded packages to be installed, if any * @param boolean if true, then deps on pear.php.net that fail will also check * against pecl.php.net packages to accommodate extensions that have * moved to pecl.php.net from pear.php.net */ function validatePackageDependency($dep, $required, $params, $depv1 = false) { if ($this->_state != PEAR_VALIDATE_INSTALLING && $this->_state != PEAR_VALIDATE_DOWNLOADING) { return true; } if (isset($dep['providesextension'])) { if ($this->extension_loaded($dep['providesextension'])) { $save = $dep; $subdep = $dep; $subdep['name'] = $subdep['providesextension']; PEAR::pushErrorHandling(PEAR_ERROR_RETURN); $ret = $this->validateExtensionDependency($subdep, $required); PEAR::popErrorHandling(); if (!PEAR::isError($ret)) { return true; } } } if ($this->_state == PEAR_VALIDATE_INSTALLING) { return $this->_validatePackageInstall($dep, $required, $depv1); } if ($this->_state == PEAR_VALIDATE_DOWNLOADING) { return $this->_validatePackageDownload($dep, $required, $params, $depv1); } } function _validatePackageDownload($dep, $required, $params, $depv1 = false) { $dep['package'] = $dep['name']; if (isset($dep['uri'])) { $dep['channel'] = '__uri'; } $depname = $this->_registry->parsedPackageNameToString($dep, true); $found = false; foreach ($params as $param) { if ($param->isEqual( array('package' => $dep['name'], 'channel' => $dep['channel']))) { $found = true; break; } if ($depv1 && $dep['channel'] == 'pear.php.net') { if ($param->isEqual( array('package' => $dep['name'], 'channel' => 'pecl.php.net'))) { $found = true; break; } } } if (!$found && isset($dep['providesextension'])) { foreach ($params as $param) { if ($param->isExtension($dep['providesextension'])) { $found = true; break; } } } if ($found) { $version = $param->getVersion(); $installed = false; $downloaded = true; } else { if ($this->_registry->packageExists($dep['name'], $dep['channel'])) { $installed = true; $downloaded = false; $version = $this->_registry->packageinfo($dep['name'], 'version', $dep['channel']); } else { if ($dep['channel'] == 'pecl.php.net' && $this->_registry->packageExists($dep['name'], 'pear.php.net')) { $installed = true; $downloaded = false; $version = $this->_registry->packageinfo($dep['name'], 'version', 'pear.php.net'); } else { $version = 'not installed or downloaded'; $installed = false; $downloaded = false; } } } $extra = self::_getExtraString($dep); if (isset($dep['exclude']) && !is_array($dep['exclude'])) { $dep['exclude'] = array($dep['exclude']); } if (!isset($dep['min']) && !isset($dep['max']) && !isset($dep['recommended']) && !isset($dep['exclude']) ) { if ($installed || $downloaded) { $installed = $installed ? 'installed' : 'downloaded'; if (isset($dep['conflicts'])) { $rest = ''; if ($version) { $rest = ", $installed version is " . $version; } if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { return $this->raiseError('%s conflicts with package "' . $depname . '"' . $extra . $rest); } return $this->warning('warning: %s conflicts with package "' . $depname . '"' . $extra . $rest); } return true; } if (isset($dep['conflicts'])) { return true; } if ($required) { if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { return $this->raiseError('%s requires package "' . $depname . '"' . $extra); } return $this->warning('warning: %s requires package "' . $depname . '"' . $extra); } return $this->warning('%s can optionally use package "' . $depname . '"' . $extra); } if (!$installed && !$downloaded) { if (isset($dep['conflicts'])) { return true; } if ($required) { if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { return $this->raiseError('%s requires package "' . $depname . '"' . $extra); } return $this->warning('warning: %s requires package "' . $depname . '"' . $extra); } return $this->warning('%s can optionally use package "' . $depname . '"' . $extra); } $fail = false; if (isset($dep['min']) && version_compare($version, $dep['min'], '<')) { $fail = true; } if (isset($dep['max']) && version_compare($version, $dep['max'], '>')) { $fail = true; } if ($fail && !isset($dep['conflicts'])) { $installed = $installed ? 'installed' : 'downloaded'; $dep['package'] = $dep['name']; $dep = $this->_registry->parsedPackageNameToString($dep, true); if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { return $this->raiseError('%s requires package "' . $depname . '"' . $extra . ", $installed version is " . $version); } return $this->warning('warning: %s requires package "' . $depname . '"' . $extra . ", $installed version is " . $version); } elseif ((isset($dep['min']) || isset($dep['max'])) && !$fail && isset($dep['conflicts']) && !isset($dep['exclude'])) { $installed = $installed ? 'installed' : 'downloaded'; if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { return $this->raiseError('%s conflicts with package "' . $depname . '"' . $extra . ", $installed version is " . $version); } return $this->warning('warning: %s conflicts with package "' . $depname . '"' . $extra . ", $installed version is " . $version); } if (isset($dep['exclude'])) { $installed = $installed ? 'installed' : 'downloaded'; foreach ($dep['exclude'] as $exclude) { if (version_compare($version, $exclude, '==') && !isset($dep['conflicts'])) { if (!isset($this->_options['nodeps']) && !isset($this->_options['force']) ) { return $this->raiseError('%s is not compatible with ' . $installed . ' package "' . $depname . '" version ' . $exclude); } return $this->warning('warning: %s is not compatible with ' . $installed . ' package "' . $depname . '" version ' . $exclude); } elseif (version_compare($version, $exclude, '!=') && isset($dep['conflicts'])) { $installed = $installed ? 'installed' : 'downloaded'; if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { return $this->raiseError('%s conflicts with package "' . $depname . '"' . $extra . ", $installed version is " . $version); } return $this->warning('warning: %s conflicts with package "' . $depname . '"' . $extra . ", $installed version is " . $version); } } } if (isset($dep['recommended'])) { $installed = $installed ? 'installed' : 'downloaded'; if (version_compare($version, $dep['recommended'], '==')) { return true; } if (!$found && $installed) { $param = $this->_registry->getPackage($dep['name'], $dep['channel']); } if ($param) { $found = false; foreach ($params as $parent) { if ($parent->isEqual($this->_currentPackage)) { $found = true; break; } } if ($found) { if ($param->isCompatible($parent)) { return true; } } else { // this is for validPackage() calls $parent = $this->_registry->getPackage($this->_currentPackage['package'], $this->_currentPackage['channel']); if ($parent !== null && $param->isCompatible($parent)) { return true; } } } if (!isset($this->_options['nodeps']) && !isset($this->_options['force']) && !isset($this->_options['loose']) ) { return $this->raiseError('%s dependency package "' . $depname . '" ' . $installed . ' version ' . $version . ' is not the recommended version ' . $dep['recommended'] . ', but may be compatible, use --force to install'); } return $this->warning('warning: %s dependency package "' . $depname . '" ' . $installed . ' version ' . $version . ' is not the recommended version ' . $dep['recommended']); } return true; } function _validatePackageInstall($dep, $required, $depv1 = false) { return $this->_validatePackageDownload($dep, $required, array(), $depv1); } /** * Verify that uninstalling packages passed in to command line is OK. * * @param PEAR_Installer $dl * @return PEAR_Error|true */ function validatePackageUninstall(&$dl) { if (PEAR::isError($this->_dependencydb)) { return $this->_dependencydb; } $params = array(); // construct an array of "downloaded" packages to fool the package dependency checker // into using these to validate uninstalls of circular dependencies $downloaded = &$dl->getUninstallPackages(); foreach ($downloaded as $i => $pf) { if (!class_exists('PEAR_Downloader_Package')) { require_once 'PEAR/Downloader/Package.php'; } $dp = new PEAR_Downloader_Package($dl); $dp->setPackageFile($downloaded[$i]); $params[$i] = $dp; } // check cache $memyselfandI = strtolower($this->_currentPackage['channel']) . '/' . strtolower($this->_currentPackage['package']); if (isset($dl->___uninstall_package_cache)) { $badpackages = $dl->___uninstall_package_cache; if (isset($badpackages[$memyselfandI]['warnings'])) { foreach ($badpackages[$memyselfandI]['warnings'] as $warning) { $dl->log(0, $warning[0]); } } if (isset($badpackages[$memyselfandI]['errors'])) { foreach ($badpackages[$memyselfandI]['errors'] as $error) { if (is_array($error)) { $dl->log(0, $error[0]); } else { $dl->log(0, $error->getMessage()); } } if (isset($this->_options['nodeps']) || isset($this->_options['force'])) { return $this->warning( 'warning: %s should not be uninstalled, other installed packages depend ' . 'on this package'); } return $this->raiseError( '%s cannot be uninstalled, other installed packages depend on this package'); } return true; } // first, list the immediate parents of each package to be uninstalled $perpackagelist = array(); $allparents = array(); foreach ($params as $i => $param) { $a = array( 'channel' => strtolower($param->getChannel()), 'package' => strtolower($param->getPackage()) ); $deps = $this->_dependencydb->getDependentPackages($a); if ($deps) { foreach ($deps as $d) { $pardeps = $this->_dependencydb->getDependencies($d); foreach ($pardeps as $dep) { if (strtolower($dep['dep']['channel']) == $a['channel'] && strtolower($dep['dep']['name']) == $a['package']) { if (!isset($perpackagelist[$a['channel'] . '/' . $a['package']])) { $perpackagelist[$a['channel'] . '/' . $a['package']] = array(); } $perpackagelist[$a['channel'] . '/' . $a['package']][] = array($d['channel'] . '/' . $d['package'], $dep); if (!isset($allparents[$d['channel'] . '/' . $d['package']])) { $allparents[$d['channel'] . '/' . $d['package']] = array(); } if (!isset($allparents[$d['channel'] . '/' . $d['package']][$a['channel'] . '/' . $a['package']])) { $allparents[$d['channel'] . '/' . $d['package']][$a['channel'] . '/' . $a['package']] = array(); } $allparents[$d['channel'] . '/' . $d['package']] [$a['channel'] . '/' . $a['package']][] = array($d, $dep); } } } } } // next, remove any packages from the parents list that are not installed $remove = array(); foreach ($allparents as $parent => $d1) { foreach ($d1 as $d) { if ($this->_registry->packageExists($d[0][0]['package'], $d[0][0]['channel'])) { continue; } $remove[$parent] = true; } } // next remove any packages from the parents list that are not passed in for // uninstallation foreach ($allparents as $parent => $d1) { foreach ($d1 as $d) { foreach ($params as $param) { if (strtolower($param->getChannel()) == $d[0][0]['channel'] && strtolower($param->getPackage()) == $d[0][0]['package']) { // found it continue 3; } } $remove[$parent] = true; } } // remove all packages whose dependencies fail // save which ones failed for error reporting $badchildren = array(); do { $fail = false; foreach ($remove as $package => $unused) { if (!isset($allparents[$package])) { continue; } foreach ($allparents[$package] as $kid => $d1) { foreach ($d1 as $depinfo) { if ($depinfo[1]['type'] != 'optional') { if (isset($badchildren[$kid])) { continue; } $badchildren[$kid] = true; $remove[$kid] = true; $fail = true; continue 2; } } } if ($fail) { // start over, we removed some children continue 2; } } } while ($fail); // next, construct the list of packages that can't be uninstalled $badpackages = array(); $save = $this->_currentPackage; foreach ($perpackagelist as $package => $packagedeps) { foreach ($packagedeps as $parent) { if (!isset($remove[$parent[0]])) { continue; } $packagename = $this->_registry->parsePackageName($parent[0]); $packagename['channel'] = $this->_registry->channelAlias($packagename['channel']); $pa = $this->_registry->getPackage($packagename['package'], $packagename['channel']); $packagename['package'] = $pa->getPackage(); $this->_currentPackage = $packagename; // parent is not present in uninstall list, make sure we can actually // uninstall it (parent dep is optional) $parentname['channel'] = $this->_registry->channelAlias($parent[1]['dep']['channel']); $pa = $this->_registry->getPackage($parent[1]['dep']['name'], $parent[1]['dep']['channel']); $parentname['package'] = $pa->getPackage(); $parent[1]['dep']['package'] = $parentname['package']; $parent[1]['dep']['channel'] = $parentname['channel']; if ($parent[1]['type'] == 'optional') { $test = $this->_validatePackageUninstall($parent[1]['dep'], false, $dl); if ($test !== true) { $badpackages[$package]['warnings'][] = $test; } } else { $test = $this->_validatePackageUninstall($parent[1]['dep'], true, $dl); if ($test !== true) { $badpackages[$package]['errors'][] = $test; } } } } $this->_currentPackage = $save; $dl->___uninstall_package_cache = $badpackages; if (isset($badpackages[$memyselfandI])) { if (isset($badpackages[$memyselfandI]['warnings'])) { foreach ($badpackages[$memyselfandI]['warnings'] as $warning) { $dl->log(0, $warning[0]); } } if (isset($badpackages[$memyselfandI]['errors'])) { foreach ($badpackages[$memyselfandI]['errors'] as $error) { if (is_array($error)) { $dl->log(0, $error[0]); } else { $dl->log(0, $error->getMessage()); } } if (isset($this->_options['nodeps']) || isset($this->_options['force'])) { return $this->warning( 'warning: %s should not be uninstalled, other installed packages depend ' . 'on this package'); } return $this->raiseError( '%s cannot be uninstalled, other installed packages depend on this package'); } } return true; } function _validatePackageUninstall($dep, $required, $dl) { $depname = $this->_registry->parsedPackageNameToString($dep, true); $version = $this->_registry->packageinfo($dep['package'], 'version', $dep['channel']); if (!$version) { return true; } $extra = self::_getExtraString($dep); if (isset($dep['exclude']) && !is_array($dep['exclude'])) { $dep['exclude'] = array($dep['exclude']); } if (isset($dep['conflicts'])) { return true; // uninstall OK - these packages conflict (probably installed with --force) } if (!isset($dep['min']) && !isset($dep['max'])) { if (!$required) { return $this->warning('"' . $depname . '" can be optionally used by ' . 'installed package %s' . $extra); } if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { return $this->raiseError('"' . $depname . '" is required by ' . 'installed package %s' . $extra); } return $this->warning('warning: "' . $depname . '" is required by ' . 'installed package %s' . $extra); } $fail = false; if (isset($dep['min']) && version_compare($version, $dep['min'], '>=')) { $fail = true; } if (isset($dep['max']) && version_compare($version, $dep['max'], '<=')) { $fail = true; } // we re-use this variable, preserve the original value $saverequired = $required; if (!$required) { return $this->warning($depname . $extra . ' can be optionally used by installed package' . ' "%s"'); } if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { return $this->raiseError($depname . $extra . ' is required by installed package' . ' "%s"'); } return $this->raiseError('warning: ' . $depname . $extra . ' is required by installed package "%s"'); } /** * validate a downloaded package against installed packages * * As of PEAR 1.4.3, this will only validate * * @param array|PEAR_Downloader_Package|PEAR_PackageFile_v1|PEAR_PackageFile_v2 * $pkg package identifier (either * array('package' => blah, 'channel' => blah) or an array with * index 'info' referencing an object) * @param PEAR_Downloader $dl * @param array $params full list of packages to install * @return true|PEAR_Error */ function validatePackage($pkg, &$dl, $params = array()) { if (is_array($pkg) && isset($pkg['info'])) { $deps = $this->_dependencydb->getDependentPackageDependencies($pkg['info']); } else { $deps = $this->_dependencydb->getDependentPackageDependencies($pkg); } $fail = false; if ($deps) { if (!class_exists('PEAR_Downloader_Package')) { require_once 'PEAR/Downloader/Package.php'; } $dp = new PEAR_Downloader_Package($dl); if (is_object($pkg)) { $dp->setPackageFile($pkg); } else { $dp->setDownloadURL($pkg); } PEAR::pushErrorHandling(PEAR_ERROR_RETURN); foreach ($deps as $channel => $info) { foreach ($info as $package => $ds) { foreach ($params as $packd) { if (strtolower($packd->getPackage()) == strtolower($package) && $packd->getChannel() == $channel) { $dl->log(3, 'skipping installed package check of "' . $this->_registry->parsedPackageNameToString( array('channel' => $channel, 'package' => $package), true) . '", version "' . $packd->getVersion() . '" will be ' . 'downloaded and installed'); continue 2; // jump to next package } } foreach ($ds as $d) { $checker = new PEAR_Dependency2($this->_config, $this->_options, array('channel' => $channel, 'package' => $package), $this->_state); $dep = $d['dep']; $required = $d['type'] == 'required'; $ret = $checker->_validatePackageDownload($dep, $required, array(&$dp)); if (is_array($ret)) { $dl->log(0, $ret[0]); } elseif (PEAR::isError($ret)) { $dl->log(0, $ret->getMessage()); $fail = true; } } } } PEAR::popErrorHandling(); } if ($fail) { return $this->raiseError( '%s cannot be installed, conflicts with installed packages'); } return true; } /** * validate a package.xml 1.0 dependency */ function validateDependency1($dep, $params = array()) { if (!isset($dep['optional'])) { $dep['optional'] = 'no'; } list($newdep, $type) = self::normalizeDep($dep); if (!$newdep) { return $this->raiseError("Invalid Dependency"); } if (method_exists($this, "validate{$type}Dependency")) { return $this->{"validate{$type}Dependency"}($newdep, $dep['optional'] == 'no', $params, true); } } /** * Convert a 1.0 dep into a 2.0 dep */ static function normalizeDep($dep) { $types = array( 'pkg' => 'Package', 'ext' => 'Extension', 'os' => 'Os', 'php' => 'Php' ); if (!isset($types[$dep['type']])) { return array(false, false); } $type = $types[$dep['type']]; $newdep = array(); switch ($type) { case 'Package' : $newdep['channel'] = 'pear.php.net'; case 'Extension' : case 'Os' : $newdep['name'] = $dep['name']; break; } $dep['rel'] = PEAR_Dependency2::signOperator($dep['rel']); switch ($dep['rel']) { case 'has' : return array($newdep, $type); break; case 'not' : $newdep['conflicts'] = true; break; case '>=' : case '>' : $newdep['min'] = $dep['version']; if ($dep['rel'] == '>') { $newdep['exclude'] = $dep['version']; } break; case '<=' : case '<' : $newdep['max'] = $dep['version']; if ($dep['rel'] == '<') { $newdep['exclude'] = $dep['version']; } break; case 'ne' : case '!=' : $newdep['min'] = '0'; $newdep['max'] = '100000'; $newdep['exclude'] = $dep['version']; break; case '==' : $newdep['min'] = $dep['version']; $newdep['max'] = $dep['version']; break; } if ($type == 'Php') { if (!isset($newdep['min'])) { $newdep['min'] = '4.4.0'; } if (!isset($newdep['max'])) { $newdep['max'] = '6.0.0'; } } return array($newdep, $type); } /** * Converts text comparing operators to them sign equivalents * * Example: 'ge' to '>=' * * @access public * @param string Operator * @return string Sign equivalent */ static function signOperator($operator) { switch($operator) { case 'lt': return '<'; case 'le': return '<='; case 'gt': return '>'; case 'ge': return '>='; case 'eq': return '=='; case 'ne': return '!='; default: return $operator; } } function raiseError($msg) { if (isset($this->_options['ignore-errors'])) { return $this->warning($msg); } return PEAR::raiseError(sprintf($msg, $this->_registry->parsedPackageNameToString( $this->_currentPackage, true))); } function warning($msg) { return array(sprintf($msg, $this->_registry->parsedPackageNameToString( $this->_currentPackage, true))); } } PKu]ym6m6PEAR/Exception.phpnu[ * @author Hans Lellelid * @author Bertrand Mansion * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 1.3.3 */ /** * Base PEAR_Exception Class * * 1) Features: * * - Nestable exceptions (throw new PEAR_Exception($msg, $prev_exception)) * - Definable triggers, shot when exceptions occur * - Pretty and informative error messages * - Added more context info available (like class, method or cause) * - cause can be a PEAR_Exception or an array of mixed * PEAR_Exceptions/PEAR_ErrorStack warnings * - callbacks for specific exception classes and their children * * 2) Ideas: * * - Maybe a way to define a 'template' for the output * * 3) Inherited properties from PHP Exception Class: * * protected $message * protected $code * protected $line * protected $file * private $trace * * 4) Inherited methods from PHP Exception Class: * * __clone * __construct * getMessage * getCode * getFile * getLine * getTraceSafe * getTraceSafeAsString * __toString * * 5) Usage example * * * require_once 'PEAR/Exception.php'; * * class Test { * function foo() { * throw new PEAR_Exception('Error Message', ERROR_CODE); * } * } * * function myLogger($pear_exception) { * echo $pear_exception->getMessage(); * } * // each time a exception is thrown the 'myLogger' will be called * // (its use is completely optional) * PEAR_Exception::addObserver('myLogger'); * $test = new Test; * try { * $test->foo(); * } catch (PEAR_Exception $e) { * print $e; * } * * * @category pear * @package PEAR * @author Tomas V.V.Cox * @author Hans Lellelid * @author Bertrand Mansion * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.3.3 * */ class PEAR_Exception extends Exception { const OBSERVER_PRINT = -2; const OBSERVER_TRIGGER = -4; const OBSERVER_DIE = -8; protected $cause; private static $_observers = array(); private static $_uniqueid = 0; private $_trace; /** * Supported signatures: * - PEAR_Exception(string $message); * - PEAR_Exception(string $message, int $code); * - PEAR_Exception(string $message, Exception $cause); * - PEAR_Exception(string $message, Exception $cause, int $code); * - PEAR_Exception(string $message, PEAR_Error $cause); * - PEAR_Exception(string $message, PEAR_Error $cause, int $code); * - PEAR_Exception(string $message, array $causes); * - PEAR_Exception(string $message, array $causes, int $code); * @param string exception message * @param int|Exception|PEAR_Error|array|null exception cause * @param int|null exception code or null */ public function __construct($message, $p2 = null, $p3 = null) { if (is_int($p2)) { $code = $p2; $this->cause = null; } elseif (is_object($p2) || is_array($p2)) { // using is_object allows both Exception and PEAR_Error if (is_object($p2) && !($p2 instanceof Exception)) { if (!class_exists('PEAR_Error') || !($p2 instanceof PEAR_Error)) { throw new PEAR_Exception('exception cause must be Exception, ' . 'array, or PEAR_Error'); } } $code = $p3; if (is_array($p2) && isset($p2['message'])) { // fix potential problem of passing in a single warning $p2 = array($p2); } $this->cause = $p2; } else { $code = null; $this->cause = null; } parent::__construct($message, $code); $this->signal(); } /** * @param mixed $callback - A valid php callback, see php func is_callable() * - A PEAR_Exception::OBSERVER_* constant * - An array(const PEAR_Exception::OBSERVER_*, * mixed $options) * @param string $label The name of the observer. Use this if you want * to remove it later with removeObserver() */ public static function addObserver($callback, $label = 'default') { self::$_observers[$label] = $callback; } public static function removeObserver($label = 'default') { unset(self::$_observers[$label]); } /** * @return int unique identifier for an observer */ public static function getUniqueId() { return self::$_uniqueid++; } private function signal() { foreach (self::$_observers as $func) { if (is_callable($func)) { call_user_func($func, $this); continue; } settype($func, 'array'); switch ($func[0]) { case self::OBSERVER_PRINT : $f = (isset($func[1])) ? $func[1] : '%s'; printf($f, $this->getMessage()); break; case self::OBSERVER_TRIGGER : $f = (isset($func[1])) ? $func[1] : E_USER_NOTICE; trigger_error($this->getMessage(), $f); break; case self::OBSERVER_DIE : $f = (isset($func[1])) ? $func[1] : '%s'; die(printf($f, $this->getMessage())); break; default: trigger_error('invalid observer type', E_USER_WARNING); } } } /** * Return specific error information that can be used for more detailed * error messages or translation. * * This method may be overridden in child exception classes in order * to add functionality not present in PEAR_Exception and is a placeholder * to define API * * The returned array must be an associative array of parameter => value like so: *
     * array('name' => $name, 'context' => array(...))
     * 
* @return array */ public function getErrorData() { return array(); } /** * Returns the exception that caused this exception to be thrown * @access public * @return Exception|array The context of the exception */ public function getCause() { return $this->cause; } /** * Function must be public to call on caused exceptions * @param array */ public function getCauseMessage(&$causes) { $trace = $this->getTraceSafe(); $cause = array('class' => get_class($this), 'message' => $this->message, 'file' => 'unknown', 'line' => 'unknown'); if (isset($trace[0])) { if (isset($trace[0]['file'])) { $cause['file'] = $trace[0]['file']; $cause['line'] = $trace[0]['line']; } } $causes[] = $cause; if ($this->cause instanceof PEAR_Exception) { $this->cause->getCauseMessage($causes); } elseif ($this->cause instanceof Exception) { $causes[] = array('class' => get_class($this->cause), 'message' => $this->cause->getMessage(), 'file' => $this->cause->getFile(), 'line' => $this->cause->getLine()); } elseif (class_exists('PEAR_Error') && $this->cause instanceof PEAR_Error) { $causes[] = array('class' => get_class($this->cause), 'message' => $this->cause->getMessage(), 'file' => 'unknown', 'line' => 'unknown'); } elseif (is_array($this->cause)) { foreach ($this->cause as $cause) { if ($cause instanceof PEAR_Exception) { $cause->getCauseMessage($causes); } elseif ($cause instanceof Exception) { $causes[] = array('class' => get_class($cause), 'message' => $cause->getMessage(), 'file' => $cause->getFile(), 'line' => $cause->getLine()); } elseif (class_exists('PEAR_Error') && $cause instanceof PEAR_Error) { $causes[] = array('class' => get_class($cause), 'message' => $cause->getMessage(), 'file' => 'unknown', 'line' => 'unknown'); } elseif (is_array($cause) && isset($cause['message'])) { // PEAR_ErrorStack warning $causes[] = array( 'class' => $cause['package'], 'message' => $cause['message'], 'file' => isset($cause['context']['file']) ? $cause['context']['file'] : 'unknown', 'line' => isset($cause['context']['line']) ? $cause['context']['line'] : 'unknown', ); } } } } public function getTraceSafe() { if (!isset($this->_trace)) { $this->_trace = $this->getTrace(); if (empty($this->_trace)) { $backtrace = debug_backtrace(); $this->_trace = array($backtrace[count($backtrace)-1]); } } return $this->_trace; } public function getErrorClass() { $trace = $this->getTraceSafe(); return $trace[0]['class']; } public function getErrorMethod() { $trace = $this->getTraceSafe(); return $trace[0]['function']; } public function __toString() { if (isset($_SERVER['REQUEST_URI'])) { return $this->toHtml(); } return $this->toText(); } public function toHtml() { $trace = $this->getTraceSafe(); $causes = array(); $this->getCauseMessage($causes); $html = '' . "\n"; foreach ($causes as $i => $cause) { $html .= '\n"; } $html .= '' . "\n" . '' . '' . '' . "\n"; foreach ($trace as $k => $v) { $html .= '' . '' . '' . "\n"; } $html .= '' . '' . '' . "\n" . '
' . str_repeat('-', $i) . ' ' . $cause['class'] . ': ' . htmlspecialchars($cause['message']) . ' in ' . $cause['file'] . ' ' . 'on line ' . $cause['line'] . '' . "
Exception trace
#FunctionLocation
' . $k . ''; if (!empty($v['class'])) { $html .= $v['class'] . $v['type']; } $html .= $v['function']; $args = array(); if (!empty($v['args'])) { foreach ($v['args'] as $arg) { if (is_null($arg)) $args[] = 'null'; elseif (is_array($arg)) $args[] = 'Array'; elseif (is_object($arg)) $args[] = 'Object('.get_class($arg).')'; elseif (is_bool($arg)) $args[] = $arg ? 'true' : 'false'; elseif (is_int($arg) || is_double($arg)) $args[] = $arg; else { $arg = (string)$arg; $str = htmlspecialchars(substr($arg, 0, 16)); if (strlen($arg) > 16) $str .= '…'; $args[] = "'" . $str . "'"; } } } $html .= '(' . implode(', ',$args) . ')' . '' . (isset($v['file']) ? $v['file'] : 'unknown') . ':' . (isset($v['line']) ? $v['line'] : 'unknown') . '
' . ($k+1) . '{main} 
'; return $html; } public function toText() { $causes = array(); $this->getCauseMessage($causes); $causeMsg = ''; foreach ($causes as $i => $cause) { $causeMsg .= str_repeat(' ', $i) . $cause['class'] . ': ' . $cause['message'] . ' in ' . $cause['file'] . ' on line ' . $cause['line'] . "\n"; } return $causeMsg . $this->getTraceAsString(); } }PKu]b PEAR/ErrorStack.phpnu[ * @copyright 2004-2008 Greg Beaver * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR_ErrorStack */ /** * Singleton storage * * Format: *
 * array(
 *  'package1' => PEAR_ErrorStack object,
 *  'package2' => PEAR_ErrorStack object,
 *  ...
 * )
 * 
* @access private * @global array $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] */ $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] = array(); /** * Global error callback (default) * * This is only used if set to non-false. * is the default callback for * all packages, whereas specific packages may set a default callback * for all instances, regardless of whether they are a singleton or not. * * To exclude non-singletons, only set the local callback for the singleton * @see PEAR_ErrorStack::setDefaultCallback() * @access private * @global array $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'] */ $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'] = array( '*' => false, ); /** * Global Log object (default) * * This is only used if set to non-false. Use to set a default log object for * all stacks, regardless of instantiation order or location * @see PEAR_ErrorStack::setDefaultLogger() * @access private * @global array $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] */ $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = false; /** * Global Overriding Callback * * This callback will override any error callbacks that specific loggers have set. * Use with EXTREME caution * @see PEAR_ErrorStack::staticPushCallback() * @access private * @global array $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] */ $GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'] = array(); /**#@+ * One of four possible return values from the error Callback * @see PEAR_ErrorStack::_errorCallback() */ /** * If this is returned, then the error will be both pushed onto the stack * and logged. */ define('PEAR_ERRORSTACK_PUSHANDLOG', 1); /** * If this is returned, then the error will only be pushed onto the stack, * and not logged. */ define('PEAR_ERRORSTACK_PUSH', 2); /** * If this is returned, then the error will only be logged, but not pushed * onto the error stack. */ define('PEAR_ERRORSTACK_LOG', 3); /** * If this is returned, then the error is completely ignored. */ define('PEAR_ERRORSTACK_IGNORE', 4); /** * If this is returned, then the error is logged and die() is called. */ define('PEAR_ERRORSTACK_DIE', 5); /**#@-*/ /** * Error code for an attempt to instantiate a non-class as a PEAR_ErrorStack in * the singleton method. */ define('PEAR_ERRORSTACK_ERR_NONCLASS', 1); /** * Error code for an attempt to pass an object into {@link PEAR_ErrorStack::getMessage()} * that has no __toString() method */ define('PEAR_ERRORSTACK_ERR_OBJTOSTRING', 2); /** * Error Stack Implementation * * Usage: * * // global error stack * $global_stack = &PEAR_ErrorStack::singleton('MyPackage'); * // local error stack * $local_stack = new PEAR_ErrorStack('MyPackage'); * * @author Greg Beaver * @version 1.10.16 * @package PEAR_ErrorStack * @category Debugging * @copyright 2004-2008 Greg Beaver * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR_ErrorStack */ class PEAR_ErrorStack { /** * Errors are stored in the order that they are pushed on the stack. * @since 0.4alpha Errors are no longer organized by error level. * This renders pop() nearly unusable, and levels could be more easily * handled in a callback anyway * @var array * @access private */ var $_errors = array(); /** * Storage of errors by level. * * Allows easy retrieval and deletion of only errors from a particular level * @since PEAR 1.4.0dev * @var array * @access private */ var $_errorsByLevel = array(); /** * Package name this error stack represents * @var string * @access protected */ var $_package; /** * Determines whether a PEAR_Error is thrown upon every error addition * @var boolean * @access private */ var $_compat = false; /** * If set to a valid callback, this will be used to generate the error * message from the error code, otherwise the message passed in will be * used * @var false|string|array * @access private */ var $_msgCallback = false; /** * If set to a valid callback, this will be used to generate the error * context for an error. For PHP-related errors, this will be a file * and line number as retrieved from debug_backtrace(), but can be * customized for other purposes. The error might actually be in a separate * configuration file, or in a database query. * @var false|string|array * @access protected */ var $_contextCallback = false; /** * If set to a valid callback, this will be called every time an error * is pushed onto the stack. The return value will be used to determine * whether to allow an error to be pushed or logged. * * The return value must be one an PEAR_ERRORSTACK_* constant * @see PEAR_ERRORSTACK_PUSHANDLOG, PEAR_ERRORSTACK_PUSH, PEAR_ERRORSTACK_LOG * @var false|string|array * @access protected */ var $_errorCallback = array(); /** * PEAR::Log object for logging errors * @var false|Log * @access protected */ var $_logger = false; /** * Error messages - designed to be overridden * @var array * @abstract */ var $_errorMsgs = array(); /** * Set up a new error stack * * @param string $package name of the package this error stack represents * @param callback $msgCallback callback used for error message generation * @param callback $contextCallback callback used for context generation, * defaults to {@link getFileLine()} * @param boolean $throwPEAR_Error */ function __construct($package, $msgCallback = false, $contextCallback = false, $throwPEAR_Error = false) { $this->_package = $package; $this->setMessageCallback($msgCallback); $this->setContextCallback($contextCallback); $this->_compat = $throwPEAR_Error; } /** * Return a single error stack for this package. * * Note that all parameters are ignored if the stack for package $package * has already been instantiated * @param string $package name of the package this error stack represents * @param callback $msgCallback callback used for error message generation * @param callback $contextCallback callback used for context generation, * defaults to {@link getFileLine()} * @param boolean $throwPEAR_Error * @param string $stackClass class to instantiate * * @return PEAR_ErrorStack */ public static function &singleton( $package, $msgCallback = false, $contextCallback = false, $throwPEAR_Error = false, $stackClass = 'PEAR_ErrorStack' ) { if (isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) { return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]; } if (!class_exists($stackClass)) { if (function_exists('debug_backtrace')) { $trace = debug_backtrace(); } PEAR_ErrorStack::staticPush('PEAR_ErrorStack', PEAR_ERRORSTACK_ERR_NONCLASS, 'exception', array('stackclass' => $stackClass), 'stack class "%stackclass%" is not a valid class name (should be like PEAR_ErrorStack)', false, $trace); } $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package] = new $stackClass($package, $msgCallback, $contextCallback, $throwPEAR_Error); return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]; } /** * Internal error handler for PEAR_ErrorStack class * * Dies if the error is an exception (and would have died anyway) * @access private */ function _handleError($err) { if ($err['level'] == 'exception') { $message = $err['message']; if (isset($_SERVER['REQUEST_URI'])) { echo '
'; } else { echo "\n"; } var_dump($err['context']); die($message); } } /** * Set up a PEAR::Log object for all error stacks that don't have one * @param Log $log */ public static function setDefaultLogger(&$log) { if (is_object($log) && method_exists($log, 'log') ) { $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = &$log; } elseif (is_callable($log)) { $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = &$log; } } /** * Set up a PEAR::Log object for this error stack * @param Log $log */ function setLogger(&$log) { if (is_object($log) && method_exists($log, 'log') ) { $this->_logger = &$log; } elseif (is_callable($log)) { $this->_logger = &$log; } } /** * Set an error code => error message mapping callback * * This method sets the callback that can be used to generate error * messages for any instance * @param array|string Callback function/method */ function setMessageCallback($msgCallback) { if (!$msgCallback) { $this->_msgCallback = array(&$this, 'getErrorMessage'); } else { if (is_callable($msgCallback)) { $this->_msgCallback = $msgCallback; } } } /** * Get an error code => error message mapping callback * * This method returns the current callback that can be used to generate error * messages * @return array|string|false Callback function/method or false if none */ function getMessageCallback() { return $this->_msgCallback; } /** * Sets a default callback to be used by all error stacks * * This method sets the callback that can be used to generate error * messages for a singleton * @param array|string Callback function/method * @param string Package name, or false for all packages */ public static function setDefaultCallback($callback = false, $package = false) { if (!is_callable($callback)) { $callback = false; } $package = $package ? $package : '*'; $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'][$package] = $callback; } /** * Set a callback that generates context information (location of error) for an error stack * * This method sets the callback that can be used to generate context * information for an error. Passing in NULL will disable context generation * and remove the expensive call to debug_backtrace() * @param array|string|null Callback function/method */ function setContextCallback($contextCallback) { if ($contextCallback === null) { return $this->_contextCallback = false; } if (!$contextCallback) { $this->_contextCallback = array(&$this, 'getFileLine'); } else { if (is_callable($contextCallback)) { $this->_contextCallback = $contextCallback; } } } /** * Set an error Callback * If set to a valid callback, this will be called every time an error * is pushed onto the stack. The return value will be used to determine * whether to allow an error to be pushed or logged. * * The return value must be one of the ERRORSTACK_* constants. * * This functionality can be used to emulate PEAR's pushErrorHandling, and * the PEAR_ERROR_CALLBACK mode, without affecting the integrity of * the error stack or logging * @see PEAR_ERRORSTACK_PUSHANDLOG, PEAR_ERRORSTACK_PUSH, PEAR_ERRORSTACK_LOG * @see popCallback() * @param string|array $cb */ function pushCallback($cb) { array_push($this->_errorCallback, $cb); } /** * Remove a callback from the error callback stack * @see pushCallback() * @return array|string|false */ function popCallback() { if (!count($this->_errorCallback)) { return false; } return array_pop($this->_errorCallback); } /** * Set a temporary overriding error callback for every package error stack * * Use this to temporarily disable all existing callbacks (can be used * to emulate the @ operator, for instance) * @see PEAR_ERRORSTACK_PUSHANDLOG, PEAR_ERRORSTACK_PUSH, PEAR_ERRORSTACK_LOG * @see staticPopCallback(), pushCallback() * @param string|array $cb */ public static function staticPushCallback($cb) { array_push($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'], $cb); } /** * Remove a temporary overriding error callback * @see staticPushCallback() * @return array|string|false */ public static function staticPopCallback() { $ret = array_pop($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK']); if (!is_array($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'])) { $GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'] = array(); } return $ret; } /** * Add an error to the stack * * If the message generator exists, it is called with 2 parameters. * - the current Error Stack object * - an array that is in the same format as an error. Available indices * are 'code', 'package', 'time', 'params', 'level', and 'context' * * Next, if the error should contain context information, this is * handled by the context grabbing method. * Finally, the error is pushed onto the proper error stack * @param int $code Package-specific error code * @param string $level Error level. This is NOT spell-checked * @param array $params associative array of error parameters * @param string $msg Error message, or a portion of it if the message * is to be generated * @param array $repackage If this error re-packages an error pushed by * another package, place the array returned from * {@link pop()} in this parameter * @param array $backtrace Protected parameter: use this to pass in the * {@link debug_backtrace()} that should be used * to find error context * @return PEAR_Error|array if compatibility mode is on, a PEAR_Error is also * thrown. If a PEAR_Error is returned, the userinfo * property is set to the following array: * * * array( * 'code' => $code, * 'params' => $params, * 'package' => $this->_package, * 'level' => $level, * 'time' => time(), * 'context' => $context, * 'message' => $msg, * //['repackage' => $err] repackaged error array/Exception class * ); * * * Normally, the previous array is returned. */ function push($code, $level = 'error', $params = array(), $msg = false, $repackage = false, $backtrace = false) { $context = false; // grab error context if ($this->_contextCallback) { if (!$backtrace) { $backtrace = debug_backtrace(); } $context = call_user_func($this->_contextCallback, $code, $params, $backtrace); } // save error $time = explode(' ', microtime()); $time = $time[1] + $time[0]; $err = array( 'code' => $code, 'params' => $params, 'package' => $this->_package, 'level' => $level, 'time' => $time, 'context' => $context, 'message' => $msg, ); if ($repackage) { $err['repackage'] = $repackage; } // set up the error message, if necessary if ($this->_msgCallback) { $msg = call_user_func_array($this->_msgCallback, array(&$this, $err)); $err['message'] = $msg; } $push = $log = true; $die = false; // try the overriding callback first $callback = $this->staticPopCallback(); if ($callback) { $this->staticPushCallback($callback); } if (!is_callable($callback)) { // try the local callback next $callback = $this->popCallback(); if (is_callable($callback)) { $this->pushCallback($callback); } else { // try the default callback $callback = isset($GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'][$this->_package]) ? $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'][$this->_package] : $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK']['*']; } } if (is_callable($callback)) { switch(call_user_func($callback, $err)){ case PEAR_ERRORSTACK_IGNORE: return $err; break; case PEAR_ERRORSTACK_PUSH: $log = false; break; case PEAR_ERRORSTACK_LOG: $push = false; break; case PEAR_ERRORSTACK_DIE: $die = true; break; // anything else returned has the same effect as pushandlog } } if ($push) { array_unshift($this->_errors, $err); if (!isset($this->_errorsByLevel[$err['level']])) { $this->_errorsByLevel[$err['level']] = array(); } $this->_errorsByLevel[$err['level']][] = &$this->_errors[0]; } if ($log) { if ($this->_logger || $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER']) { $this->_log($err); } } if ($die) { die(); } if ($this->_compat && $push) { return $this->raiseError($msg, $code, null, null, $err); } return $err; } /** * Static version of {@link push()} * * @param string $package Package name this error belongs to * @param int $code Package-specific error code * @param string $level Error level. This is NOT spell-checked * @param array $params associative array of error parameters * @param string $msg Error message, or a portion of it if the message * is to be generated * @param array $repackage If this error re-packages an error pushed by * another package, place the array returned from * {@link pop()} in this parameter * @param array $backtrace Protected parameter: use this to pass in the * {@link debug_backtrace()} that should be used * to find error context * @return PEAR_Error|array if compatibility mode is on, a PEAR_Error is also * thrown. see docs for {@link push()} */ public static function staticPush( $package, $code, $level = 'error', $params = array(), $msg = false, $repackage = false, $backtrace = false ) { $s = &PEAR_ErrorStack::singleton($package); if ($s->_contextCallback) { if (!$backtrace) { if (function_exists('debug_backtrace')) { $backtrace = debug_backtrace(); } } } return $s->push($code, $level, $params, $msg, $repackage, $backtrace); } /** * Log an error using PEAR::Log * @param array $err Error array * @param array $levels Error level => Log constant map * @access protected */ function _log($err) { if ($this->_logger) { $logger = &$this->_logger; } else { $logger = &$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER']; } if (is_a($logger, 'Log')) { $levels = array( 'exception' => PEAR_LOG_CRIT, 'alert' => PEAR_LOG_ALERT, 'critical' => PEAR_LOG_CRIT, 'error' => PEAR_LOG_ERR, 'warning' => PEAR_LOG_WARNING, 'notice' => PEAR_LOG_NOTICE, 'info' => PEAR_LOG_INFO, 'debug' => PEAR_LOG_DEBUG); if (isset($levels[$err['level']])) { $level = $levels[$err['level']]; } else { $level = PEAR_LOG_INFO; } $logger->log($err['message'], $level, $err); } else { // support non-standard logs call_user_func($logger, $err); } } /** * Pop an error off of the error stack * * @return false|array * @since 0.4alpha it is no longer possible to specify a specific error * level to return - the last error pushed will be returned, instead */ function pop() { $err = @array_shift($this->_errors); if (!is_null($err)) { @array_pop($this->_errorsByLevel[$err['level']]); if (!count($this->_errorsByLevel[$err['level']])) { unset($this->_errorsByLevel[$err['level']]); } } return $err; } /** * Pop an error off of the error stack, static method * * @param string package name * @return boolean * @since PEAR1.5.0a1 */ static function staticPop($package) { if ($package) { if (!isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) { return false; } return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]->pop(); } } /** * Determine whether there are any errors on the stack * @param string|array Level name. Use to determine if any errors * of level (string), or levels (array) have been pushed * @return boolean */ function hasErrors($level = false) { if ($level) { return isset($this->_errorsByLevel[$level]); } return count($this->_errors); } /** * Retrieve all errors since last purge * * @param boolean set in order to empty the error stack * @param string level name, to return only errors of a particular severity * @return array */ function getErrors($purge = false, $level = false) { if (!$purge) { if ($level) { if (!isset($this->_errorsByLevel[$level])) { return array(); } else { return $this->_errorsByLevel[$level]; } } else { return $this->_errors; } } if ($level) { $ret = $this->_errorsByLevel[$level]; foreach ($this->_errorsByLevel[$level] as $i => $unused) { // entries are references to the $_errors array $this->_errorsByLevel[$level][$i] = false; } // array_filter removes all entries === false $this->_errors = array_filter($this->_errors); unset($this->_errorsByLevel[$level]); return $ret; } $ret = $this->_errors; $this->_errors = array(); $this->_errorsByLevel = array(); return $ret; } /** * Determine whether there are any errors on a single error stack, or on any error stack * * The optional parameter can be used to test the existence of any errors without the need of * singleton instantiation * @param string|false Package name to check for errors * @param string Level name to check for a particular severity * @return boolean */ public static function staticHasErrors($package = false, $level = false) { if ($package) { if (!isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) { return false; } return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]->hasErrors($level); } foreach ($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] as $package => $obj) { if ($obj->hasErrors($level)) { return true; } } return false; } /** * Get a list of all errors since last purge, organized by package * @since PEAR 1.4.0dev BC break! $level is now in the place $merge used to be * @param boolean $purge Set to purge the error stack of existing errors * @param string $level Set to a level name in order to retrieve only errors of a particular level * @param boolean $merge Set to return a flat array, not organized by package * @param array $sortfunc Function used to sort a merged array - default * sorts by time, and should be good for most cases * * @return array */ public static function staticGetErrors( $purge = false, $level = false, $merge = false, $sortfunc = array('PEAR_ErrorStack', '_sortErrors') ) { $ret = array(); if (!is_callable($sortfunc)) { $sortfunc = array('PEAR_ErrorStack', '_sortErrors'); } foreach ($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] as $package => $obj) { $test = $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]->getErrors($purge, $level); if ($test) { if ($merge) { $ret = array_merge($ret, $test); } else { $ret[$package] = $test; } } } if ($merge) { usort($ret, $sortfunc); } return $ret; } /** * Error sorting function, sorts by time * @access private */ public static function _sortErrors($a, $b) { if ($a['time'] == $b['time']) { return 0; } if ($a['time'] < $b['time']) { return 1; } return -1; } /** * Standard file/line number/function/class context callback * * This function uses a backtrace generated from {@link debug_backtrace()} * and so will not work at all in PHP < 4.3.0. The frame should * reference the frame that contains the source of the error. * @return array|false either array('file' => file, 'line' => line, * 'function' => function name, 'class' => class name) or * if this doesn't work, then false * @param unused * @param integer backtrace frame. * @param array Results of debug_backtrace() */ public static function getFileLine($code, $params, $backtrace = null) { if ($backtrace === null) { return false; } $frame = 0; $functionframe = 1; if (!isset($backtrace[1])) { $functionframe = 0; } else { while (isset($backtrace[$functionframe]['function']) && $backtrace[$functionframe]['function'] == 'eval' && isset($backtrace[$functionframe + 1])) { $functionframe++; } } if (isset($backtrace[$frame])) { if (!isset($backtrace[$frame]['file'])) { $frame++; } $funcbacktrace = $backtrace[$functionframe]; $filebacktrace = $backtrace[$frame]; $ret = array('file' => $filebacktrace['file'], 'line' => $filebacktrace['line']); // rearrange for eval'd code or create function errors if (strpos($filebacktrace['file'], '(') && preg_match(';^(.*?)\((\d+)\) : (.*?)\\z;', $filebacktrace['file'], $matches)) { $ret['file'] = $matches[1]; $ret['line'] = $matches[2] + 0; } if (isset($funcbacktrace['function']) && isset($backtrace[1])) { if ($funcbacktrace['function'] != 'eval') { if ($funcbacktrace['function'] == '__lambda_func') { $ret['function'] = 'create_function() code'; } else { $ret['function'] = $funcbacktrace['function']; } } } if (isset($funcbacktrace['class']) && isset($backtrace[1])) { $ret['class'] = $funcbacktrace['class']; } return $ret; } return false; } /** * Standard error message generation callback * * This method may also be called by a custom error message generator * to fill in template values from the params array, simply * set the third parameter to the error message template string to use * * The special variable %__msg% is reserved: use it only to specify * where a message passed in by the user should be placed in the template, * like so: * * Error message: %msg% - internal error * * If the message passed like so: * * * $stack->push(ERROR_CODE, 'error', array(), 'server error 500'); * * * The returned error message will be "Error message: server error 500 - * internal error" * @param PEAR_ErrorStack * @param array * @param string|false Pre-generated error message template * * @return string */ public static function getErrorMessage(&$stack, $err, $template = false) { if ($template) { $mainmsg = $template; } else { $mainmsg = $stack->getErrorMessageTemplate($err['code']); } $mainmsg = str_replace('%__msg%', $err['message'], $mainmsg); if (is_array($err['params']) && count($err['params'])) { foreach ($err['params'] as $name => $val) { if (is_array($val)) { // @ is needed in case $val is a multi-dimensional array $val = @implode(', ', $val); } if (is_object($val)) { if (method_exists($val, '__toString')) { $val = $val->__toString(); } else { PEAR_ErrorStack::staticPush('PEAR_ErrorStack', PEAR_ERRORSTACK_ERR_OBJTOSTRING, 'warning', array('obj' => get_class($val)), 'object %obj% passed into getErrorMessage, but has no __toString() method'); $val = 'Object'; } } $mainmsg = str_replace('%' . $name . '%', $val, $mainmsg); } } return $mainmsg; } /** * Standard Error Message Template generator from code * @return string */ function getErrorMessageTemplate($code) { if (!isset($this->_errorMsgs[$code])) { return '%__msg%'; } return $this->_errorMsgs[$code]; } /** * Set the Error Message Template array * * The array format must be: *
     * array(error code => 'message template',...)
     * 
* * Error message parameters passed into {@link push()} will be used as input * for the error message. If the template is 'message %foo% was %bar%', and the * parameters are array('foo' => 'one', 'bar' => 'six'), the error message returned will * be 'message one was six' * @return string */ function setErrorMessageTemplate($template) { $this->_errorMsgs = $template; } /** * emulate PEAR::raiseError() * * @return PEAR_Error */ function raiseError() { require_once 'PEAR.php'; $args = func_get_args(); return call_user_func_array(array('PEAR', 'raiseError'), $args); } } $stack = &PEAR_ErrorStack::singleton('PEAR_ErrorStack'); $stack->pushCallback(array('PEAR_ErrorStack', '_handleError')); ?> PKu][ WPEAR/XMLParser.phpnu[ * @author Stephan Schmidt (original XML_Unserializer code) * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ /** * Parser for any xml file * @category pear * @package PEAR * @author Greg Beaver * @author Stephan Schmidt (original XML_Unserializer code) * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ class PEAR_XMLParser { /** * unserilialized data * @var string $_serializedData */ var $_unserializedData = null; /** * name of the root tag * @var string $_root */ var $_root = null; /** * stack for all data that is found * @var array $_dataStack */ var $_dataStack = array(); /** * stack for all values that are generated * @var array $_valStack */ var $_valStack = array(); /** * current tag depth * @var int $_depth */ var $_depth = 0; /** * The XML encoding to use * @var string $encoding */ var $encoding = 'ISO-8859-1'; /** * @return array */ function getData() { return $this->_unserializedData; } /** * @param string xml content * @return true|PEAR_Error */ function parse($data) { if (!extension_loaded('xml')) { include_once 'PEAR.php'; return PEAR::raiseError("XML Extension not found", 1); } $this->_dataStack = $this->_valStack = array(); $this->_depth = 0; if ( strpos($data, 'encoding="UTF-8"') || strpos($data, 'encoding="utf-8"') || strpos($data, "encoding='UTF-8'") || strpos($data, "encoding='utf-8'") ) { $this->encoding = 'UTF-8'; } $xp = xml_parser_create($this->encoding); xml_parser_set_option($xp, XML_OPTION_CASE_FOLDING, 0); xml_set_object($xp, $this); xml_set_element_handler($xp, 'startHandler', 'endHandler'); xml_set_character_data_handler($xp, 'cdataHandler'); if (!xml_parse($xp, $data)) { $msg = xml_error_string(xml_get_error_code($xp)); $line = xml_get_current_line_number($xp); xml_parser_free($xp); include_once 'PEAR.php'; return PEAR::raiseError("XML Error: '$msg' on line '$line'", 2); } xml_parser_free($xp); return true; } /** * Start element handler for XML parser * * @access private * @param object $parser XML parser object * @param string $element XML element * @param array $attribs attributes of XML tag * @return void */ function startHandler($parser, $element, $attribs) { $this->_depth++; $this->_dataStack[$this->_depth] = null; $val = array( 'name' => $element, 'value' => null, 'type' => 'string', 'childrenKeys' => array(), 'aggregKeys' => array() ); if (count($attribs) > 0) { $val['children'] = array(); $val['type'] = 'array'; $val['children']['attribs'] = $attribs; } array_push($this->_valStack, $val); } /** * post-process data * * @param string $data * @param string $element element name */ function postProcess($data, $element) { return trim($data); } /** * End element handler for XML parser * * @access private * @param object XML parser object * @param string * @return void */ function endHandler($parser, $element) { $value = array_pop($this->_valStack); $data = $this->postProcess($this->_dataStack[$this->_depth], $element); // adjust type of the value switch (strtolower($value['type'])) { // unserialize an array case 'array': if ($data !== '') { $value['children']['_content'] = $data; } $value['value'] = isset($value['children']) ? $value['children'] : array(); break; /* * unserialize a null value */ case 'null': $data = null; break; /* * unserialize any scalar value */ default: settype($data, $value['type']); $value['value'] = $data; break; } $parent = array_pop($this->_valStack); if ($parent === null) { $this->_unserializedData = &$value['value']; $this->_root = &$value['name']; return true; } // parent has to be an array if (!isset($parent['children']) || !is_array($parent['children'])) { $parent['children'] = array(); if ($parent['type'] != 'array') { $parent['type'] = 'array'; } } if (!empty($value['name'])) { // there already has been a tag with this name if (in_array($value['name'], $parent['childrenKeys'])) { // no aggregate has been created for this tag if (!in_array($value['name'], $parent['aggregKeys'])) { if (isset($parent['children'][$value['name']])) { $parent['children'][$value['name']] = array($parent['children'][$value['name']]); } else { $parent['children'][$value['name']] = array(); } array_push($parent['aggregKeys'], $value['name']); } array_push($parent['children'][$value['name']], $value['value']); } else { $parent['children'][$value['name']] = &$value['value']; array_push($parent['childrenKeys'], $value['name']); } } else { array_push($parent['children'],$value['value']); } array_push($this->_valStack, $parent); $this->_depth--; } /** * Handler for character data * * @access private * @param object XML parser object * @param string CDATA * @return void */ function cdataHandler($parser, $cdata) { $this->_dataStack[$this->_depth] .= $cdata; } }PKu]PEAR/Config.phpnu[ * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 0.1 */ /** * Required for error handling */ require_once 'PEAR.php'; require_once 'PEAR/Registry.php'; require_once 'PEAR/Installer/Role.php'; require_once 'System.php'; /** * Last created PEAR_Config instance. * @var object */ $GLOBALS['_PEAR_Config_instance'] = null; if (!defined('PEAR_INSTALL_DIR') || !PEAR_INSTALL_DIR) { $PEAR_INSTALL_DIR = PHP_LIBDIR . DIRECTORY_SEPARATOR . 'pear'; } else { $PEAR_INSTALL_DIR = PEAR_INSTALL_DIR; } // Below we define constants with default values for all configuration // parameters except username/password. All of them can have their // defaults set through environment variables. The reason we use the // PHP_ prefix is for some security, PHP protects environment // variables starting with PHP_*. // default channel and preferred mirror is based on whether we are invoked through // the "pear" or the "pecl" command if (!defined('PEAR_RUNTYPE')) { define('PEAR_RUNTYPE', 'pear'); } if (PEAR_RUNTYPE == 'pear') { define('PEAR_CONFIG_DEFAULT_CHANNEL', 'pear.php.net'); } else { define('PEAR_CONFIG_DEFAULT_CHANNEL', 'pecl.php.net'); } if (getenv('PHP_PEAR_SYSCONF_DIR')) { define('PEAR_CONFIG_SYSCONFDIR', getenv('PHP_PEAR_SYSCONF_DIR')); } elseif (getenv('SystemRoot')) { define('PEAR_CONFIG_SYSCONFDIR', getenv('SystemRoot')); } else { define('PEAR_CONFIG_SYSCONFDIR', PHP_SYSCONFDIR); } // Default for master_server if (getenv('PHP_PEAR_MASTER_SERVER')) { define('PEAR_CONFIG_DEFAULT_MASTER_SERVER', getenv('PHP_PEAR_MASTER_SERVER')); } else { define('PEAR_CONFIG_DEFAULT_MASTER_SERVER', 'pear.php.net'); } // Default for http_proxy if (getenv('PHP_PEAR_HTTP_PROXY')) { define('PEAR_CONFIG_DEFAULT_HTTP_PROXY', getenv('PHP_PEAR_HTTP_PROXY')); } elseif (getenv('http_proxy')) { define('PEAR_CONFIG_DEFAULT_HTTP_PROXY', getenv('http_proxy')); } else { define('PEAR_CONFIG_DEFAULT_HTTP_PROXY', ''); } // Default for php_dir if (getenv('PHP_PEAR_INSTALL_DIR')) { define('PEAR_CONFIG_DEFAULT_PHP_DIR', getenv('PHP_PEAR_INSTALL_DIR')); } else { define('PEAR_CONFIG_DEFAULT_PHP_DIR', $PEAR_INSTALL_DIR); } // Default for metadata_dir if (getenv('PHP_PEAR_METADATA_DIR')) { define('PEAR_CONFIG_DEFAULT_METADATA_DIR', getenv('PHP_PEAR_METADATA_DIR')); } else { define('PEAR_CONFIG_DEFAULT_METADATA_DIR', ''); } // Default for ext_dir if (getenv('PHP_PEAR_EXTENSION_DIR')) { define('PEAR_CONFIG_DEFAULT_EXT_DIR', getenv('PHP_PEAR_EXTENSION_DIR')); } else { if (ini_get('extension_dir')) { define('PEAR_CONFIG_DEFAULT_EXT_DIR', ini_get('extension_dir')); } elseif (defined('PEAR_EXTENSION_DIR') && file_exists(PEAR_EXTENSION_DIR) && is_dir(PEAR_EXTENSION_DIR)) { define('PEAR_CONFIG_DEFAULT_EXT_DIR', PEAR_EXTENSION_DIR); } elseif (defined('PHP_EXTENSION_DIR')) { define('PEAR_CONFIG_DEFAULT_EXT_DIR', PHP_EXTENSION_DIR); } else { define('PEAR_CONFIG_DEFAULT_EXT_DIR', '.'); } } // Default for doc_dir if (getenv('PHP_PEAR_DOC_DIR')) { define('PEAR_CONFIG_DEFAULT_DOC_DIR', getenv('PHP_PEAR_DOC_DIR')); } else { define('PEAR_CONFIG_DEFAULT_DOC_DIR', $PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'docs'); } // Default for bin_dir if (getenv('PHP_PEAR_BIN_DIR')) { define('PEAR_CONFIG_DEFAULT_BIN_DIR', getenv('PHP_PEAR_BIN_DIR')); } else { define('PEAR_CONFIG_DEFAULT_BIN_DIR', PHP_BINDIR); } // Default for data_dir if (getenv('PHP_PEAR_DATA_DIR')) { define('PEAR_CONFIG_DEFAULT_DATA_DIR', getenv('PHP_PEAR_DATA_DIR')); } else { define('PEAR_CONFIG_DEFAULT_DATA_DIR', $PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'data'); } // Default for cfg_dir if (getenv('PHP_PEAR_CFG_DIR')) { define('PEAR_CONFIG_DEFAULT_CFG_DIR', getenv('PHP_PEAR_CFG_DIR')); } else { define('PEAR_CONFIG_DEFAULT_CFG_DIR', $PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'cfg'); } // Default for www_dir if (getenv('PHP_PEAR_WWW_DIR')) { define('PEAR_CONFIG_DEFAULT_WWW_DIR', getenv('PHP_PEAR_WWW_DIR')); } else { define('PEAR_CONFIG_DEFAULT_WWW_DIR', $PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'www'); } // Default for man_dir if (getenv('PHP_PEAR_MAN_DIR')) { define('PEAR_CONFIG_DEFAULT_MAN_DIR', getenv('PHP_PEAR_MAN_DIR')); } else { if (defined('PHP_MANDIR')) { // Added in PHP5.3.7 define('PEAR_CONFIG_DEFAULT_MAN_DIR', PHP_MANDIR); } else { define('PEAR_CONFIG_DEFAULT_MAN_DIR', PHP_PREFIX . DIRECTORY_SEPARATOR . 'local' . DIRECTORY_SEPARATOR .'man'); } } // Default for test_dir if (getenv('PHP_PEAR_TEST_DIR')) { define('PEAR_CONFIG_DEFAULT_TEST_DIR', getenv('PHP_PEAR_TEST_DIR')); } else { define('PEAR_CONFIG_DEFAULT_TEST_DIR', $PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'tests'); } // Default for temp_dir if (getenv('PHP_PEAR_TEMP_DIR')) { define('PEAR_CONFIG_DEFAULT_TEMP_DIR', getenv('PHP_PEAR_TEMP_DIR')); } else { define('PEAR_CONFIG_DEFAULT_TEMP_DIR', System::tmpdir() . DIRECTORY_SEPARATOR . 'pear' . DIRECTORY_SEPARATOR . 'temp'); } // Default for cache_dir if (getenv('PHP_PEAR_CACHE_DIR')) { define('PEAR_CONFIG_DEFAULT_CACHE_DIR', getenv('PHP_PEAR_CACHE_DIR')); } else { define('PEAR_CONFIG_DEFAULT_CACHE_DIR', System::tmpdir() . DIRECTORY_SEPARATOR . 'pear' . DIRECTORY_SEPARATOR . 'cache'); } // Default for download_dir if (getenv('PHP_PEAR_DOWNLOAD_DIR')) { define('PEAR_CONFIG_DEFAULT_DOWNLOAD_DIR', getenv('PHP_PEAR_DOWNLOAD_DIR')); } else { define('PEAR_CONFIG_DEFAULT_DOWNLOAD_DIR', System::tmpdir() . DIRECTORY_SEPARATOR . 'pear' . DIRECTORY_SEPARATOR . 'download'); } // Default for php_bin if (getenv('PHP_PEAR_PHP_BIN')) { define('PEAR_CONFIG_DEFAULT_PHP_BIN', getenv('PHP_PEAR_PHP_BIN')); } else { define('PEAR_CONFIG_DEFAULT_PHP_BIN', PEAR_CONFIG_DEFAULT_BIN_DIR. DIRECTORY_SEPARATOR.'php'.(OS_WINDOWS ? '.exe' : '')); } // Default for verbose if (getenv('PHP_PEAR_VERBOSE')) { define('PEAR_CONFIG_DEFAULT_VERBOSE', getenv('PHP_PEAR_VERBOSE')); } else { define('PEAR_CONFIG_DEFAULT_VERBOSE', 1); } // Default for preferred_state if (getenv('PHP_PEAR_PREFERRED_STATE')) { define('PEAR_CONFIG_DEFAULT_PREFERRED_STATE', getenv('PHP_PEAR_PREFERRED_STATE')); } else { define('PEAR_CONFIG_DEFAULT_PREFERRED_STATE', 'stable'); } // Default for umask if (getenv('PHP_PEAR_UMASK')) { define('PEAR_CONFIG_DEFAULT_UMASK', getenv('PHP_PEAR_UMASK')); } else { define('PEAR_CONFIG_DEFAULT_UMASK', decoct(umask())); } // Default for cache_ttl if (getenv('PHP_PEAR_CACHE_TTL')) { define('PEAR_CONFIG_DEFAULT_CACHE_TTL', getenv('PHP_PEAR_CACHE_TTL')); } else { define('PEAR_CONFIG_DEFAULT_CACHE_TTL', 3600); } // Default for sig_type if (getenv('PHP_PEAR_SIG_TYPE')) { define('PEAR_CONFIG_DEFAULT_SIG_TYPE', getenv('PHP_PEAR_SIG_TYPE')); } else { define('PEAR_CONFIG_DEFAULT_SIG_TYPE', 'gpg'); } // Default for sig_bin if (getenv('PHP_PEAR_SIG_BIN')) { define('PEAR_CONFIG_DEFAULT_SIG_BIN', getenv('PHP_PEAR_SIG_BIN')); } else { define('PEAR_CONFIG_DEFAULT_SIG_BIN', System::which( 'gpg', OS_WINDOWS ? 'c:\gnupg\gpg.exe' : '/usr/local/bin/gpg')); } // Default for sig_keydir if (getenv('PHP_PEAR_SIG_KEYDIR')) { define('PEAR_CONFIG_DEFAULT_SIG_KEYDIR', getenv('PHP_PEAR_SIG_KEYDIR')); } else { define('PEAR_CONFIG_DEFAULT_SIG_KEYDIR', PEAR_CONFIG_SYSCONFDIR . DIRECTORY_SEPARATOR . 'pearkeys'); } /** * This is a class for storing configuration data, keeping track of * which are system-defined, user-defined or defaulted. * @category pear * @package PEAR * @author Stig Bakken * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 0.1 */ class PEAR_Config extends PEAR { /** * Array of config files used. * * @var array layer => config file */ var $files = array( 'system' => '', 'user' => '', ); var $layers = array(); /** * Configuration data, two-dimensional array where the first * dimension is the config layer ('user', 'system' and 'default'), * and the second dimension is keyname => value. * * The order in the first dimension is important! Earlier * layers will shadow later ones when a config value is * requested (if a 'user' value exists, it will be returned first, * then 'system' and finally 'default'). * * @var array layer => array(keyname => value, ...) */ var $configuration = array( 'user' => array(), 'system' => array(), 'default' => array(), ); /** * Configuration values that can be set for a channel * * All other configuration values can only have a global value * @var array * @access private */ var $_channelConfigInfo = array( 'php_dir', 'ext_dir', 'doc_dir', 'bin_dir', 'data_dir', 'cfg_dir', 'test_dir', 'www_dir', 'php_bin', 'php_prefix', 'php_suffix', 'username', 'password', 'verbose', 'preferred_state', 'umask', 'preferred_mirror', 'php_ini' ); /** * Channels that can be accessed * @see setChannels() * @var array * @access private */ var $_channels = array('pear.php.net', 'pecl.php.net', '__uri'); /** * This variable is used to control the directory values returned * @see setInstallRoot(); * @var string|false * @access private */ var $_installRoot = false; /** * If requested, this will always refer to the registry * contained in php_dir * @var PEAR_Registry */ var $_registry = array(); /** * @var array * @access private */ var $_regInitialized = array(); /** * @var bool * @access private */ var $_noRegistry = false; /** * amount of errors found while parsing config * @var integer * @access private */ var $_errorsFound = 0; var $_lastError = null; /** * Information about the configuration data. Stores the type, * default value and a documentation string for each configuration * value. * * @var array layer => array(infotype => value, ...) */ var $configuration_info = array( // Channels/Internet Access 'default_channel' => array( 'type' => 'string', 'default' => PEAR_CONFIG_DEFAULT_CHANNEL, 'doc' => 'the default channel to use for all non explicit commands', 'prompt' => 'Default Channel', 'group' => 'Internet Access', ), 'preferred_mirror' => array( 'type' => 'string', 'default' => PEAR_CONFIG_DEFAULT_CHANNEL, 'doc' => 'the default server or mirror to use for channel actions', 'prompt' => 'Default Channel Mirror', 'group' => 'Internet Access', ), 'remote_config' => array( 'type' => 'password', 'default' => '', 'doc' => 'ftp url of remote configuration file to use for synchronized install', 'prompt' => 'Remote Configuration File', 'group' => 'Internet Access', ), 'auto_discover' => array( 'type' => 'integer', 'default' => 0, 'doc' => 'whether to automatically discover new channels', 'prompt' => 'Auto-discover new Channels', 'group' => 'Internet Access', ), // Internet Access 'master_server' => array( 'type' => 'string', 'default' => 'pear.php.net', 'doc' => 'name of the main PEAR server [NOT USED IN THIS VERSION]', 'prompt' => 'PEAR server [DEPRECATED]', 'group' => 'Internet Access', ), 'http_proxy' => array( 'type' => 'string', 'default' => PEAR_CONFIG_DEFAULT_HTTP_PROXY, 'doc' => 'HTTP proxy (host:port) to use when downloading packages', 'prompt' => 'HTTP Proxy Server Address', 'group' => 'Internet Access', ), // File Locations 'php_dir' => array( 'type' => 'directory', 'default' => PEAR_CONFIG_DEFAULT_PHP_DIR, 'doc' => 'directory where .php files are installed', 'prompt' => 'PEAR directory', 'group' => 'File Locations', ), 'ext_dir' => array( 'type' => 'directory', 'default' => PEAR_CONFIG_DEFAULT_EXT_DIR, 'doc' => 'directory where loadable extensions are installed', 'prompt' => 'PHP extension directory', 'group' => 'File Locations', ), 'doc_dir' => array( 'type' => 'directory', 'default' => PEAR_CONFIG_DEFAULT_DOC_DIR, 'doc' => 'directory where documentation is installed', 'prompt' => 'PEAR documentation directory', 'group' => 'File Locations', ), 'bin_dir' => array( 'type' => 'directory', 'default' => PEAR_CONFIG_DEFAULT_BIN_DIR, 'doc' => 'directory where executables are installed', 'prompt' => 'PEAR executables directory', 'group' => 'File Locations', ), 'data_dir' => array( 'type' => 'directory', 'default' => PEAR_CONFIG_DEFAULT_DATA_DIR, 'doc' => 'directory where data files are installed', 'prompt' => 'PEAR data directory', 'group' => 'File Locations (Advanced)', ), 'cfg_dir' => array( 'type' => 'directory', 'default' => PEAR_CONFIG_DEFAULT_CFG_DIR, 'doc' => 'directory where modifiable configuration files are installed', 'prompt' => 'PEAR configuration file directory', 'group' => 'File Locations (Advanced)', ), 'www_dir' => array( 'type' => 'directory', 'default' => PEAR_CONFIG_DEFAULT_WWW_DIR, 'doc' => 'directory where www frontend files (html/js) are installed', 'prompt' => 'PEAR www files directory', 'group' => 'File Locations (Advanced)', ), 'man_dir' => array( 'type' => 'directory', 'default' => PEAR_CONFIG_DEFAULT_MAN_DIR, 'doc' => 'directory where unix manual pages are installed', 'prompt' => 'Systems manpage files directory', 'group' => 'File Locations (Advanced)', ), 'test_dir' => array( 'type' => 'directory', 'default' => PEAR_CONFIG_DEFAULT_TEST_DIR, 'doc' => 'directory where regression tests are installed', 'prompt' => 'PEAR test directory', 'group' => 'File Locations (Advanced)', ), 'cache_dir' => array( 'type' => 'directory', 'default' => PEAR_CONFIG_DEFAULT_CACHE_DIR, 'doc' => 'directory which is used for web service cache', 'prompt' => 'PEAR Installer cache directory', 'group' => 'File Locations (Advanced)', ), 'temp_dir' => array( 'type' => 'directory', 'default' => PEAR_CONFIG_DEFAULT_TEMP_DIR, 'doc' => 'directory which is used for all temp files', 'prompt' => 'PEAR Installer temp directory', 'group' => 'File Locations (Advanced)', ), 'download_dir' => array( 'type' => 'directory', 'default' => PEAR_CONFIG_DEFAULT_DOWNLOAD_DIR, 'doc' => 'directory which is used for all downloaded files', 'prompt' => 'PEAR Installer download directory', 'group' => 'File Locations (Advanced)', ), 'php_bin' => array( 'type' => 'file', 'default' => PEAR_CONFIG_DEFAULT_PHP_BIN, 'doc' => 'PHP CLI/CGI binary for executing scripts', 'prompt' => 'PHP CLI/CGI binary', 'group' => 'File Locations (Advanced)', ), 'php_prefix' => array( 'type' => 'string', 'default' => '', 'doc' => '--program-prefix for php_bin\'s ./configure, used for pecl installs', 'prompt' => '--program-prefix passed to PHP\'s ./configure', 'group' => 'File Locations (Advanced)', ), 'php_suffix' => array( 'type' => 'string', 'default' => '', 'doc' => '--program-suffix for php_bin\'s ./configure, used for pecl installs', 'prompt' => '--program-suffix passed to PHP\'s ./configure', 'group' => 'File Locations (Advanced)', ), 'php_ini' => array( 'type' => 'file', 'default' => '', 'doc' => 'location of php.ini in which to enable PECL extensions on install', 'prompt' => 'php.ini location', 'group' => 'File Locations (Advanced)', ), 'metadata_dir' => array( 'type' => 'directory', 'default' => PEAR_CONFIG_DEFAULT_METADATA_DIR, 'doc' => 'directory where metadata files are installed (registry, filemap, channels, ...)', 'prompt' => 'PEAR metadata directory', 'group' => 'File Locations (Advanced)', ), // Maintainers 'username' => array( 'type' => 'string', 'default' => '', 'doc' => '(maintainers) your PEAR account name', 'prompt' => 'PEAR username (for maintainers)', 'group' => 'Maintainers', ), 'password' => array( 'type' => 'password', 'default' => '', 'doc' => '(maintainers) your PEAR account password', 'prompt' => 'PEAR password (for maintainers)', 'group' => 'Maintainers', ), // Advanced 'verbose' => array( 'type' => 'integer', 'default' => PEAR_CONFIG_DEFAULT_VERBOSE, 'doc' => 'verbosity level 0: really quiet 1: somewhat quiet 2: verbose 3: debug', 'prompt' => 'Debug Log Level', 'group' => 'Advanced', ), 'preferred_state' => array( 'type' => 'set', 'default' => PEAR_CONFIG_DEFAULT_PREFERRED_STATE, 'doc' => 'the installer will prefer releases with this state when installing packages without a version or state specified', 'valid_set' => array( 'stable', 'beta', 'alpha', 'devel', 'snapshot'), 'prompt' => 'Preferred Package State', 'group' => 'Advanced', ), 'umask' => array( 'type' => 'mask', 'default' => PEAR_CONFIG_DEFAULT_UMASK, 'doc' => 'umask used when creating files (Unix-like systems only)', 'prompt' => 'Unix file mask', 'group' => 'Advanced', ), 'cache_ttl' => array( 'type' => 'integer', 'default' => PEAR_CONFIG_DEFAULT_CACHE_TTL, 'doc' => 'amount of secs where the local cache is used and not updated', 'prompt' => 'Cache TimeToLive', 'group' => 'Advanced', ), 'sig_type' => array( 'type' => 'set', 'default' => PEAR_CONFIG_DEFAULT_SIG_TYPE, 'doc' => 'which package signature mechanism to use', 'valid_set' => array('gpg'), 'prompt' => 'Package Signature Type', 'group' => 'Maintainers', ), 'sig_bin' => array( 'type' => 'string', 'default' => PEAR_CONFIG_DEFAULT_SIG_BIN, 'doc' => 'which package signature mechanism to use', 'prompt' => 'Signature Handling Program', 'group' => 'Maintainers', ), 'sig_keyid' => array( 'type' => 'string', 'default' => '', 'doc' => 'which key to use for signing with', 'prompt' => 'Signature Key Id', 'group' => 'Maintainers', ), 'sig_keydir' => array( 'type' => 'directory', 'default' => PEAR_CONFIG_DEFAULT_SIG_KEYDIR, 'doc' => 'directory where signature keys are located', 'prompt' => 'Signature Key Directory', 'group' => 'Maintainers', ), // __channels is reserved - used for channel-specific configuration ); /** * Constructor. * * @param string file to read user-defined options from * @param string file to read system-wide defaults from * @param bool determines whether a registry object "follows" * the value of php_dir (is automatically created * and moved when php_dir is changed) * @param bool if true, fails if configuration files cannot be loaded * * @access public * * @see PEAR_Config::singleton */ function __construct($user_file = '', $system_file = '', $ftp_file = false, $strict = true) { parent::__construct(); PEAR_Installer_Role::initializeConfig($this); $sl = DIRECTORY_SEPARATOR; if (empty($user_file)) { if (OS_WINDOWS) { $user_file = PEAR_CONFIG_SYSCONFDIR . $sl . 'pear.ini'; } else { $user_file = getenv('HOME') . $sl . '.pearrc'; } } if (empty($system_file)) { $system_file = PEAR_CONFIG_SYSCONFDIR . $sl; if (OS_WINDOWS) { $system_file .= 'pearsys.ini'; } else { $system_file .= 'pear.conf'; } } $this->layers = array_keys($this->configuration); $this->files['user'] = $user_file; $this->files['system'] = $system_file; if ($user_file && file_exists($user_file)) { $this->pushErrorHandling(PEAR_ERROR_RETURN); $this->readConfigFile($user_file, 'user', $strict); $this->popErrorHandling(); if ($this->_errorsFound > 0) { return; } } if ($system_file && @file_exists($system_file)) { $this->mergeConfigFile($system_file, false, 'system', $strict); if ($this->_errorsFound > 0) { return; } } if (!$ftp_file) { $ftp_file = $this->get('remote_config'); } if ($ftp_file && defined('PEAR_REMOTEINSTALL_OK')) { $this->readFTPConfigFile($ftp_file); } foreach ($this->configuration_info as $key => $info) { $this->configuration['default'][$key] = $info['default']; } $this->_registry['default'] = new PEAR_Registry( $this->configuration['default']['php_dir'], false, false, $this->configuration['default']['metadata_dir']); $this->_registry['default']->setConfig($this, false); $this->_regInitialized['default'] = false; //$GLOBALS['_PEAR_Config_instance'] = &$this; } /** * Return the default locations of user and system configuration files */ public static function getDefaultConfigFiles() { $sl = DIRECTORY_SEPARATOR; if (OS_WINDOWS) { return array( 'user' => PEAR_CONFIG_SYSCONFDIR . $sl . 'pear.ini', 'system' => PEAR_CONFIG_SYSCONFDIR . $sl . 'pearsys.ini' ); } return array( 'user' => getenv('HOME') . $sl . '.pearrc', 'system' => PEAR_CONFIG_SYSCONFDIR . $sl . 'pear.conf' ); } /** * Static singleton method. If you want to keep only one instance * of this class in use, this method will give you a reference to * the last created PEAR_Config object if one exists, or create a * new object. * * @param string (optional) file to read user-defined options from * @param string (optional) file to read system-wide defaults from * * @return object an existing or new PEAR_Config instance * * @see PEAR_Config::PEAR_Config */ public static function &singleton($user_file = '', $system_file = '', $strict = true) { if (is_object($GLOBALS['_PEAR_Config_instance'])) { return $GLOBALS['_PEAR_Config_instance']; } $t_conf = new PEAR_Config($user_file, $system_file, false, $strict); if ($t_conf->_errorsFound > 0) { return $t_conf->_lastError; } $GLOBALS['_PEAR_Config_instance'] = &$t_conf; return $GLOBALS['_PEAR_Config_instance']; } /** * Determine whether any configuration files have been detected, and whether a * registry object can be retrieved from this configuration. * @return bool * @since PEAR 1.4.0a1 */ function validConfiguration() { if ($this->isDefinedLayer('user') || $this->isDefinedLayer('system')) { return true; } return false; } /** * Reads configuration data from a file. All existing values in * the config layer are discarded and replaced with data from the * file. * @param string file to read from, if NULL or not specified, the * last-used file for the same layer (second param) is used * @param string config layer to insert data into ('user' or 'system') * @return bool TRUE on success or a PEAR error on failure */ function readConfigFile($file = null, $layer = 'user', $strict = true) { if (empty($this->files[$layer])) { return $this->raiseError("unknown config layer `$layer'"); } if ($file === null) { $file = $this->files[$layer]; } $data = $this->_readConfigDataFrom($file); if (PEAR::isError($data)) { if (!$strict) { return true; } $this->_errorsFound++; $this->_lastError = $data; return $data; } $this->files[$layer] = $file; $this->_decodeInput($data); $this->configuration[$layer] = $data; $this->_setupChannels(); if (!$this->_noRegistry && ($phpdir = $this->get('php_dir', $layer, 'pear.php.net'))) { $this->_registry[$layer] = new PEAR_Registry( $phpdir, false, false, $this->get('metadata_dir', $layer, 'pear.php.net')); $this->_registry[$layer]->setConfig($this, false); $this->_regInitialized[$layer] = false; } else { unset($this->_registry[$layer]); } return true; } /** * @param string url to the remote config file, like ftp://www.example.com/pear/config.ini * @return true|PEAR_Error */ function readFTPConfigFile($path) { do { // poor man's try if (!class_exists('PEAR_FTP')) { if (!class_exists('PEAR_Common')) { require_once 'PEAR/Common.php'; } if (PEAR_Common::isIncludeable('PEAR/FTP.php')) { require_once 'PEAR/FTP.php'; } } if (!class_exists('PEAR_FTP')) { return PEAR::raiseError('PEAR_RemoteInstaller must be installed to use remote config'); } $this->_ftp = new PEAR_FTP; $this->_ftp->pushErrorHandling(PEAR_ERROR_RETURN); $e = $this->_ftp->init($path); if (PEAR::isError($e)) { $this->_ftp->popErrorHandling(); return $e; } $tmp = System::mktemp('-d'); PEAR_Common::addTempFile($tmp); $e = $this->_ftp->get(basename($path), $tmp . DIRECTORY_SEPARATOR . 'pear.ini', false, FTP_BINARY); if (PEAR::isError($e)) { $this->_ftp->popErrorHandling(); return $e; } PEAR_Common::addTempFile($tmp . DIRECTORY_SEPARATOR . 'pear.ini'); $this->_ftp->disconnect(); $this->_ftp->popErrorHandling(); $this->files['ftp'] = $tmp . DIRECTORY_SEPARATOR . 'pear.ini'; $e = $this->readConfigFile(null, 'ftp'); if (PEAR::isError($e)) { return $e; } $fail = array(); foreach ($this->configuration_info as $key => $val) { if (in_array($this->getGroup($key), array('File Locations', 'File Locations (Advanced)')) && $this->getType($key) == 'directory') { // any directory configs must be set for this to work if (!isset($this->configuration['ftp'][$key])) { $fail[] = $key; } } } if (!count($fail)) { return true; } $fail = '"' . implode('", "', $fail) . '"'; unset($this->files['ftp']); unset($this->configuration['ftp']); return PEAR::raiseError('ERROR: Ftp configuration file must set all ' . 'directory configuration variables. These variables were not set: ' . $fail); } while (false); // poor man's catch unset($this->files['ftp']); return PEAR::raiseError('no remote host specified'); } /** * Reads the existing configurations and creates the _channels array from it */ function _setupChannels() { $set = array_flip(array_values($this->_channels)); foreach ($this->configuration as $layer => $data) { $i = 1000; if (isset($data['__channels']) && is_array($data['__channels'])) { foreach ($data['__channels'] as $channel => $info) { $set[$channel] = $i++; } } } $this->_channels = array_values(array_flip($set)); $this->setChannels($this->_channels); } function deleteChannel($channel) { $ch = strtolower($channel); foreach ($this->configuration as $layer => $data) { if (isset($data['__channels']) && isset($data['__channels'][$ch])) { unset($this->configuration[$layer]['__channels'][$ch]); } } $this->_channels = array_flip($this->_channels); unset($this->_channels[$ch]); $this->_channels = array_flip($this->_channels); } /** * Merges data into a config layer from a file. Does the same * thing as readConfigFile, except it does not replace all * existing values in the config layer. * @param string file to read from * @param bool whether to overwrite existing data (default TRUE) * @param string config layer to insert data into ('user' or 'system') * @param string if true, errors are returned if file opening fails * @return bool TRUE on success or a PEAR error on failure */ function mergeConfigFile($file, $override = true, $layer = 'user', $strict = true) { if (empty($this->files[$layer])) { return $this->raiseError("unknown config layer `$layer'"); } if ($file === null) { $file = $this->files[$layer]; } $data = $this->_readConfigDataFrom($file); if (PEAR::isError($data)) { if (!$strict) { return true; } $this->_errorsFound++; $this->_lastError = $data; return $data; } $this->_decodeInput($data); if ($override) { $this->configuration[$layer] = PEAR_Config::arrayMergeRecursive($this->configuration[$layer], $data); } else { $this->configuration[$layer] = PEAR_Config::arrayMergeRecursive($data, $this->configuration[$layer]); } $this->_setupChannels(); if (!$this->_noRegistry && ($phpdir = $this->get('php_dir', $layer, 'pear.php.net'))) { $this->_registry[$layer] = new PEAR_Registry( $phpdir, false, false, $this->get('metadata_dir', $layer, 'pear.php.net')); $this->_registry[$layer]->setConfig($this, false); $this->_regInitialized[$layer] = false; } else { unset($this->_registry[$layer]); } return true; } /** * @param array * @param array * @return array */ public static function arrayMergeRecursive($arr2, $arr1) { $ret = array(); foreach ($arr2 as $key => $data) { if (!isset($arr1[$key])) { $ret[$key] = $data; unset($arr1[$key]); continue; } if (is_array($data)) { if (!is_array($arr1[$key])) { $ret[$key] = $arr1[$key]; unset($arr1[$key]); continue; } $ret[$key] = PEAR_Config::arrayMergeRecursive($arr1[$key], $arr2[$key]); unset($arr1[$key]); } } return array_merge($ret, $arr1); } /** * Writes data into a config layer from a file. * * @param string|null file to read from, or null for default * @param string config layer to insert data into ('user' or * 'system') * @param string|null data to write to config file or null for internal data [DEPRECATED] * @return bool TRUE on success or a PEAR error on failure */ function writeConfigFile($file = null, $layer = 'user', $data = null) { $this->_lazyChannelSetup($layer); if ($layer == 'both' || $layer == 'all') { foreach ($this->files as $type => $file) { $err = $this->writeConfigFile($file, $type, $data); if (PEAR::isError($err)) { return $err; } } return true; } if (empty($this->files[$layer])) { return $this->raiseError("unknown config file type `$layer'"); } if ($file === null) { $file = $this->files[$layer]; } $data = ($data === null) ? $this->configuration[$layer] : $data; $this->_encodeOutput($data); $opt = array('-p', dirname($file)); if (!@System::mkDir($opt)) { return $this->raiseError("could not create directory: " . dirname($file)); } if (file_exists($file) && is_file($file) && !is_writeable($file)) { return $this->raiseError("no write access to $file!"); } $fp = @fopen($file, "w"); if (!$fp) { return $this->raiseError("PEAR_Config::writeConfigFile fopen('$file','w') failed ($php_errormsg)"); } $contents = "#PEAR_Config 0.9\n" . serialize($data); if (!@fwrite($fp, $contents)) { return $this->raiseError("PEAR_Config::writeConfigFile: fwrite failed ($php_errormsg)"); } return true; } /** * Reads configuration data from a file and returns the parsed data * in an array. * * @param string file to read from * @return array configuration data or a PEAR error on failure * @access private */ function _readConfigDataFrom($file) { $fp = false; if (file_exists($file)) { $fp = @fopen($file, "r"); } if (!$fp) { return $this->raiseError("PEAR_Config::readConfigFile fopen('$file','r') failed"); } $size = filesize($file); fclose($fp); $contents = file_get_contents($file); if (empty($contents)) { return $this->raiseError('Configuration file "' . $file . '" is empty'); } $version = false; if (preg_match('/^#PEAR_Config\s+(\S+)\s+/si', $contents, $matches)) { $version = $matches[1]; $contents = substr($contents, strlen($matches[0])); } else { // Museum config file if (substr($contents,0,2) == 'a:') { $version = '0.1'; } } if ($version && version_compare("$version", '1', '<')) { $data = @unserialize($contents); if (!is_array($data) && !$data) { if ($contents == serialize(false)) { $data = array(); } else { $err = $this->raiseError("PEAR_Config: bad data in $file"); return $err; } } if (!is_array($data)) { if (strlen(trim($contents)) > 0) { $error = "PEAR_Config: bad data in $file"; $err = $this->raiseError($error); return $err; } $data = array(); } // add parsing of newer formats here... } else { $err = $this->raiseError("$file: unknown version `$version'"); return $err; } return $data; } /** * Gets the file used for storing the config for a layer * * @param string $layer 'user' or 'system' */ function getConfFile($layer) { return $this->files[$layer]; } /** * @param string Configuration class name, used for detecting duplicate calls * @param array information on a role as parsed from its xml file * @return true|PEAR_Error * @access private */ function _addConfigVars($class, $vars) { static $called = array(); if (isset($called[$class])) { return; } $called[$class] = 1; if (count($vars) > 3) { return $this->raiseError('Roles can only define 3 new config variables or less'); } foreach ($vars as $name => $var) { if (!is_array($var)) { return $this->raiseError('Configuration information must be an array'); } if (!isset($var['type'])) { return $this->raiseError('Configuration information must contain a type'); } elseif (!in_array($var['type'], array('string', 'mask', 'password', 'directory', 'file', 'set'))) { return $this->raiseError( 'Configuration type must be one of directory, file, string, ' . 'mask, set, or password'); } if (!isset($var['default'])) { return $this->raiseError( 'Configuration information must contain a default value ("default" index)'); } if (is_array($var['default'])) { $real_default = ''; foreach ($var['default'] as $config_var => $val) { if (strpos($config_var, 'text') === 0) { $real_default .= $val; } elseif (strpos($config_var, 'constant') === 0) { if (!defined($val)) { return $this->raiseError( 'Unknown constant "' . $val . '" requested in ' . 'default value for configuration variable "' . $name . '"'); } $real_default .= constant($val); } elseif (isset($this->configuration_info[$config_var])) { $real_default .= $this->configuration_info[$config_var]['default']; } else { return $this->raiseError( 'Unknown request for "' . $config_var . '" value in ' . 'default value for configuration variable "' . $name . '"'); } } $var['default'] = $real_default; } if ($var['type'] == 'integer') { $var['default'] = (integer) $var['default']; } if (!isset($var['doc'])) { return $this->raiseError( 'Configuration information must contain a summary ("doc" index)'); } if (!isset($var['prompt'])) { return $this->raiseError( 'Configuration information must contain a simple prompt ("prompt" index)'); } if (!isset($var['group'])) { return $this->raiseError( 'Configuration information must contain a simple group ("group" index)'); } if (isset($this->configuration_info[$name])) { return $this->raiseError('Configuration variable "' . $name . '" already exists'); } $this->configuration_info[$name] = $var; // fix bug #7351: setting custom config variable in a channel fails $this->_channelConfigInfo[] = $name; } return true; } /** * Encodes/scrambles configuration data before writing to files. * Currently, 'password' values will be base64-encoded as to avoid * that people spot cleartext passwords by accident. * * @param array (reference) array to encode values in * @return bool TRUE on success * @access private */ function _encodeOutput(&$data) { foreach ($data as $key => $value) { if ($key == '__channels') { foreach ($data['__channels'] as $channel => $blah) { $this->_encodeOutput($data['__channels'][$channel]); } } if (!isset($this->configuration_info[$key])) { continue; } $type = $this->configuration_info[$key]['type']; switch ($type) { // we base64-encode passwords so they are at least // not shown in plain by accident case 'password': { $data[$key] = base64_encode($data[$key]); break; } case 'mask': { $data[$key] = octdec($data[$key]); break; } } } return true; } /** * Decodes/unscrambles configuration data after reading from files. * * @param array (reference) array to encode values in * @return bool TRUE on success * @access private * * @see PEAR_Config::_encodeOutput */ function _decodeInput(&$data) { if (!is_array($data)) { return true; } foreach ($data as $key => $value) { if ($key == '__channels') { foreach ($data['__channels'] as $channel => $blah) { $this->_decodeInput($data['__channels'][$channel]); } } if (!isset($this->configuration_info[$key])) { continue; } $type = $this->configuration_info[$key]['type']; switch ($type) { case 'password': { $data[$key] = base64_decode($data[$key]); break; } case 'mask': { $data[$key] = decoct($data[$key]); break; } } } return true; } /** * Retrieve the default channel. * * On startup, channels are not initialized, so if the default channel is not * pear.php.net, then initialize the config. * @param string registry layer * @return string|false */ function getDefaultChannel($layer = null) { $ret = false; if ($layer === null) { foreach ($this->layers as $layer) { if (isset($this->configuration[$layer]['default_channel'])) { $ret = $this->configuration[$layer]['default_channel']; break; } } } elseif (isset($this->configuration[$layer]['default_channel'])) { $ret = $this->configuration[$layer]['default_channel']; } if ($ret == 'pear.php.net' && defined('PEAR_RUNTYPE') && PEAR_RUNTYPE == 'pecl') { $ret = 'pecl.php.net'; } if ($ret) { if ($ret != 'pear.php.net') { $this->_lazyChannelSetup(); } return $ret; } return PEAR_CONFIG_DEFAULT_CHANNEL; } /** * Returns a configuration value, prioritizing layers as per the * layers property. * * @param string config key * @return mixed the config value, or NULL if not found * @access public */ function get($key, $layer = null, $channel = false) { if (!isset($this->configuration_info[$key])) { return null; } if ($key == '__channels') { return null; } if ($key == 'default_channel') { return $this->getDefaultChannel($layer); } if (!$channel) { $channel = $this->getDefaultChannel(); } elseif ($channel != 'pear.php.net') { $this->_lazyChannelSetup(); } $channel = strtolower($channel); $test = (in_array($key, $this->_channelConfigInfo)) ? $this->_getChannelValue($key, $layer, $channel) : null; if ($test !== null) { if ($this->_installRoot) { if (in_array($this->getGroup($key), array('File Locations', 'File Locations (Advanced)')) && $this->getType($key) == 'directory') { return $this->_prependPath($test, $this->_installRoot); } } return $test; } if ($layer === null) { foreach ($this->layers as $layer) { if (isset($this->configuration[$layer][$key])) { $test = $this->configuration[$layer][$key]; if ($this->_installRoot) { if (in_array($this->getGroup($key), array('File Locations', 'File Locations (Advanced)')) && $this->getType($key) == 'directory') { return $this->_prependPath($test, $this->_installRoot); } } if ($key == 'preferred_mirror') { $reg = &$this->getRegistry(); if (is_object($reg)) { $chan = $reg->getChannel($channel); if (PEAR::isError($chan)) { return $channel; } if (!$chan->getMirror($test) && $chan->getName() != $test) { return $channel; // mirror does not exist } } } return $test; } } } elseif (isset($this->configuration[$layer][$key])) { $test = $this->configuration[$layer][$key]; if ($this->_installRoot) { if (in_array($this->getGroup($key), array('File Locations', 'File Locations (Advanced)')) && $this->getType($key) == 'directory') { return $this->_prependPath($test, $this->_installRoot); } } if ($key == 'preferred_mirror') { $reg = &$this->getRegistry(); if (is_object($reg)) { $chan = $reg->getChannel($channel); if (PEAR::isError($chan)) { return $channel; } if (!$chan->getMirror($test) && $chan->getName() != $test) { return $channel; // mirror does not exist } } } return $test; } return null; } /** * Returns a channel-specific configuration value, prioritizing layers as per the * layers property. * * @param string config key * @return mixed the config value, or NULL if not found * @access private */ function _getChannelValue($key, $layer, $channel) { if ($key == '__channels' || $channel == 'pear.php.net') { return null; } $ret = null; if ($layer === null) { foreach ($this->layers as $ilayer) { if (isset($this->configuration[$ilayer]['__channels'][$channel][$key])) { $ret = $this->configuration[$ilayer]['__channels'][$channel][$key]; break; } } } elseif (isset($this->configuration[$layer]['__channels'][$channel][$key])) { $ret = $this->configuration[$layer]['__channels'][$channel][$key]; } if ($key != 'preferred_mirror') { return $ret; } if ($ret !== null) { $reg = &$this->getRegistry($layer); if (is_object($reg)) { $chan = $reg->getChannel($channel); if (PEAR::isError($chan)) { return $channel; } if (!$chan->getMirror($ret) && $chan->getName() != $ret) { return $channel; // mirror does not exist } } return $ret; } if ($channel != $this->getDefaultChannel($layer)) { return $channel; // we must use the channel name as the preferred mirror // if the user has not chosen an alternate } return $this->getDefaultChannel($layer); } /** * Set a config value in a specific layer (defaults to 'user'). * Enforces the types defined in the configuration_info array. An * integer config variable will be cast to int, and a set config * variable will be validated against its legal values. * * @param string config key * @param string config value * @param string (optional) config layer * @param string channel to set this value for, or null for global value * @return bool TRUE on success, FALSE on failure */ function set($key, $value, $layer = 'user', $channel = false) { if ($key == '__channels') { return false; } if (!isset($this->configuration[$layer])) { return false; } if ($key == 'default_channel') { // can only set this value globally $channel = 'pear.php.net'; if ($value != 'pear.php.net') { $this->_lazyChannelSetup($layer); } } if ($key == 'preferred_mirror') { if ($channel == '__uri') { return false; // can't set the __uri pseudo-channel's mirror } $reg = &$this->getRegistry($layer); if (is_object($reg)) { $chan = $reg->getChannel($channel ? $channel : 'pear.php.net'); if (PEAR::isError($chan)) { return false; } if (!$chan->getMirror($value) && $chan->getName() != $value) { return false; // mirror does not exist } } } if (!isset($this->configuration_info[$key])) { return false; } extract($this->configuration_info[$key]); switch ($type) { case 'integer': $value = (int)$value; break; case 'set': { // If a valid_set is specified, require the value to // be in the set. If there is no valid_set, accept // any value. if ($valid_set) { reset($valid_set); if ((key($valid_set) === 0 && !in_array($value, $valid_set)) || (key($valid_set) !== 0 && empty($valid_set[$value]))) { return false; } } break; } } if (!$channel) { $channel = $this->get('default_channel', null, 'pear.php.net'); } if (!in_array($channel, $this->_channels)) { $this->_lazyChannelSetup($layer); $reg = &$this->getRegistry($layer); if ($reg) { $channel = $reg->channelName($channel); } if (!in_array($channel, $this->_channels)) { return false; } } if ($channel != 'pear.php.net') { if (in_array($key, $this->_channelConfigInfo)) { $this->configuration[$layer]['__channels'][$channel][$key] = $value; return true; } return false; } if ($key == 'default_channel') { if (!isset($reg)) { $reg = &$this->getRegistry($layer); if (!$reg) { $reg = &$this->getRegistry(); } } if ($reg) { $value = $reg->channelName($value); } if (!$value) { return false; } } $this->configuration[$layer][$key] = $value; if ($key == 'php_dir' && !$this->_noRegistry) { if (!isset($this->_registry[$layer]) || $value != $this->_registry[$layer]->install_dir) { $this->_registry[$layer] = new PEAR_Registry($value); $this->_regInitialized[$layer] = false; $this->_registry[$layer]->setConfig($this, false); } } return true; } function _lazyChannelSetup($uselayer = false) { if ($this->_noRegistry) { return; } $merge = false; foreach ($this->_registry as $layer => $p) { if ($uselayer && $uselayer != $layer) { continue; } if (!$this->_regInitialized[$layer]) { if ($layer == 'default' && isset($this->_registry['user']) || isset($this->_registry['system'])) { // only use the default registry if there are no alternatives continue; } if (!is_object($this->_registry[$layer])) { if ($phpdir = $this->get('php_dir', $layer, 'pear.php.net')) { $this->_registry[$layer] = new PEAR_Registry( $phpdir, false, false, $this->get('metadata_dir', $layer, 'pear.php.net')); $this->_registry[$layer]->setConfig($this, false); $this->_regInitialized[$layer] = false; } else { unset($this->_registry[$layer]); return; } } $this->setChannels($this->_registry[$layer]->listChannels(), $merge); $this->_regInitialized[$layer] = true; $merge = true; } } } /** * Set the list of channels. * * This should be set via a call to {@link PEAR_Registry::listChannels()} * @param array * @param bool * @return bool success of operation */ function setChannels($channels, $merge = false) { if (!is_array($channels)) { return false; } if ($merge) { $this->_channels = array_merge($this->_channels, $channels); } else { $this->_channels = $channels; } foreach ($channels as $channel) { $channel = strtolower($channel); if ($channel == 'pear.php.net') { continue; } foreach ($this->layers as $layer) { if (!isset($this->configuration[$layer]['__channels'])) { $this->configuration[$layer]['__channels'] = array(); } if (!isset($this->configuration[$layer]['__channels'][$channel]) || !is_array($this->configuration[$layer]['__channels'][$channel])) { $this->configuration[$layer]['__channels'][$channel] = array(); } } } return true; } /** * Get the type of a config value. * * @param string config key * * @return string type, one of "string", "integer", "file", * "directory", "set" or "password". * * @access public * */ function getType($key) { if (isset($this->configuration_info[$key])) { return $this->configuration_info[$key]['type']; } return false; } /** * Get the documentation for a config value. * * @param string config key * @return string documentation string * * @access public * */ function getDocs($key) { if (isset($this->configuration_info[$key])) { return $this->configuration_info[$key]['doc']; } return false; } /** * Get the short documentation for a config value. * * @param string config key * @return string short documentation string * * @access public * */ function getPrompt($key) { if (isset($this->configuration_info[$key])) { return $this->configuration_info[$key]['prompt']; } return false; } /** * Get the parameter group for a config key. * * @param string config key * @return string parameter group * * @access public * */ function getGroup($key) { if (isset($this->configuration_info[$key])) { return $this->configuration_info[$key]['group']; } return false; } /** * Get the list of parameter groups. * * @return array list of parameter groups * * @access public * */ function getGroups() { $tmp = array(); foreach ($this->configuration_info as $key => $info) { $tmp[$info['group']] = 1; } return array_keys($tmp); } /** * Get the list of the parameters in a group. * * @param string $group parameter group * @return array list of parameters in $group * * @access public * */ function getGroupKeys($group) { $keys = array(); foreach ($this->configuration_info as $key => $info) { if ($info['group'] == $group) { $keys[] = $key; } } return $keys; } /** * Get the list of allowed set values for a config value. Returns * NULL for config values that are not sets. * * @param string config key * @return array enumerated array of set values, or NULL if the * config key is unknown or not a set * * @access public * */ function getSetValues($key) { if (isset($this->configuration_info[$key]) && isset($this->configuration_info[$key]['type']) && $this->configuration_info[$key]['type'] == 'set') { $valid_set = $this->configuration_info[$key]['valid_set']; reset($valid_set); if (key($valid_set) === 0) { return $valid_set; } return array_keys($valid_set); } return null; } /** * Get all the current config keys. * * @return array simple array of config keys * * @access public */ function getKeys() { $keys = array(); foreach ($this->layers as $layer) { $test = $this->configuration[$layer]; if (isset($test['__channels'])) { foreach ($test['__channels'] as $channel => $configs) { $keys = array_merge($keys, $configs); } } unset($test['__channels']); $keys = array_merge($keys, $test); } return array_keys($keys); } /** * Remove the a config key from a specific config layer. * * @param string config key * @param string (optional) config layer * @param string (optional) channel (defaults to default channel) * @return bool TRUE on success, FALSE on failure * * @access public */ function remove($key, $layer = 'user', $channel = null) { if ($channel === null) { $channel = $this->getDefaultChannel(); } if ($channel !== 'pear.php.net') { if (isset($this->configuration[$layer]['__channels'][$channel][$key])) { unset($this->configuration[$layer]['__channels'][$channel][$key]); return true; } } if (isset($this->configuration[$layer][$key])) { unset($this->configuration[$layer][$key]); return true; } return false; } /** * Temporarily remove an entire config layer. USE WITH CARE! * * @param string config key * @param string (optional) config layer * @return bool TRUE on success, FALSE on failure * * @access public */ function removeLayer($layer) { if (isset($this->configuration[$layer])) { $this->configuration[$layer] = array(); return true; } return false; } /** * Stores configuration data in a layer. * * @param string config layer to store * @return bool TRUE on success, or PEAR error on failure * * @access public */ function store($layer = 'user', $data = null) { return $this->writeConfigFile(null, $layer, $data); } /** * Tells what config layer that gets to define a key. * * @param string config key * @param boolean return the defining channel * * @return string|array the config layer, or an empty string if not found. * * if $returnchannel, the return is an array array('layer' => layername, * 'channel' => channelname), or an empty string if not found * * @access public */ function definedBy($key, $returnchannel = false) { foreach ($this->layers as $layer) { $channel = $this->getDefaultChannel(); if ($channel !== 'pear.php.net') { if (isset($this->configuration[$layer]['__channels'][$channel][$key])) { if ($returnchannel) { return array('layer' => $layer, 'channel' => $channel); } return $layer; } } if (isset($this->configuration[$layer][$key])) { if ($returnchannel) { return array('layer' => $layer, 'channel' => 'pear.php.net'); } return $layer; } } return ''; } /** * Tells whether a given key exists as a config value. * * @param string config key * @return bool whether exists in this object * * @access public */ function isDefined($key) { foreach ($this->layers as $layer) { if (isset($this->configuration[$layer][$key])) { return true; } } return false; } /** * Tells whether a given config layer exists. * * @param string config layer * @return bool whether exists in this object * * @access public */ function isDefinedLayer($layer) { return isset($this->configuration[$layer]); } /** * Returns the layers defined (except the 'default' one) * * @return array of the defined layers */ function getLayers() { $cf = $this->configuration; unset($cf['default']); return array_keys($cf); } function apiVersion() { return '1.1'; } /** * @return PEAR_Registry */ function &getRegistry($use = null) { $layer = $use === null ? 'user' : $use; if (isset($this->_registry[$layer])) { return $this->_registry[$layer]; } elseif ($use === null && isset($this->_registry['system'])) { return $this->_registry['system']; } elseif ($use === null && isset($this->_registry['default'])) { return $this->_registry['default']; } elseif ($use) { $a = false; return $a; } // only go here if null was passed in echo "CRITICAL ERROR: Registry could not be initialized from any value"; exit(1); } /** * This is to allow customization like the use of installroot * @param PEAR_Registry * @return bool */ function setRegistry(&$reg, $layer = 'user') { if ($this->_noRegistry) { return false; } if (!in_array($layer, array('user', 'system'))) { return false; } $this->_registry[$layer] = &$reg; if (is_object($reg)) { $this->_registry[$layer]->setConfig($this, false); } return true; } function noRegistry() { $this->_noRegistry = true; } /** * @return PEAR_REST */ function &getREST($version, $options = array()) { $version = str_replace('.', '', $version); if (!class_exists($class = 'PEAR_REST_' . $version)) { require_once 'PEAR/REST/' . $version . '.php'; } $remote = new $class($this, $options); return $remote; } /** * The ftp server is set in {@link readFTPConfigFile()}. It exists only if a * remote configuration file has been specified * @return PEAR_FTP|false */ function &getFTP() { if (isset($this->_ftp)) { return $this->_ftp; } $a = false; return $a; } static function _prependPath($path, $prepend) { if (strlen($prepend) > 0) { if (OS_WINDOWS && preg_match('/^[a-z]:/i', $path)) { if (preg_match('/^[a-z]:/i', $prepend)) { $prepend = substr($prepend, 2); } elseif ($prepend[0] != '\\') { $prepend = "\\$prepend"; } $path = substr($path, 0, 2) . $prepend . substr($path, 2); } else { $path = $prepend . $path; } } return $path; } /** * @param string|false installation directory to prepend to all _dir variables, or false to * disable */ function setInstallRoot($root) { if (substr($root, -1) == DIRECTORY_SEPARATOR) { $root = substr($root, 0, -1); } $old = $this->_installRoot; $this->_installRoot = $root; if (($old != $root) && !$this->_noRegistry) { foreach (array_keys($this->_registry) as $layer) { if ($layer == 'ftp' || !isset($this->_registry[$layer])) { continue; } $this->_registry[$layer] = new PEAR_Registry( $this->get('php_dir', $layer, 'pear.php.net'), false, false, $this->get('metadata_dir', $layer, 'pear.php.net')); $this->_registry[$layer]->setConfig($this, false); $this->_regInitialized[$layer] = false; } } } } PKu]jy99PEAR/Validator/PECL.phpnu[ * @copyright 1997-2006 The PHP Group * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a5 */ /** * This is the parent class for all validators */ require_once 'PEAR/Validate.php'; /** * Channel Validator for the pecl.php.net channel * @category pear * @package PEAR * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a5 */ class PEAR_Validator_PECL extends PEAR_Validate { function validateVersion() { if ($this->_state == PEAR_VALIDATE_PACKAGING) { $version = $this->_packagexml->getVersion(); $versioncomponents = explode('.', $version); $last = array_pop($versioncomponents); if (substr($last, 1, 2) == 'rc') { $this->_addFailure('version', 'Release Candidate versions must have ' . 'upper-case RC, not lower-case rc'); return false; } } return true; } function validatePackageName() { $ret = parent::validatePackageName(); if ($this->_packagexml->getPackageType() == 'extsrc' || $this->_packagexml->getPackageType() == 'zendextsrc') { if (strtolower($this->_packagexml->getPackage()) != strtolower($this->_packagexml->getProvidesExtension())) { $this->_addWarning('providesextension', 'package name "' . $this->_packagexml->getPackage() . '" is different from extension name "' . $this->_packagexml->getProvidesExtension() . '"'); } } return $ret; } } ?>PKu]ZbgbgPEAR/Common.phpnu[ * @author Tomas V. V. Cox * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 0.1.0 * @deprecated File deprecated since Release 1.4.0a1 */ /** * Include error handling */ require_once 'PEAR.php'; /** * PEAR_Common error when an invalid PHP file is passed to PEAR_Common::analyzeSourceCode() */ define('PEAR_COMMON_ERROR_INVALIDPHP', 1); define('_PEAR_COMMON_PACKAGE_NAME_PREG', '[A-Za-z][a-zA-Z0-9_]+'); define('PEAR_COMMON_PACKAGE_NAME_PREG', '/^' . _PEAR_COMMON_PACKAGE_NAME_PREG . '\\z/'); // this should allow: 1, 1.0, 1.0RC1, 1.0dev, 1.0dev123234234234, 1.0a1, 1.0b1, 1.0pl1 define('_PEAR_COMMON_PACKAGE_VERSION_PREG', '\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?'); define('PEAR_COMMON_PACKAGE_VERSION_PREG', '/^' . _PEAR_COMMON_PACKAGE_VERSION_PREG . '\\z/i'); // XXX far from perfect :-) define('_PEAR_COMMON_PACKAGE_DOWNLOAD_PREG', '(' . _PEAR_COMMON_PACKAGE_NAME_PREG . ')(-([.0-9a-zA-Z]+))?'); define('PEAR_COMMON_PACKAGE_DOWNLOAD_PREG', '/^' . _PEAR_COMMON_PACKAGE_DOWNLOAD_PREG . '\\z/'); define('_PEAR_CHANNELS_NAME_PREG', '[A-Za-z][a-zA-Z0-9\.]+'); define('PEAR_CHANNELS_NAME_PREG', '/^' . _PEAR_CHANNELS_NAME_PREG . '\\z/'); // this should allow any dns or IP address, plus a path - NO UNDERSCORES ALLOWED define('_PEAR_CHANNELS_SERVER_PREG', '[a-zA-Z0-9\-]+(?:\.[a-zA-Z0-9\-]+)*(\/[a-zA-Z0-9\-]+)*'); define('PEAR_CHANNELS_SERVER_PREG', '/^' . _PEAR_CHANNELS_SERVER_PREG . '\\z/i'); define('_PEAR_CHANNELS_PACKAGE_PREG', '(' ._PEAR_CHANNELS_SERVER_PREG . ')\/(' . _PEAR_COMMON_PACKAGE_NAME_PREG . ')'); define('PEAR_CHANNELS_PACKAGE_PREG', '/^' . _PEAR_CHANNELS_PACKAGE_PREG . '\\z/i'); define('_PEAR_COMMON_CHANNEL_DOWNLOAD_PREG', '(' . _PEAR_CHANNELS_NAME_PREG . ')::(' . _PEAR_COMMON_PACKAGE_NAME_PREG . ')(-([.0-9a-zA-Z]+))?'); define('PEAR_COMMON_CHANNEL_DOWNLOAD_PREG', '/^' . _PEAR_COMMON_CHANNEL_DOWNLOAD_PREG . '\\z/'); /** * List of temporary files and directories registered by * PEAR_Common::addTempFile(). * @var array */ $GLOBALS['_PEAR_Common_tempfiles'] = array(); /** * Valid maintainer roles * @var array */ $GLOBALS['_PEAR_Common_maintainer_roles'] = array('lead','developer','contributor','helper'); /** * Valid release states * @var array */ $GLOBALS['_PEAR_Common_release_states'] = array('alpha','beta','stable','snapshot','devel'); /** * Valid dependency types * @var array */ $GLOBALS['_PEAR_Common_dependency_types'] = array('pkg','ext','php','prog','ldlib','rtlib','os','websrv','sapi'); /** * Valid dependency relations * @var array */ $GLOBALS['_PEAR_Common_dependency_relations'] = array('has','eq','lt','le','gt','ge','not', 'ne'); /** * Valid file roles * @var array */ $GLOBALS['_PEAR_Common_file_roles'] = array('php','ext','test','doc','data','src','script'); /** * Valid replacement types * @var array */ $GLOBALS['_PEAR_Common_replacement_types'] = array('php-const', 'pear-config', 'package-info'); /** * Valid "provide" types * @var array */ $GLOBALS['_PEAR_Common_provide_types'] = array('ext', 'prog', 'class', 'function', 'feature', 'api'); /** * Valid "provide" types * @var array */ $GLOBALS['_PEAR_Common_script_phases'] = array('pre-install', 'post-install', 'pre-uninstall', 'post-uninstall', 'pre-build', 'post-build', 'pre-configure', 'post-configure', 'pre-setup', 'post-setup'); /** * Class providing common functionality for PEAR administration classes. * @category pear * @package PEAR * @author Stig Bakken * @author Tomas V. V. Cox * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 * @deprecated This class will disappear, and its components will be spread * into smaller classes, like the AT&T breakup, as of Release 1.4.0a1 */ class PEAR_Common extends PEAR { /** * User Interface object (PEAR_Frontend_* class). If null, * the log() method uses print. * @var object */ var $ui = null; /** * Configuration object (PEAR_Config). * @var PEAR_Config */ var $config = null; /** stack of elements, gives some sort of XML context */ var $element_stack = array(); /** name of currently parsed XML element */ var $current_element; /** array of attributes of the currently parsed XML element */ var $current_attributes = array(); /** assoc with information about a package */ var $pkginfo = array(); var $current_path = null; /** * Flag variable used to mark a valid package file * @var boolean * @access private */ var $_validPackageFile; /** * PEAR_Common constructor * * @access public */ function __construct() { parent::__construct(); $this->config = &PEAR_Config::singleton(); $this->debug = $this->config->get('verbose'); } /** * PEAR_Common destructor * * @access private */ function _PEAR_Common() { // doesn't work due to bug #14744 //$tempfiles = $this->_tempfiles; $tempfiles =& $GLOBALS['_PEAR_Common_tempfiles']; while ($file = array_shift($tempfiles)) { if (@is_dir($file)) { if (!class_exists('System')) { require_once 'System.php'; } System::rm(array('-rf', $file)); } elseif (file_exists($file)) { unlink($file); } } } /** * Register a temporary file or directory. When the destructor is * executed, all registered temporary files and directories are * removed. * * @param string $file name of file or directory * * @return void * * @access public */ static function addTempFile($file) { if (!class_exists('PEAR_Frontend')) { require_once 'PEAR/Frontend.php'; } PEAR_Frontend::addTempFile($file); } /** * Wrapper to System::mkDir(), creates a directory as well as * any necessary parent directories. * * @param string $dir directory name * * @return bool TRUE on success, or a PEAR error * * @access public */ function mkDirHier($dir) { // Only used in Installer - move it there ? $this->log(2, "+ create dir $dir"); if (!class_exists('System')) { require_once 'System.php'; } return System::mkDir(array('-p', $dir)); } /** * Logging method. * * @param int $level log level (0 is quiet, higher is noisier) * @param string $msg message to write to the log * * @return void */ public function log($level, $msg, $append_crlf = true) { if ($this->debug >= $level) { if (!class_exists('PEAR_Frontend')) { require_once 'PEAR/Frontend.php'; } $ui = &PEAR_Frontend::singleton(); if (is_a($ui, 'PEAR_Frontend')) { $ui->log($msg, $append_crlf); } else { print "$msg\n"; } } } /** * Create and register a temporary directory. * * @param string $tmpdir (optional) Directory to use as tmpdir. * Will use system defaults (for example * /tmp or c:\windows\temp) if not specified * * @return string name of created directory * * @access public */ function mkTempDir($tmpdir = '') { $topt = $tmpdir ? array('-t', $tmpdir) : array(); $topt = array_merge($topt, array('-d', 'pear')); if (!class_exists('System')) { require_once 'System.php'; } if (!$tmpdir = System::mktemp($topt)) { return false; } self::addTempFile($tmpdir); return $tmpdir; } /** * Set object that represents the frontend to be used. * * @param object Reference of the frontend object * @return void * @access public */ function setFrontendObject(&$ui) { $this->ui = &$ui; } /** * Return an array containing all of the states that are more stable than * or equal to the passed in state * * @param string Release state * @param boolean Determines whether to include $state in the list * @return false|array False if $state is not a valid release state */ static function betterStates($state, $include = false) { static $states = array('snapshot', 'devel', 'alpha', 'beta', 'stable'); $i = array_search($state, $states); if ($i === false) { return false; } if ($include) { $i--; } return array_slice($states, $i + 1); } /** * Get the valid roles for a PEAR package maintainer * * @return array */ public static function getUserRoles() { return $GLOBALS['_PEAR_Common_maintainer_roles']; } /** * Get the valid package release states of packages * * @return array */ public static function getReleaseStates() { return $GLOBALS['_PEAR_Common_release_states']; } /** * Get the implemented dependency types (php, ext, pkg etc.) * * @return array */ public static function getDependencyTypes() { return $GLOBALS['_PEAR_Common_dependency_types']; } /** * Get the implemented dependency relations (has, lt, ge etc.) * * @return array */ public static function getDependencyRelations() { return $GLOBALS['_PEAR_Common_dependency_relations']; } /** * Get the implemented file roles * * @return array */ public static function getFileRoles() { return $GLOBALS['_PEAR_Common_file_roles']; } /** * Get the implemented file replacement types in * * @return array */ public static function getReplacementTypes() { return $GLOBALS['_PEAR_Common_replacement_types']; } /** * Get the implemented file replacement types in * * @return array */ public static function getProvideTypes() { return $GLOBALS['_PEAR_Common_provide_types']; } /** * Get the implemented file replacement types in * * @return array */ public static function getScriptPhases() { return $GLOBALS['_PEAR_Common_script_phases']; } /** * Test whether a string contains a valid package name. * * @param string $name the package name to test * * @return bool * * @access public */ function validPackageName($name) { return (bool)preg_match(PEAR_COMMON_PACKAGE_NAME_PREG, $name); } /** * Test whether a string contains a valid package version. * * @param string $ver the package version to test * * @return bool * * @access public */ function validPackageVersion($ver) { return (bool)preg_match(PEAR_COMMON_PACKAGE_VERSION_PREG, $ver); } /** * @param string $path relative or absolute include path * @return boolean */ public static function isIncludeable($path) { if (file_exists($path) && is_readable($path)) { return true; } $ipath = explode(PATH_SEPARATOR, ini_get('include_path')); foreach ($ipath as $include) { $test = realpath($include . DIRECTORY_SEPARATOR . $path); if (file_exists($test) && is_readable($test)) { return true; } } return false; } function _postProcessChecks($pf) { if (!PEAR::isError($pf)) { return $this->_postProcessValidPackagexml($pf); } $errs = $pf->getUserinfo(); if (is_array($errs)) { foreach ($errs as $error) { $e = $this->raiseError($error['message'], $error['code'], null, null, $error); } } return $pf; } /** * Returns information about a package file. Expects the name of * a gzipped tar file as input. * * @param string $file name of .tgz file * * @return array array with package information * * @access public * @deprecated use PEAR_PackageFile->fromTgzFile() instead * */ function infoFromTgzFile($file) { $packagefile = new PEAR_PackageFile($this->config); $pf = &$packagefile->fromTgzFile($file, PEAR_VALIDATE_NORMAL); return $this->_postProcessChecks($pf); } /** * Returns information about a package file. Expects the name of * a package xml file as input. * * @param string $descfile name of package xml file * * @return array array with package information * * @access public * @deprecated use PEAR_PackageFile->fromPackageFile() instead * */ function infoFromDescriptionFile($descfile) { $packagefile = new PEAR_PackageFile($this->config); $pf = &$packagefile->fromPackageFile($descfile, PEAR_VALIDATE_NORMAL); return $this->_postProcessChecks($pf); } /** * Returns information about a package file. Expects the contents * of a package xml file as input. * * @param string $data contents of package.xml file * * @return array array with package information * * @access public * @deprecated use PEAR_PackageFile->fromXmlstring() instead * */ function infoFromString($data) { $packagefile = new PEAR_PackageFile($this->config); $pf = &$packagefile->fromXmlString($data, PEAR_VALIDATE_NORMAL, false); return $this->_postProcessChecks($pf); } /** * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 * @return array */ function _postProcessValidPackagexml(&$pf) { if (!is_a($pf, 'PEAR_PackageFile_v2')) { $this->pkginfo = $pf->toArray(); return $this->pkginfo; } // sort of make this into a package.xml 1.0-style array // changelog is not converted to old format. $arr = $pf->toArray(true); $arr = array_merge($arr, $arr['old']); unset($arr['old'], $arr['xsdversion'], $arr['contents'], $arr['compatible'], $arr['channel'], $arr['uri'], $arr['dependencies'], $arr['phprelease'], $arr['extsrcrelease'], $arr['zendextsrcrelease'], $arr['extbinrelease'], $arr['zendextbinrelease'], $arr['bundle'], $arr['lead'], $arr['developer'], $arr['helper'], $arr['contributor']); $arr['filelist'] = $pf->getFilelist(); $this->pkginfo = $arr; return $arr; } /** * Returns package information from different sources * * This method is able to extract information about a package * from a .tgz archive or from a XML package definition file. * * @access public * @param string Filename of the source ('package.xml', '.tgz') * @return string * @deprecated use PEAR_PackageFile->fromAnyFile() instead */ function infoFromAny($info) { if (is_string($info) && file_exists($info)) { $packagefile = new PEAR_PackageFile($this->config); $pf = &$packagefile->fromAnyFile($info, PEAR_VALIDATE_NORMAL); if (PEAR::isError($pf)) { $errs = $pf->getUserinfo(); if (is_array($errs)) { foreach ($errs as $error) { $e = $this->raiseError($error['message'], $error['code'], null, null, $error); } } return $pf; } return $this->_postProcessValidPackagexml($pf); } return $info; } /** * Return an XML document based on the package info (as returned * by the PEAR_Common::infoFrom* methods). * * @param array $pkginfo package info * * @return string XML data * * @access public * @deprecated use a PEAR_PackageFile_v* object's generator instead */ function xmlFromInfo($pkginfo) { $config = &PEAR_Config::singleton(); $packagefile = new PEAR_PackageFile($config); $pf = &$packagefile->fromArray($pkginfo); $gen = &$pf->getDefaultGenerator(); return $gen->toXml(PEAR_VALIDATE_PACKAGING); } /** * Validate XML package definition file. * * @param string $info Filename of the package archive or of the * package definition file * @param array $errors Array that will contain the errors * @param array $warnings Array that will contain the warnings * @param string $dir_prefix (optional) directory where source files * may be found, or empty if they are not available * @access public * @return boolean * @deprecated use the validation of PEAR_PackageFile objects */ function validatePackageInfo($info, &$errors, &$warnings, $dir_prefix = '') { $config = &PEAR_Config::singleton(); $packagefile = new PEAR_PackageFile($config); PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); if (strpos($info, 'fromXmlString($info, PEAR_VALIDATE_NORMAL, ''); } else { $pf = &$packagefile->fromAnyFile($info, PEAR_VALIDATE_NORMAL); } PEAR::staticPopErrorHandling(); if (PEAR::isError($pf)) { $errs = $pf->getUserinfo(); if (is_array($errs)) { foreach ($errs as $error) { if ($error['level'] == 'error') { $errors[] = $error['message']; } else { $warnings[] = $error['message']; } } } return false; } return true; } /** * Build a "provides" array from data returned by * analyzeSourceCode(). The format of the built array is like * this: * * array( * 'class;MyClass' => 'array('type' => 'class', 'name' => 'MyClass'), * ... * ) * * * @param array $srcinfo array with information about a source file * as returned by the analyzeSourceCode() method. * * @return void * * @access public * */ function buildProvidesArray($srcinfo) { $file = basename($srcinfo['source_file']); $pn = ''; if (isset($this->_packageName)) { $pn = $this->_packageName; } $pnl = strlen($pn); foreach ($srcinfo['declared_classes'] as $class) { $key = "class;$class"; if (isset($this->pkginfo['provides'][$key])) { continue; } $this->pkginfo['provides'][$key] = array('file'=> $file, 'type' => 'class', 'name' => $class); if (isset($srcinfo['inheritance'][$class])) { $this->pkginfo['provides'][$key]['extends'] = $srcinfo['inheritance'][$class]; } } foreach ($srcinfo['declared_methods'] as $class => $methods) { foreach ($methods as $method) { $function = "$class::$method"; $key = "function;$function"; if ($method[0] == '_' || !strcasecmp($method, $class) || isset($this->pkginfo['provides'][$key])) { continue; } $this->pkginfo['provides'][$key] = array('file'=> $file, 'type' => 'function', 'name' => $function); } } foreach ($srcinfo['declared_functions'] as $function) { $key = "function;$function"; if ($function[0] == '_' || isset($this->pkginfo['provides'][$key])) { continue; } if (!strstr($function, '::') && strncasecmp($function, $pn, $pnl)) { $warnings[] = "in1 " . $file . ": function \"$function\" not prefixed with package name \"$pn\""; } $this->pkginfo['provides'][$key] = array('file'=> $file, 'type' => 'function', 'name' => $function); } } /** * Analyze the source code of the given PHP file * * @param string Filename of the PHP file * @return mixed * @access public */ static function analyzeSourceCode($file) { if (!class_exists('PEAR_PackageFile_v2_Validator')) { require_once 'PEAR/PackageFile/v2/Validator.php'; } $a = new PEAR_PackageFile_v2_Validator; return $a->analyzeSourceCode($file); } function detectDependencies($any, $status_callback = null) { if (!function_exists("token_get_all")) { return false; } if (PEAR::isError($info = $this->infoFromAny($any))) { return $this->raiseError($info); } if (!is_array($info)) { return false; } $deps = array(); $used_c = $decl_c = $decl_f = $decl_m = array(); foreach ($info['filelist'] as $file => $fa) { $tmp = $this->analyzeSourceCode($file); $used_c = @array_merge($used_c, $tmp['used_classes']); $decl_c = @array_merge($decl_c, $tmp['declared_classes']); $decl_f = @array_merge($decl_f, $tmp['declared_functions']); $decl_m = @array_merge($decl_m, $tmp['declared_methods']); $inheri = @array_merge($inheri, $tmp['inheritance']); } $used_c = array_unique($used_c); $decl_c = array_unique($decl_c); $undecl_c = array_diff($used_c, $decl_c); return array('used_classes' => $used_c, 'declared_classes' => $decl_c, 'declared_methods' => $decl_m, 'declared_functions' => $decl_f, 'undeclared_classes' => $undecl_c, 'inheritance' => $inheri, ); } /** * Download a file through HTTP. Considers suggested file name in * Content-disposition: header and can run a callback function for * different events. The callback will be called with two * parameters: the callback type, and parameters. The implemented * callback types are: * * 'setup' called at the very beginning, parameter is a UI object * that should be used for all output * 'message' the parameter is a string with an informational message * 'saveas' may be used to save with a different file name, the * parameter is the filename that is about to be used. * If a 'saveas' callback returns a non-empty string, * that file name will be used as the filename instead. * Note that $save_dir will not be affected by this, only * the basename of the file. * 'start' download is starting, parameter is number of bytes * that are expected, or -1 if unknown * 'bytesread' parameter is the number of bytes read so far * 'done' download is complete, parameter is the total number * of bytes read * 'connfailed' if the TCP connection fails, this callback is called * with array(host,port,errno,errmsg) * 'writefailed' if writing to disk fails, this callback is called * with array(destfile,errmsg) * * If an HTTP proxy has been configured (http_proxy PEAR_Config * setting), the proxy will be used. * * @param string $url the URL to download * @param object $ui PEAR_Frontend_* instance * @param object $config PEAR_Config instance * @param string $save_dir (optional) directory to save file in * @param mixed $callback (optional) function/method to call for status * updates * @param false|string|array $lastmodified header values to check against * for caching * use false to return the header * values from this download * @param false|array $accept Accept headers to send * @param false|string $channel Channel to use for retrieving * authentication * * @return mixed Returns the full path of the downloaded file or a PEAR * error on failure. If the error is caused by * socket-related errors, the error object will * have the fsockopen error code available through * getCode(). If caching is requested, then return the header * values. * If $lastmodified was given and the there are no changes, * boolean false is returned. * * @access public */ function downloadHttp( $url, &$ui, $save_dir = '.', $callback = null, $lastmodified = null, $accept = false, $channel = false ) { if (!class_exists('PEAR_Downloader')) { require_once 'PEAR/Downloader.php'; } return PEAR_Downloader::_downloadHttp( $this, $url, $ui, $save_dir, $callback, $lastmodified, $accept, $channel ); } } require_once 'PEAR/Config.php'; require_once 'PEAR/PackageFile.php'; PKu]s6 6 PEAR/Command/Config.xmlnu[ Show All Settings doConfigShow csh c show configuration variables for another channel CHAN [layer] Displays all configuration values. An optional argument may be used to tell which configuration layer to display. Valid configuration layers are "user", "system" and "default". To display configurations for different channels, set the default_channel configuration variable and run config-show again. Show One Setting doConfigGet cg c show configuration variables for another channel CHAN <parameter> [layer] Displays the value of one configuration parameter. The first argument is the name of the parameter, an optional second argument may be used to tell which configuration layer to look in. Valid configuration layers are "user", "system" and "default". If no layer is specified, a value will be picked from the first layer that defines the parameter, in the order just specified. The configuration value will be retrieved for the channel specified by the default_channel configuration variable. Change Setting doConfigSet cs c show configuration variables for another channel CHAN <parameter> <value> [layer] Sets the value of one configuration parameter. The first argument is the name of the parameter, the second argument is the new value. Some parameters are subject to validation, and the command will fail with an error message if the new value does not make sense. An optional third argument may be used to specify in which layer to set the configuration parameter. The default layer is "user". The configuration value will be set for the current channel, which is controlled by the default_channel configuration variable. Show Information About Setting doConfigHelp ch [parameter] Displays help for a configuration parameter. Without arguments it displays help for all configuration parameters. Create a Default configuration file doConfigCreate coc w create a config file for a windows install <root path> <filename> Create a default configuration file with all directory configuration variables set to subdirectories of <root path>, and save it as <filename>. This is useful especially for creating a configuration file for a remote PEAR installation (using the --remoteconfig option of install, upgrade, and uninstall). PKu]j!!PEAR/Command/Install.xmlnu[ Install Package doInstall i f will overwrite newer installed packages l do not check for recommended dependency version n ignore dependencies, install anyway r do not install files, only register the package as installed s soft install, fail silently, or upgrade if already installed B don't build C extensions D OPTION1=VALUE[ OPTION2=VALUE] Z request uncompressed files when downloading R root directory used when installing files (ala PHP's INSTALL_ROOT), use packagingroot for RPM DIR P root directory used when packaging files, like RPM packaging DIR force install even if there were errors a install all required and optional dependencies o install all required dependencies O do not attempt to download any urls or contact channels p Only list the packages that would be downloaded [channel/]<package> ... Installs one or more PEAR packages. You can specify a package to install in four ways: "Package-1.0.tgz" : installs from a local file "http://example.com/Package-1.0.tgz" : installs from anywhere on the net. "package.xml" : installs the package described in package.xml. Useful for testing, or for wrapping a PEAR package in another package manager such as RPM. "Package[-version/state][.tar]" : queries your default channel's server ({config master_server}) and downloads the newest package with the preferred quality/state ({config preferred_state}). To retrieve Package version 1.1, use "Package-1.1," to retrieve Package state beta, use "Package-beta." To retrieve an uncompressed file, append .tar (make sure there is no file by the same name first) To download a package from another channel, prefix with the channel name like "channel/Package" More than one package may be specified at once. It is ok to mix these four ways of specifying packages. Upgrade Package doInstall up c upgrade packages from a specific channel CHAN f overwrite newer installed packages l do not check for recommended dependency version n ignore dependencies, upgrade anyway r do not install files, only register the package as upgraded B don't build C extensions Z request uncompressed files when downloading R root directory used when installing files (ala PHP's INSTALL_ROOT) DIR force install even if there were errors a install all required and optional dependencies o install all required dependencies O do not attempt to download any urls or contact channels p Only list the packages that would be downloaded <package> ... Upgrades one or more PEAR packages. See documentation for the "install" command for ways to specify a package. When upgrading, your package will be updated if the provided new package has a higher version number (use the -f option if you need to upgrade anyway). More than one package may be specified at once. Upgrade All Packages [Deprecated in favor of calling upgrade with no parameters] doUpgradeAll ua c upgrade packages from a specific channel CHAN n ignore dependencies, upgrade anyway r do not install files, only register the package as upgraded B don't build C extensions Z request uncompressed files when downloading R root directory used when installing files (ala PHP's INSTALL_ROOT), use packagingroot for RPM DIR force install even if there were errors do not check for recommended dependency version WARNING: This function is deprecated in favor of using the upgrade command with no params Upgrades all packages that have a newer release available. Upgrades are done only if there is a release available of the state specified in "preferred_state" (currently {config preferred_state}), or a state considered more stable. Un-install Package doUninstall un n ignore dependencies, uninstall anyway r do not remove files, only register the packages as not installed R root directory used when installing files (ala PHP's INSTALL_ROOT) DIR force install even if there were errors O do not attempt to uninstall remotely [channel/]<package> ... Uninstalls one or more PEAR packages. More than one package may be specified at once. Prefix with channel name to uninstall from a channel not in your default channel ({config default_channel}) Unpacks a Pecl Package doBundle bun d Optional destination directory for unpacking (defaults to current path or "ext" if exists) DIR f Force the unpacking even if there were errors in the package <package> Unpacks a Pecl Package into the selected location. It will download the package if needed. Run Post-Install Scripts bundled with a package doRunScripts rs <package> Run post-installation scripts in package <package>, if any exist. PKu],_h/h/PEAR/Command/Test.phpnu[ * @author Martin Jansen * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 0.1 */ /** * base class */ require_once 'PEAR/Command/Common.php'; /** * PEAR commands for login/logout * * @category pear * @package PEAR * @author Stig Bakken * @author Martin Jansen * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 0.1 */ class PEAR_Command_Test extends PEAR_Command_Common { var $commands = array( 'run-tests' => array( 'summary' => 'Run Regression Tests', 'function' => 'doRunTests', 'shortcut' => 'rt', 'options' => array( 'recur' => array( 'shortopt' => 'r', 'doc' => 'Run tests in child directories, recursively. 4 dirs deep maximum', ), 'ini' => array( 'shortopt' => 'i', 'doc' => 'actual string of settings to pass to php in format " -d setting=blah"', 'arg' => 'SETTINGS' ), 'realtimelog' => array( 'shortopt' => 'l', 'doc' => 'Log test runs/results as they are run', ), 'quiet' => array( 'shortopt' => 'q', 'doc' => 'Only display detail for failed tests', ), 'simple' => array( 'shortopt' => 's', 'doc' => 'Display simple output for all tests', ), 'package' => array( 'shortopt' => 'p', 'doc' => 'Treat parameters as installed packages from which to run tests', ), 'phpunit' => array( 'shortopt' => 'u', 'doc' => 'Search parameters for AllTests.php, and use that to run phpunit-based tests If none is found, all .phpt tests will be tried instead.', ), 'tapoutput' => array( 'shortopt' => 't', 'doc' => 'Output run-tests.log in TAP-compliant format', ), 'cgi' => array( 'shortopt' => 'c', 'doc' => 'CGI php executable (needed for tests with POST/GET section)', 'arg' => 'PHPCGI', ), 'coverage' => array( 'shortopt' => 'x', 'doc' => 'Generate a code coverage report (requires Xdebug 2.0.0+)', ), 'showdiff' => array( 'shortopt' => 'd', 'doc' => 'Output diff on test failure', ), ), 'doc' => '[testfile|dir ...] Run regression tests with PHP\'s regression testing script (run-tests.php).', ), ); var $output; /** * PEAR_Command_Test constructor. * * @access public */ function __construct(&$ui, &$config) { parent::__construct($ui, $config); } function doRunTests($command, $options, $params) { if (isset($options['phpunit']) && isset($options['tapoutput'])) { return $this->raiseError('ERROR: cannot use both --phpunit and --tapoutput at the same time'); } require_once 'PEAR/Common.php'; require_once 'System.php'; $log = new PEAR_Common; $log->ui = &$this->ui; // slightly hacky, but it will work $tests = array(); $depth = isset($options['recur']) ? 14 : 1; if (!count($params)) { $params[] = '.'; } if (isset($options['package'])) { $oldparams = $params; $params = array(); $reg = &$this->config->getRegistry(); foreach ($oldparams as $param) { $pname = $reg->parsePackageName($param, $this->config->get('default_channel')); if (PEAR::isError($pname)) { return $this->raiseError($pname); } $package = &$reg->getPackage($pname['package'], $pname['channel']); if (!$package) { return PEAR::raiseError('Unknown package "' . $reg->parsedPackageNameToString($pname) . '"'); } $filelist = $package->getFilelist(); foreach ($filelist as $name => $atts) { if (isset($atts['role']) && $atts['role'] != 'test') { continue; } if (isset($options['phpunit']) && preg_match('/AllTests\.php\\z/i', $name)) { $params[] = $atts['installed_as']; continue; } elseif (!preg_match('/\.phpt\\z/', $name)) { continue; } $params[] = $atts['installed_as']; } } } foreach ($params as $p) { if (is_dir($p)) { if (isset($options['phpunit'])) { $dir = System::find(array($p, '-type', 'f', '-maxdepth', $depth, '-name', 'AllTests.php')); if (count($dir)) { foreach ($dir as $p) { $p = realpath($p); if (!count($tests) || (count($tests) && strlen($p) < strlen($tests[0]))) { // this is in a higher-level directory, use this one instead. $tests = array($p); } } } continue; } $args = array($p, '-type', 'f', '-name', '*.phpt'); } else { if (isset($options['phpunit'])) { if (preg_match('/AllTests\.php\\z/i', $p)) { $p = realpath($p); if (!count($tests) || (count($tests) && strlen($p) < strlen($tests[0]))) { // this is in a higher-level directory, use this one instead. $tests = array($p); } } continue; } if (file_exists($p) && preg_match('/\.phpt$/', $p)) { $tests[] = $p; continue; } if (!preg_match('/\.phpt\\z/', $p)) { $p .= '.phpt'; } $args = array(dirname($p), '-type', 'f', '-name', $p); } if (!isset($options['recur'])) { $args[] = '-maxdepth'; $args[] = 1; } $dir = System::find($args); $tests = array_merge($tests, $dir); } $ini_settings = ''; if (isset($options['ini'])) { $ini_settings .= $options['ini']; } if (isset($_ENV['TEST_PHP_INCLUDE_PATH'])) { $ini_settings .= " -d include_path={$_ENV['TEST_PHP_INCLUDE_PATH']}"; } if ($ini_settings) { $this->ui->outputData('Using INI settings: "' . $ini_settings . '"'); } $skipped = $passed = $failed = array(); $tests_count = count($tests); $this->ui->outputData('Running ' . $tests_count . ' tests', $command); $start = time(); if (isset($options['realtimelog']) && file_exists('run-tests.log')) { unlink('run-tests.log'); } if (isset($options['tapoutput'])) { $tap = '1..' . $tests_count . "\n"; } require_once 'PEAR/RunTest.php'; $run = new PEAR_RunTest($log, $options); $run->tests_count = $tests_count; if (isset($options['coverage']) && extension_loaded('xdebug')){ $run->xdebug_loaded = true; } else { $run->xdebug_loaded = false; } $j = $i = 1; foreach ($tests as $t) { if (isset($options['realtimelog'])) { $fp = @fopen('run-tests.log', 'a'); if ($fp) { fwrite($fp, "Running test [$i / $tests_count] $t..."); fclose($fp); } } PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); if (isset($options['phpunit'])) { $result = $run->runPHPUnit($t, $ini_settings); } else { $result = $run->run($t, $ini_settings, $j); } PEAR::staticPopErrorHandling(); if (PEAR::isError($result)) { $this->ui->log($result->getMessage()); continue; } if (isset($options['tapoutput'])) { $tap .= $result[0] . ' ' . $i . $result[1] . "\n"; continue; } if (isset($options['realtimelog'])) { $fp = @fopen('run-tests.log', 'a'); if ($fp) { fwrite($fp, "$result\n"); fclose($fp); } } if ($result == 'FAILED') { $failed[] = $t; } if ($result == 'PASSED') { $passed[] = $t; } if ($result == 'SKIPPED') { $skipped[] = $t; } $j++; } $total = date('i:s', time() - $start); if (isset($options['tapoutput'])) { $fp = @fopen('run-tests.log', 'w'); if ($fp) { fwrite($fp, $tap, strlen($tap)); fclose($fp); $this->ui->outputData('wrote TAP-format log to "' .realpath('run-tests.log') . '"', $command); } } else { if (count($failed)) { $output = "TOTAL TIME: $total\n"; $output .= count($passed) . " PASSED TESTS\n"; $output .= count($skipped) . " SKIPPED TESTS\n"; $output .= count($failed) . " FAILED TESTS:\n"; foreach ($failed as $failure) { $output .= $failure . "\n"; } $mode = isset($options['realtimelog']) ? 'a' : 'w'; $fp = @fopen('run-tests.log', $mode); if ($fp) { fwrite($fp, $output, strlen($output)); fclose($fp); $this->ui->outputData('wrote log to "' . realpath('run-tests.log') . '"', $command); } } elseif (file_exists('run-tests.log') && !is_dir('run-tests.log')) { @unlink('run-tests.log'); } } $this->ui->outputData('TOTAL TIME: ' . $total); $this->ui->outputData(count($passed) . ' PASSED TESTS', $command); $this->ui->outputData(count($skipped) . ' SKIPPED TESTS', $command); if (count($failed)) { $this->ui->outputData(count($failed) . ' FAILED TESTS:', $command); foreach ($failed as $failure) { $this->ui->outputData($failure, $command); } } if (count($failed) == 0) { return true; } return $this->raiseError('Some tests failed'); } } PKu] #S S PEAR/Command/Build.phpnu[ * @author Tomas V.V.Cox * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 0.1 */ /** * base class */ require_once 'PEAR/Command/Common.php'; /** * PEAR commands for building extensions. * * @category pear * @package PEAR * @author Stig Bakken * @author Tomas V.V.Cox * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 0.1 */ class PEAR_Command_Build extends PEAR_Command_Common { var $commands = array( 'build' => array( 'summary' => 'Build an Extension From C Source', 'function' => 'doBuild', 'shortcut' => 'b', 'options' => array( 'configureoptions' => array( 'shortopt' => 'D', 'arg' => 'OPTION1=VALUE[ OPTION2=VALUE]', 'doc' => 'space-delimited list of configure options', ), ), 'doc' => '[package.xml] Builds one or more extensions contained in a package.' ), ); /** * PEAR_Command_Build constructor. * * @access public */ function __construct(&$ui, &$config) { parent::__construct($ui, $config); } function doBuild($command, $options, $params) { require_once 'PEAR/Builder.php'; if (sizeof($params) < 1) { $params[0] = 'package.xml'; } $configureoptions = empty($options['configureoptions']) ? '' : $options['configureoptions']; $builder = new PEAR_Builder($configureoptions, $this->ui); $this->debug = $this->config->get('verbose'); $err = $builder->build($params[0], array(&$this, 'buildCallback')); if (PEAR::isError($err)) { return $err; } return true; } function buildCallback($what, $data) { if (($what == 'cmdoutput' && $this->debug > 1) || ($what == 'output' && $this->debug > 0)) { $this->ui->outputData(rtrim($data), 'build'); } } } PKu] \ PEAR/Command/Remote.xmlnu[ Information About Remote Packages doRemoteInfo ri <package> Get details on a package from the server. List Available Upgrades doListUpgrades lu i output fully channel-aware data, even on failure [preferred_state] List releases on the server of packages you have installed where a newer version is available with the same release state (stable etc.) or the state passed as the second parameter. List Remote Packages doRemoteList rl c specify a channel other than the default channel CHAN Lists the packages available on the configured server along with the latest stable release of each package. Search remote package database doSearch sp c specify a channel other than the default channel CHAN a search packages from all known channels i output fully channel-aware data, even on failure [packagename] [packageinfo] Lists all packages which match the search parameters. The first parameter is a fragment of a packagename. The default channel will be used unless explicitly overridden. The second parameter will be used to match any portion of the summary/description List All Packages doListAll la c specify a channel other than the default channel CHAN i output fully channel-aware data, even on failure Lists the packages available on the configured server along with the latest stable release of each package. Download Package doDownload d Z download an uncompressed (.tar) file <package>... Download package tarballs. The files will be named as suggested by the server, for example if you download the DB package and the latest stable version of DB is 1.6.5, the downloaded file will be DB-1.6.5.tgz. Clear Web Services Cache doClearCache cc Clear the XML-RPC/REST cache. See also the cache_ttl configuration parameter. PKu]uPEAR/Command/Registry.xmlnu[ List Installed Packages In The Default Channel doList l c list installed packages from this channel CHAN a list installed packages from all channels i output fully channel-aware data, even on failure <package> If invoked without parameters, this command lists the PEAR packages installed in your php_dir ({config php_dir}). With a parameter, it lists the files in a package. List Files In Installed Package doFileList fl <package> List the files in an installed package. Shell Script Test doShellTest st <package> [[relation] version] Tests if a package is installed in the system. Will exit(1) if it is not. <relation> The version comparison operator. One of: <, lt, <=, le, >, gt, >=, ge, ==, =, eq, !=, <>, ne <version> The version to compare with Display information about a package doInfo in <package> Displays information about a package. The package argument may be a local package file, an URL to a package file, or the name of an installed package. PKu]PEAR/Command/Mirror.phpnu[ * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 1.2.0 */ /** * base class */ require_once 'PEAR/Command/Common.php'; /** * PEAR commands for providing file mirrors * * @category pear * @package PEAR * @author Alexander Merz * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.2.0 */ class PEAR_Command_Mirror extends PEAR_Command_Common { var $commands = array( 'download-all' => array( 'summary' => 'Downloads each available package from the default channel', 'function' => 'doDownloadAll', 'shortcut' => 'da', 'options' => array( 'channel' => array( 'shortopt' => 'c', 'doc' => 'specify a channel other than the default channel', 'arg' => 'CHAN', ), ), 'doc' => ' Requests a list of available packages from the default channel ({config default_channel}) and downloads them to current working directory. Note: only packages within preferred_state ({config preferred_state}) will be downloaded' ), ); /** * PEAR_Command_Mirror constructor. * * @access public * @param object PEAR_Frontend a reference to an frontend * @param object PEAR_Config a reference to the configuration data */ function __construct(&$ui, &$config) { parent::__construct($ui, $config); } /** * For unit-testing */ function &factory($a) { $a = &PEAR_Command::factory($a, $this->config); return $a; } /** * retrieves a list of avaible Packages from master server * and downloads them * * @access public * @param string $command the command * @param array $options the command options before the command * @param array $params the stuff after the command name * @return bool true if successful * @throw PEAR_Error */ function doDownloadAll($command, $options, $params) { $savechannel = $this->config->get('default_channel'); $reg = &$this->config->getRegistry(); $channel = isset($options['channel']) ? $options['channel'] : $this->config->get('default_channel'); if (!$reg->channelExists($channel)) { $this->config->set('default_channel', $savechannel); return $this->raiseError('Channel "' . $channel . '" does not exist'); } $this->config->set('default_channel', $channel); $this->ui->outputData('Using Channel ' . $this->config->get('default_channel')); $chan = $reg->getChannel($channel); if (PEAR::isError($chan)) { return $this->raiseError($chan); } if ($chan->supportsREST($this->config->get('preferred_mirror')) && $base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) { $rest = &$this->config->getREST('1.0', array()); $remoteInfo = array_flip($rest->listPackages($base, $channel)); } if (PEAR::isError($remoteInfo)) { return $remoteInfo; } $cmd = &$this->factory("download"); if (PEAR::isError($cmd)) { return $cmd; } $this->ui->outputData('Using Preferred State of ' . $this->config->get('preferred_state')); $this->ui->outputData('Gathering release information, please wait...'); /** * Error handling not necessary, because already done by * the download command */ PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); $err = $cmd->run('download', array('downloadonly' => true), array_keys($remoteInfo)); PEAR::staticPopErrorHandling(); $this->config->set('default_channel', $savechannel); if (PEAR::isError($err)) { $this->ui->outputData($err->getMessage()); } return true; } } PKu],t"u"uPEAR/Command/Remote.phpnu[ * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 0.1 */ /** * base class */ require_once 'PEAR/Command/Common.php'; require_once 'PEAR/REST.php'; /** * PEAR commands for remote server querying * * @category pear * @package PEAR * @author Stig Bakken * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 0.1 */ class PEAR_Command_Remote extends PEAR_Command_Common { var $commands = array( 'remote-info' => array( 'summary' => 'Information About Remote Packages', 'function' => 'doRemoteInfo', 'shortcut' => 'ri', 'options' => array(), 'doc' => ' Get details on a package from the server.', ), 'list-upgrades' => array( 'summary' => 'List Available Upgrades', 'function' => 'doListUpgrades', 'shortcut' => 'lu', 'options' => array( 'channelinfo' => array( 'shortopt' => 'i', 'doc' => 'output fully channel-aware data, even on failure', ), ), 'doc' => '[preferred_state] List releases on the server of packages you have installed where a newer version is available with the same release state (stable etc.) or the state passed as the second parameter.' ), 'remote-list' => array( 'summary' => 'List Remote Packages', 'function' => 'doRemoteList', 'shortcut' => 'rl', 'options' => array( 'channel' => array( 'shortopt' => 'c', 'doc' => 'specify a channel other than the default channel', 'arg' => 'CHAN', ) ), 'doc' => ' Lists the packages available on the configured server along with the latest stable release of each package.', ), 'search' => array( 'summary' => 'Search remote package database', 'function' => 'doSearch', 'shortcut' => 'sp', 'options' => array( 'channel' => array( 'shortopt' => 'c', 'doc' => 'specify a channel other than the default channel', 'arg' => 'CHAN', ), 'allchannels' => array( 'shortopt' => 'a', 'doc' => 'search packages from all known channels', ), 'channelinfo' => array( 'shortopt' => 'i', 'doc' => 'output fully channel-aware data, even on failure', ), ), 'doc' => '[packagename] [packageinfo] Lists all packages which match the search parameters. The first parameter is a fragment of a packagename. The default channel will be used unless explicitly overridden. The second parameter will be used to match any portion of the summary/description', ), 'list-all' => array( 'summary' => 'List All Packages', 'function' => 'doListAll', 'shortcut' => 'la', 'options' => array( 'channel' => array( 'shortopt' => 'c', 'doc' => 'specify a channel other than the default channel', 'arg' => 'CHAN', ), 'channelinfo' => array( 'shortopt' => 'i', 'doc' => 'output fully channel-aware data, even on failure', ), ), 'doc' => ' Lists the packages available on the configured server along with the latest stable release of each package.', ), 'download' => array( 'summary' => 'Download Package', 'function' => 'doDownload', 'shortcut' => 'd', 'options' => array( 'nocompress' => array( 'shortopt' => 'Z', 'doc' => 'download an uncompressed (.tar) file', ), ), 'doc' => '... Download package tarballs. The files will be named as suggested by the server, for example if you download the DB package and the latest stable version of DB is 1.6.5, the downloaded file will be DB-1.6.5.tgz.', ), 'clear-cache' => array( 'summary' => 'Clear Web Services Cache', 'function' => 'doClearCache', 'shortcut' => 'cc', 'options' => array(), 'doc' => ' Clear the REST cache. See also the cache_ttl configuration parameter. ', ), ); /** * PEAR_Command_Remote constructor. * * @access public */ function __construct(&$ui, &$config) { parent::__construct($ui, $config); } function _checkChannelForStatus($channel, $chan) { if (PEAR::isError($chan)) { $this->raiseError($chan); } if (!is_a($chan, 'PEAR_ChannelFile')) { return $this->raiseError('Internal corruption error: invalid channel "' . $channel . '"'); } $rest = new PEAR_REST($this->config); PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); $mirror = $this->config->get('preferred_mirror', null, $channel); $a = $rest->downloadHttp('http://' . $channel . '/channel.xml', $chan->lastModified()); PEAR::staticPopErrorHandling(); if (!PEAR::isError($a) && $a) { $this->ui->outputData('WARNING: channel "' . $channel . '" has ' . 'updated its protocols, use "' . PEAR_RUNTYPE . ' channel-update ' . $channel . '" to update'); } } function doRemoteInfo($command, $options, $params) { if (sizeof($params) != 1) { return $this->raiseError("$command expects one param: the remote package name"); } $savechannel = $channel = $this->config->get('default_channel'); $reg = &$this->config->getRegistry(); $package = $params[0]; $parsed = $reg->parsePackageName($package, $channel); if (PEAR::isError($parsed)) { return $this->raiseError('Invalid package name "' . $package . '"'); } $channel = $parsed['channel']; $this->config->set('default_channel', $channel); $chan = $reg->getChannel($channel); if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) { return $e; } $mirror = $this->config->get('preferred_mirror'); if ($chan->supportsREST($mirror) && $base = $chan->getBaseURL('REST1.0', $mirror)) { $rest = &$this->config->getREST('1.0', array()); $info = $rest->packageInfo($base, $parsed['package'], $channel); } if (!isset($info)) { return $this->raiseError('No supported protocol was found'); } if (PEAR::isError($info)) { $this->config->set('default_channel', $savechannel); return $this->raiseError($info); } if (!isset($info['name'])) { return $this->raiseError('No remote package "' . $package . '" was found'); } $installed = $reg->packageInfo($info['name'], null, $channel); $info['installed'] = $installed ? $installed['version'] : '- no -'; if (is_array($info['installed'])) { $info['installed'] = $info['installed']['release']; } $this->ui->outputData($info, $command); $this->config->set('default_channel', $savechannel); return true; } function doRemoteList($command, $options, $params) { $savechannel = $channel = $this->config->get('default_channel'); $reg = &$this->config->getRegistry(); if (isset($options['channel'])) { $channel = $options['channel']; if (!$reg->channelExists($channel)) { return $this->raiseError('Channel "' . $channel . '" does not exist'); } $this->config->set('default_channel', $channel); } $chan = $reg->getChannel($channel); if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) { return $e; } $list_options = false; if ($this->config->get('preferred_state') == 'stable') { $list_options = true; } $available = array(); if ($chan->supportsREST($this->config->get('preferred_mirror')) && $base = $chan->getBaseURL('REST1.1', $this->config->get('preferred_mirror')) ) { // use faster list-all if available $rest = &$this->config->getREST('1.1', array()); $available = $rest->listAll($base, $list_options, true, false, false, $chan->getName()); } elseif ($chan->supportsREST($this->config->get('preferred_mirror')) && $base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) { $rest = &$this->config->getREST('1.0', array()); $available = $rest->listAll($base, $list_options, true, false, false, $chan->getName()); } if (PEAR::isError($available)) { $this->config->set('default_channel', $savechannel); return $this->raiseError($available); } $i = $j = 0; $data = array( 'caption' => 'Channel ' . $channel . ' Available packages:', 'border' => true, 'headline' => array('Package', 'Version'), 'channel' => $channel ); if (count($available) == 0) { $data = '(no packages available yet)'; } else { foreach ($available as $name => $info) { $version = (isset($info['stable']) && $info['stable']) ? $info['stable'] : '-n/a-'; $data['data'][] = array($name, $version); } } $this->ui->outputData($data, $command); $this->config->set('default_channel', $savechannel); return true; } function doListAll($command, $options, $params) { $savechannel = $channel = $this->config->get('default_channel'); $reg = &$this->config->getRegistry(); if (isset($options['channel'])) { $channel = $options['channel']; if (!$reg->channelExists($channel)) { return $this->raiseError("Channel \"$channel\" does not exist"); } $this->config->set('default_channel', $channel); } $list_options = false; if ($this->config->get('preferred_state') == 'stable') { $list_options = true; } $chan = $reg->getChannel($channel); if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) { return $e; } if ($chan->supportsREST($this->config->get('preferred_mirror')) && $base = $chan->getBaseURL('REST1.1', $this->config->get('preferred_mirror'))) { // use faster list-all if available $rest = &$this->config->getREST('1.1', array()); $available = $rest->listAll($base, $list_options, false, false, false, $chan->getName()); } elseif ($chan->supportsREST($this->config->get('preferred_mirror')) && $base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) { $rest = &$this->config->getREST('1.0', array()); $available = $rest->listAll($base, $list_options, false, false, false, $chan->getName()); } if (PEAR::isError($available)) { $this->config->set('default_channel', $savechannel); return $this->raiseError('The package list could not be fetched from the remote server. Please try again. (Debug info: "' . $available->getMessage() . '")'); } $data = array( 'caption' => 'All packages [Channel ' . $channel . ']:', 'border' => true, 'headline' => array('Package', 'Latest', 'Local'), 'channel' => $channel, ); if (isset($options['channelinfo'])) { // add full channelinfo $data['caption'] = 'Channel ' . $channel . ' All packages:'; $data['headline'] = array('Channel', 'Package', 'Latest', 'Local', 'Description', 'Dependencies'); } $local_pkgs = $reg->listPackages($channel); foreach ($available as $name => $info) { $installed = $reg->packageInfo($name, null, $channel); if ($installed && is_array($installed['version'])) { $installed['version'] = $installed['version']['release']; } $desc = $info['summary']; if (isset($params[$name])) { $desc .= "\n\n".$info['description']; } if (isset($options['mode'])) { if ($options['mode'] == 'installed' && !isset($installed['version'])) { continue; } if ($options['mode'] == 'notinstalled' && isset($installed['version'])) { continue; } if ($options['mode'] == 'upgrades' && (!isset($installed['version']) || version_compare($installed['version'], $info['stable'], '>='))) { continue; } } $pos = array_search(strtolower($name), $local_pkgs); if ($pos !== false) { unset($local_pkgs[$pos]); } if (isset($info['stable']) && !$info['stable']) { $info['stable'] = null; } if (isset($options['channelinfo'])) { // add full channelinfo if ($info['stable'] === $info['unstable']) { $state = $info['state']; } else { $state = 'stable'; } $latest = $info['stable'].' ('.$state.')'; $local = ''; if (isset($installed['version'])) { $inst_state = $reg->packageInfo($name, 'release_state', $channel); $local = $installed['version'].' ('.$inst_state.')'; } $packageinfo = array( $channel, $name, $latest, $local, isset($desc) ? $desc : null, isset($info['deps']) ? $info['deps'] : null, ); } else { $packageinfo = array( $reg->channelAlias($channel) . '/' . $name, isset($info['stable']) ? $info['stable'] : null, isset($installed['version']) ? $installed['version'] : null, isset($desc) ? $desc : null, isset($info['deps']) ? $info['deps'] : null, ); } $data['data'][$info['category']][] = $packageinfo; } if (isset($options['mode']) && in_array($options['mode'], array('notinstalled', 'upgrades'))) { $this->config->set('default_channel', $savechannel); $this->ui->outputData($data, $command); return true; } foreach ($local_pkgs as $name) { $info = &$reg->getPackage($name, $channel); $data['data']['Local'][] = array( $reg->channelAlias($channel) . '/' . $info->getPackage(), '', $info->getVersion(), $info->getSummary(), $info->getDeps() ); } $this->config->set('default_channel', $savechannel); $this->ui->outputData($data, $command); return true; } function doSearch($command, $options, $params) { if ((!isset($params[0]) || empty($params[0])) && (!isset($params[1]) || empty($params[1]))) { return $this->raiseError('no valid search string supplied'); } $channelinfo = isset($options['channelinfo']); $reg = &$this->config->getRegistry(); if (isset($options['allchannels'])) { // search all channels unset($options['allchannels']); $channels = $reg->getChannels(); $errors = array(); PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); foreach ($channels as $channel) { if ($channel->getName() != '__uri') { $options['channel'] = $channel->getName(); $ret = $this->doSearch($command, $options, $params); if (PEAR::isError($ret)) { $errors[] = $ret; } } } PEAR::staticPopErrorHandling(); if (count($errors) !== 0) { // for now, only give first error return PEAR::raiseError($errors[0]); } return true; } $savechannel = $channel = $this->config->get('default_channel'); $package = strtolower($params[0]); $summary = isset($params[1]) ? $params[1] : false; if (isset($options['channel'])) { $reg = &$this->config->getRegistry(); $channel = $options['channel']; if (!$reg->channelExists($channel)) { return $this->raiseError('Channel "' . $channel . '" does not exist'); } $this->config->set('default_channel', $channel); } $chan = $reg->getChannel($channel); if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) { return $e; } if ($chan->supportsREST($this->config->get('preferred_mirror')) && $base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) { $rest = &$this->config->getREST('1.0', array()); $available = $rest->listAll($base, false, false, $package, $summary, $chan->getName()); } if (PEAR::isError($available)) { $this->config->set('default_channel', $savechannel); return $this->raiseError($available); } if (!$available && !$channelinfo) { // clean exit when not found, no error ! $data = 'no packages found that match pattern "' . $package . '", for channel '.$channel.'.'; $this->ui->outputData($data); $this->config->set('default_channel', $channel); return true; } if ($channelinfo) { $data = array( 'caption' => 'Matched packages, channel ' . $channel . ':', 'border' => true, 'headline' => array('Channel', 'Package', 'Stable/(Latest)', 'Local'), 'channel' => $channel ); } else { $data = array( 'caption' => 'Matched packages, channel ' . $channel . ':', 'border' => true, 'headline' => array('Package', 'Stable/(Latest)', 'Local'), 'channel' => $channel ); } if (!$available && $channelinfo) { unset($data['headline']); $data['data'] = 'No packages found that match pattern "' . $package . '".'; $available = array(); } foreach ($available as $name => $info) { $installed = $reg->packageInfo($name, null, $channel); $desc = $info['summary']; if (isset($params[$name])) $desc .= "\n\n".$info['description']; if (!isset($info['stable']) || !$info['stable']) { $version_remote = 'none'; } else { if ($info['unstable']) { $version_remote = $info['unstable']; } else { $version_remote = $info['stable']; } $version_remote .= ' ('.$info['state'].')'; } $version = is_array($installed['version']) ? $installed['version']['release'] : $installed['version']; if ($channelinfo) { $packageinfo = array( $channel, $name, $version_remote, $version, $desc, ); } else { $packageinfo = array( $name, $version_remote, $version, $desc, ); } $data['data'][$info['category']][] = $packageinfo; } $this->ui->outputData($data, $command); $this->config->set('default_channel', $channel); return true; } function &getDownloader($options) { if (!class_exists('PEAR_Downloader')) { require_once 'PEAR/Downloader.php'; } $a = new PEAR_Downloader($this->ui, $options, $this->config); return $a; } function doDownload($command, $options, $params) { // make certain that dependencies are ignored $options['downloadonly'] = 1; // eliminate error messages for preferred_state-related errors /* TODO: Should be an option, but until now download does respect preferred state */ /* $options['ignorepreferred_state'] = 1; */ // eliminate error messages for preferred_state-related errors $downloader = &$this->getDownloader($options); PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); $e = $downloader->setDownloadDir(getcwd()); PEAR::staticPopErrorHandling(); if (PEAR::isError($e)) { return $this->raiseError('Current directory is not writeable, cannot download'); } $errors = array(); $downloaded = array(); $err = $downloader->download($params); if (PEAR::isError($err)) { return $err; } $errors = $downloader->getErrorMsgs(); if (count($errors)) { foreach ($errors as $error) { if ($error !== null) { $this->ui->outputData($error); } } return $this->raiseError("$command failed"); } $downloaded = $downloader->getDownloadedPackages(); foreach ($downloaded as $pkg) { $this->ui->outputData("File $pkg[file] downloaded", $command); } return true; } function downloadCallback($msg, $params = null) { if ($msg == 'done') { $this->bytes_downloaded = $params; } } function doListUpgrades($command, $options, $params) { require_once 'PEAR/Common.php'; if (isset($params[0]) && !is_array(PEAR_Common::betterStates($params[0]))) { return $this->raiseError($params[0] . ' is not a valid state (stable/beta/alpha/devel/etc.) try "pear help list-upgrades"'); } $savechannel = $channel = $this->config->get('default_channel'); $reg = &$this->config->getRegistry(); foreach ($reg->listChannels() as $channel) { $inst = array_flip($reg->listPackages($channel)); if (!count($inst)) { continue; } if ($channel == '__uri') { continue; } $this->config->set('default_channel', $channel); $state = empty($params[0]) ? $this->config->get('preferred_state') : $params[0]; $caption = $channel . ' Available Upgrades'; $chan = $reg->getChannel($channel); if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) { return $e; } $latest = array(); $base2 = false; $preferred_mirror = $this->config->get('preferred_mirror'); if ($chan->supportsREST($preferred_mirror) && ( ($base2 = $chan->getBaseURL('REST1.3', $preferred_mirror)) || ($base = $chan->getBaseURL('REST1.0', $preferred_mirror)) ) ) { if ($base2) { $rest = &$this->config->getREST('1.3', array()); $base = $base2; } else { $rest = &$this->config->getREST('1.0', array()); } if (empty($state) || $state == 'any') { $state = false; } else { $caption .= ' (' . implode(', ', PEAR_Common::betterStates($state, true)) . ')'; } PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); $latest = $rest->listLatestUpgrades($base, $state, $inst, $channel, $reg); PEAR::staticPopErrorHandling(); } if (PEAR::isError($latest)) { $this->ui->outputData($latest->getMessage()); continue; } $caption .= ':'; if (PEAR::isError($latest)) { $this->config->set('default_channel', $savechannel); return $latest; } $data = array( 'caption' => $caption, 'border' => 1, 'headline' => array('Channel', 'Package', 'Local', 'Remote', 'Size'), 'channel' => $channel ); foreach ((array)$latest as $pkg => $info) { $package = strtolower($pkg); if (!isset($inst[$package])) { // skip packages we don't have installed continue; } extract($info); $inst_version = $reg->packageInfo($package, 'version', $channel); $inst_state = $reg->packageInfo($package, 'release_state', $channel); if (version_compare("$version", "$inst_version", "le")) { // installed version is up-to-date continue; } if ($filesize >= 20480) { $filesize += 1024 - ($filesize % 1024); $fs = sprintf("%dkB", $filesize / 1024); } elseif ($filesize > 0) { $filesize += 103 - ($filesize % 103); $fs = sprintf("%.1fkB", $filesize / 1024.0); } else { $fs = " -"; // XXX center instead } $data['data'][] = array($channel, $pkg, "$inst_version ($inst_state)", "$version ($state)", $fs); } if (isset($options['channelinfo'])) { if (empty($data['data'])) { unset($data['headline']); if (count($inst) == 0) { $data['data'] = '(no packages installed)'; } else { $data['data'] = '(no upgrades available)'; } } $this->ui->outputData($data, $command); } else { if (empty($data['data'])) { $this->ui->outputData('Channel ' . $channel . ': No upgrades available'); } else { $this->ui->outputData($data, $command); } } } $this->config->set('default_channel', $savechannel); return true; } function doClearCache($command, $options, $params) { $cache_dir = $this->config->get('cache_dir'); $verbose = $this->config->get('verbose'); $output = ''; if (!file_exists($cache_dir) || !is_dir($cache_dir)) { return $this->raiseError("$cache_dir does not exist or is not a directory"); } if (!($dp = @opendir($cache_dir))) { return $this->raiseError("opendir($cache_dir) failed: $php_errormsg"); } if ($verbose >= 1) { $output .= "reading directory $cache_dir\n"; } $num = 0; while ($ent = readdir($dp)) { if (preg_match('/rest.cache(file|id)\\z/', $ent)) { $path = $cache_dir . DIRECTORY_SEPARATOR . $ent; if (file_exists($path)) { $ok = @unlink($path); } else { $ok = false; $php_errormsg = ''; } if ($ok) { if ($verbose >= 2) { $output .= "deleted $path\n"; } $num++; } elseif ($verbose >= 1) { $output .= "failed to delete $path $php_errormsg\n"; } } } closedir($dp); if ($verbose >= 1) { $output .= "$num cache entries cleared\n"; } $this->ui->outputData(rtrim($output), $command); return $num; } } PKu]d֣SPEAR/Command/Pickle.xmlnu[ Build PECL Package doPackage pi Z Do not gzip the package file n Print the name of the packaged file. [descfile] Creates a PECL package from its package2.xml file. An automatic conversion will be made to a package.xml 1.0 and written out to disk in the current directory as "package.xml". Note that only simple package.xml 2.0 will be converted. package.xml 2.0 with: - dependency types other than required/optional PECL package/ext/php/pearinstaller - more than one extsrcrelease or zendextsrcrelease - zendextbinrelease, extbinrelease, phprelease, or bundle release type - dependency groups - ignore tags in release filelist - tasks other than replace - custom roles will cause pickle to fail, and output an error message. If your package2.xml uses any of these features, you are best off using PEAR_PackageFileManager to generate both package.xml. PKu] uPEAR/Command/Build.xmlnu[ Build an Extension From C Source doBuild b D OPTION1=VALUE[ OPTION2=VALUE] [package.xml] Builds one or more extensions contained in a package. PKu]P>>PEAR/Command/Pickle.phpnu[ * @copyright 2005-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.1 */ /** * base class */ require_once 'PEAR/Command/Common.php'; /** * PEAR commands for login/logout * * @category pear * @package PEAR * @author Greg Beaver * @copyright 2005-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.1 */ class PEAR_Command_Pickle extends PEAR_Command_Common { var $commands = array( 'pickle' => array( 'summary' => 'Build PECL Package', 'function' => 'doPackage', 'shortcut' => 'pi', 'options' => array( 'nocompress' => array( 'shortopt' => 'Z', 'doc' => 'Do not gzip the package file' ), 'showname' => array( 'shortopt' => 'n', 'doc' => 'Print the name of the packaged file.', ), ), 'doc' => '[descfile] Creates a PECL package from its package2.xml file. An automatic conversion will be made to a package.xml 1.0 and written out to disk in the current directory as "package.xml". Note that only simple package.xml 2.0 will be converted. package.xml 2.0 with: - dependency types other than required/optional PECL package/ext/php/pearinstaller - more than one extsrcrelease or zendextsrcrelease - zendextbinrelease, extbinrelease, phprelease, or bundle release type - dependency groups - ignore tags in release filelist - tasks other than replace - custom roles will cause pickle to fail, and output an error message. If your package2.xml uses any of these features, you are best off using PEAR_PackageFileManager to generate both package.xml. ' ), ); /** * PEAR_Command_Package constructor. * * @access public */ function __construct(&$ui, &$config) { parent::__construct($ui, $config); } /** * For unit-testing ease * * @return PEAR_Packager */ function &getPackager() { if (!class_exists('PEAR_Packager')) { require_once 'PEAR/Packager.php'; } $a = new PEAR_Packager; return $a; } /** * For unit-testing ease * * @param PEAR_Config $config * @param bool $debug * @param string|null $tmpdir * @return PEAR_PackageFile */ function &getPackageFile($config, $debug = false) { if (!class_exists('PEAR_Common')) { require_once 'PEAR/Common.php'; } if (!class_exists('PEAR_PackageFile')) { require_once 'PEAR/PackageFile.php'; } $a = new PEAR_PackageFile($config, $debug); $common = new PEAR_Common; $common->ui = $this->ui; $a->setLogger($common); return $a; } function doPackage($command, $options, $params) { $this->output = ''; $pkginfofile = isset($params[0]) ? $params[0] : 'package2.xml'; $packager = &$this->getPackager(); if (PEAR::isError($err = $this->_convertPackage($pkginfofile))) { return $err; } $compress = empty($options['nocompress']) ? true : false; $result = $packager->package($pkginfofile, $compress, 'package.xml'); if (PEAR::isError($result)) { return $this->raiseError($result); } // Don't want output, only the package file name just created if (isset($options['showname'])) { $this->ui->outputData($result, $command); } return true; } function _convertPackage($packagexml) { $pkg = &$this->getPackageFile($this->config); $pf2 = &$pkg->fromPackageFile($packagexml, PEAR_VALIDATE_NORMAL); if (!is_a($pf2, 'PEAR_PackageFile_v2')) { return $this->raiseError('Cannot process "' . $packagexml . '", is not a package.xml 2.0'); } require_once 'PEAR/PackageFile/v1.php'; $pf = new PEAR_PackageFile_v1; $pf->setConfig($this->config); if ($pf2->getPackageType() != 'extsrc' && $pf2->getPackageType() != 'zendextsrc') { return $this->raiseError('Cannot safely convert "' . $packagexml . '", is not an extension source package. Using a PEAR_PackageFileManager-based ' . 'script is an option'); } if (is_array($pf2->getUsesRole())) { return $this->raiseError('Cannot safely convert "' . $packagexml . '", contains custom roles. Using a PEAR_PackageFileManager-based script or ' . 'the convert command is an option'); } if (is_array($pf2->getUsesTask())) { return $this->raiseError('Cannot safely convert "' . $packagexml . '", contains custom tasks. Using a PEAR_PackageFileManager-based script or ' . 'the convert command is an option'); } $deps = $pf2->getDependencies(); if (isset($deps['group'])) { return $this->raiseError('Cannot safely convert "' . $packagexml . '", contains dependency groups. Using a PEAR_PackageFileManager-based script ' . 'or the convert command is an option'); } if (isset($deps['required']['subpackage']) || isset($deps['optional']['subpackage'])) { return $this->raiseError('Cannot safely convert "' . $packagexml . '", contains subpackage dependencies. Using a PEAR_PackageFileManager-based '. 'script is an option'); } if (isset($deps['required']['os'])) { return $this->raiseError('Cannot safely convert "' . $packagexml . '", contains os dependencies. Using a PEAR_PackageFileManager-based '. 'script is an option'); } if (isset($deps['required']['arch'])) { return $this->raiseError('Cannot safely convert "' . $packagexml . '", contains arch dependencies. Using a PEAR_PackageFileManager-based '. 'script is an option'); } $pf->setPackage($pf2->getPackage()); $pf->setSummary($pf2->getSummary()); $pf->setDescription($pf2->getDescription()); foreach ($pf2->getMaintainers() as $maintainer) { $pf->addMaintainer($maintainer['role'], $maintainer['handle'], $maintainer['name'], $maintainer['email']); } $pf->setVersion($pf2->getVersion()); $pf->setDate($pf2->getDate()); $pf->setLicense($pf2->getLicense()); $pf->setState($pf2->getState()); $pf->setNotes($pf2->getNotes()); $pf->addPhpDep($deps['required']['php']['min'], 'ge'); if (isset($deps['required']['php']['max'])) { $pf->addPhpDep($deps['required']['php']['max'], 'le'); } if (isset($deps['required']['package'])) { if (!isset($deps['required']['package'][0])) { $deps['required']['package'] = array($deps['required']['package']); } foreach ($deps['required']['package'] as $dep) { if (!isset($dep['channel'])) { return $this->raiseError('Cannot safely convert "' . $packagexml . '"' . ' contains uri-based dependency on a package. Using a ' . 'PEAR_PackageFileManager-based script is an option'); } if ($dep['channel'] != 'pear.php.net' && $dep['channel'] != 'pecl.php.net' && $dep['channel'] != 'doc.php.net') { return $this->raiseError('Cannot safely convert "' . $packagexml . '"' . ' contains dependency on a non-standard channel package. Using a ' . 'PEAR_PackageFileManager-based script is an option'); } if (isset($dep['conflicts'])) { return $this->raiseError('Cannot safely convert "' . $packagexml . '"' . ' contains conflicts dependency. Using a ' . 'PEAR_PackageFileManager-based script is an option'); } if (isset($dep['exclude'])) { $this->ui->outputData('WARNING: exclude tags are ignored in conversion'); } if (isset($dep['min'])) { $pf->addPackageDep($dep['name'], $dep['min'], 'ge'); } if (isset($dep['max'])) { $pf->addPackageDep($dep['name'], $dep['max'], 'le'); } } } if (isset($deps['required']['extension'])) { if (!isset($deps['required']['extension'][0])) { $deps['required']['extension'] = array($deps['required']['extension']); } foreach ($deps['required']['extension'] as $dep) { if (isset($dep['conflicts'])) { return $this->raiseError('Cannot safely convert "' . $packagexml . '"' . ' contains conflicts dependency. Using a ' . 'PEAR_PackageFileManager-based script is an option'); } if (isset($dep['exclude'])) { $this->ui->outputData('WARNING: exclude tags are ignored in conversion'); } if (isset($dep['min'])) { $pf->addExtensionDep($dep['name'], $dep['min'], 'ge'); } if (isset($dep['max'])) { $pf->addExtensionDep($dep['name'], $dep['max'], 'le'); } } } if (isset($deps['optional']['package'])) { if (!isset($deps['optional']['package'][0])) { $deps['optional']['package'] = array($deps['optional']['package']); } foreach ($deps['optional']['package'] as $dep) { if (!isset($dep['channel'])) { return $this->raiseError('Cannot safely convert "' . $packagexml . '"' . ' contains uri-based dependency on a package. Using a ' . 'PEAR_PackageFileManager-based script is an option'); } if ($dep['channel'] != 'pear.php.net' && $dep['channel'] != 'pecl.php.net' && $dep['channel'] != 'doc.php.net') { return $this->raiseError('Cannot safely convert "' . $packagexml . '"' . ' contains dependency on a non-standard channel package. Using a ' . 'PEAR_PackageFileManager-based script is an option'); } if (isset($dep['exclude'])) { $this->ui->outputData('WARNING: exclude tags are ignored in conversion'); } if (isset($dep['min'])) { $pf->addPackageDep($dep['name'], $dep['min'], 'ge', 'yes'); } if (isset($dep['max'])) { $pf->addPackageDep($dep['name'], $dep['max'], 'le', 'yes'); } } } if (isset($deps['optional']['extension'])) { if (!isset($deps['optional']['extension'][0])) { $deps['optional']['extension'] = array($deps['optional']['extension']); } foreach ($deps['optional']['extension'] as $dep) { if (isset($dep['exclude'])) { $this->ui->outputData('WARNING: exclude tags are ignored in conversion'); } if (isset($dep['min'])) { $pf->addExtensionDep($dep['name'], $dep['min'], 'ge', 'yes'); } if (isset($dep['max'])) { $pf->addExtensionDep($dep['name'], $dep['max'], 'le', 'yes'); } } } $contents = $pf2->getContents(); $release = $pf2->getReleases(); if (isset($releases[0])) { return $this->raiseError('Cannot safely process "' . $packagexml . '" contains ' . 'multiple extsrcrelease/zendextsrcrelease tags. Using a PEAR_PackageFileManager-based script ' . 'or the convert command is an option'); } if ($configoptions = $pf2->getConfigureOptions()) { foreach ($configoptions as $option) { $default = isset($option['default']) ? $option['default'] : false; $pf->addConfigureOption($option['name'], $option['prompt'], $default); } } if (isset($release['filelist']['ignore'])) { return $this->raiseError('Cannot safely process "' . $packagexml . '" contains ' . 'ignore tags. Using a PEAR_PackageFileManager-based script or the convert' . ' command is an option'); } if (isset($release['filelist']['install']) && !isset($release['filelist']['install'][0])) { $release['filelist']['install'] = array($release['filelist']['install']); } if (isset($contents['dir']['attribs']['baseinstalldir'])) { $baseinstalldir = $contents['dir']['attribs']['baseinstalldir']; } else { $baseinstalldir = false; } if (!isset($contents['dir']['file'][0])) { $contents['dir']['file'] = array($contents['dir']['file']); } foreach ($contents['dir']['file'] as $file) { if ($baseinstalldir && !isset($file['attribs']['baseinstalldir'])) { $file['attribs']['baseinstalldir'] = $baseinstalldir; } $processFile = $file; unset($processFile['attribs']); if (count($processFile)) { foreach ($processFile as $name => $task) { if ($name != $pf2->getTasksNs() . ':replace') { return $this->raiseError('Cannot safely process "' . $packagexml . '" contains tasks other than replace. Using a ' . 'PEAR_PackageFileManager-based script is an option.'); } $file['attribs']['replace'][] = $task; } } if (!in_array($file['attribs']['role'], PEAR_Common::getFileRoles())) { return $this->raiseError('Cannot safely convert "' . $packagexml . '", contains custom roles. Using a PEAR_PackageFileManager-based script ' . 'or the convert command is an option'); } if (isset($release['filelist']['install'])) { foreach ($release['filelist']['install'] as $installas) { if ($installas['attribs']['name'] == $file['attribs']['name']) { $file['attribs']['install-as'] = $installas['attribs']['as']; } } } $pf->addFile('/', $file['attribs']['name'], $file['attribs']); } if ($pf2->getChangeLog()) { $this->ui->outputData('WARNING: changelog is not translated to package.xml ' . '1.0, use PEAR_PackageFileManager-based script if you need changelog-' . 'translation for package.xml 1.0'); } $gen = &$pf->getDefaultGenerator(); $gen->toPackageFile('.'); } } PKu]0(;rʹʹPEAR/Command/Registry.phpnu[ * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 0.1 */ /** * base class */ require_once 'PEAR/Command/Common.php'; /** * PEAR commands for registry manipulation * * @category pear * @package PEAR * @author Stig Bakken * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 0.1 */ class PEAR_Command_Registry extends PEAR_Command_Common { var $commands = array( 'list' => array( 'summary' => 'List Installed Packages In The Default Channel', 'function' => 'doList', 'shortcut' => 'l', 'options' => array( 'channel' => array( 'shortopt' => 'c', 'doc' => 'list installed packages from this channel', 'arg' => 'CHAN', ), 'allchannels' => array( 'shortopt' => 'a', 'doc' => 'list installed packages from all channels', ), 'channelinfo' => array( 'shortopt' => 'i', 'doc' => 'output fully channel-aware data, even on failure', ), ), 'doc' => ' If invoked without parameters, this command lists the PEAR packages installed in your php_dir ({config php_dir}). With a parameter, it lists the files in a package. ', ), 'list-files' => array( 'summary' => 'List Files In Installed Package', 'function' => 'doFileList', 'shortcut' => 'fl', 'options' => array(), 'doc' => ' List the files in an installed package. ' ), 'shell-test' => array( 'summary' => 'Shell Script Test', 'function' => 'doShellTest', 'shortcut' => 'st', 'options' => array(), 'doc' => ' [[relation] version] Tests if a package is installed in the system. Will exit(1) if it is not. The version comparison operator. One of: <, lt, <=, le, >, gt, >=, ge, ==, =, eq, !=, <>, ne The version to compare with '), 'info' => array( 'summary' => 'Display information about a package', 'function' => 'doInfo', 'shortcut' => 'in', 'options' => array(), 'doc' => ' Displays information about a package. The package argument may be a local package file, an URL to a package file, or the name of an installed package.' ) ); /** * PEAR_Command_Registry constructor. * * @access public */ function __construct(&$ui, &$config) { parent::__construct($ui, $config); } function _sortinfo($a, $b) { $apackage = isset($a['package']) ? $a['package'] : $a['name']; $bpackage = isset($b['package']) ? $b['package'] : $b['name']; return strcmp($apackage, $bpackage); } function doList($command, $options, $params) { $reg = &$this->config->getRegistry(); $channelinfo = isset($options['channelinfo']); if (isset($options['allchannels']) && !$channelinfo) { return $this->doListAll($command, array(), $params); } if (isset($options['allchannels']) && $channelinfo) { // allchannels with $channelinfo unset($options['allchannels']); $channels = $reg->getChannels(); $errors = array(); PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); foreach ($channels as $channel) { $options['channel'] = $channel->getName(); $ret = $this->doList($command, $options, $params); if (PEAR::isError($ret)) { $errors[] = $ret; } } PEAR::staticPopErrorHandling(); if (count($errors)) { // for now, only give first error return PEAR::raiseError($errors[0]); } return true; } if (count($params) === 1) { return $this->doFileList($command, $options, $params); } if (isset($options['channel'])) { if (!$reg->channelExists($options['channel'])) { return $this->raiseError('Channel "' . $options['channel'] .'" does not exist'); } $channel = $reg->channelName($options['channel']); } else { $channel = $this->config->get('default_channel'); } $installed = $reg->packageInfo(null, null, $channel); usort($installed, array(&$this, '_sortinfo')); $data = array( 'caption' => 'Installed packages, channel ' . $channel . ':', 'border' => true, 'headline' => array('Package', 'Version', 'State'), 'channel' => $channel, ); if ($channelinfo) { $data['headline'] = array('Channel', 'Package', 'Version', 'State'); } if (count($installed) && !isset($data['data'])) { $data['data'] = array(); } foreach ($installed as $package) { $pobj = $reg->getPackage(isset($package['package']) ? $package['package'] : $package['name'], $channel); if ($channelinfo) { $packageinfo = array($pobj->getChannel(), $pobj->getPackage(), $pobj->getVersion(), $pobj->getState() ? $pobj->getState() : null); } else { $packageinfo = array($pobj->getPackage(), $pobj->getVersion(), $pobj->getState() ? $pobj->getState() : null); } $data['data'][] = $packageinfo; } if (count($installed) === 0) { if (!$channelinfo) { $data = '(no packages installed from channel ' . $channel . ')'; } else { $data = array( 'caption' => 'Installed packages, channel ' . $channel . ':', 'border' => true, 'channel' => $channel, 'data' => array(array('(no packages installed)')), ); } } $this->ui->outputData($data, $command); return true; } function doListAll($command, $options, $params) { // This duplicate code is deprecated over // list --channelinfo, which gives identical // output for list and list --allchannels. $reg = &$this->config->getRegistry(); $installed = $reg->packageInfo(null, null, null); foreach ($installed as $channel => $packages) { usort($packages, array($this, '_sortinfo')); $data = array( 'caption' => 'Installed packages, channel ' . $channel . ':', 'border' => true, 'headline' => array('Package', 'Version', 'State'), 'channel' => $channel ); foreach ($packages as $package) { $p = isset($package['package']) ? $package['package'] : $package['name']; $pobj = $reg->getPackage($p, $channel); $data['data'][] = array($pobj->getPackage(), $pobj->getVersion(), $pobj->getState() ? $pobj->getState() : null); } // Adds a blank line after each section $data['data'][] = array(); if (count($packages) === 0) { $data = array( 'caption' => 'Installed packages, channel ' . $channel . ':', 'border' => true, 'data' => array(array('(no packages installed)'), array()), 'channel' => $channel ); } $this->ui->outputData($data, $command); } return true; } function doFileList($command, $options, $params) { if (count($params) !== 1) { return $this->raiseError('list-files expects 1 parameter'); } $reg = &$this->config->getRegistry(); $fp = false; if (!is_dir($params[0]) && (file_exists($params[0]) || $fp = @fopen($params[0], 'r'))) { if ($fp) { fclose($fp); } if (!class_exists('PEAR_PackageFile')) { require_once 'PEAR/PackageFile.php'; } $pkg = new PEAR_PackageFile($this->config, $this->_debug); PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); $info = &$pkg->fromAnyFile($params[0], PEAR_VALIDATE_NORMAL); PEAR::staticPopErrorHandling(); $headings = array('Package File', 'Install Path'); $installed = false; } else { PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); $parsed = $reg->parsePackageName($params[0], $this->config->get('default_channel')); PEAR::staticPopErrorHandling(); if (PEAR::isError($parsed)) { return $this->raiseError($parsed); } $info = &$reg->getPackage($parsed['package'], $parsed['channel']); $headings = array('Type', 'Install Path'); $installed = true; } if (PEAR::isError($info)) { return $this->raiseError($info); } if ($info === null) { return $this->raiseError("`$params[0]' not installed"); } $list = ($info->getPackagexmlVersion() == '1.0' || $installed) ? $info->getFilelist() : $info->getContents(); if ($installed) { $caption = 'Installed Files For ' . $params[0]; } else { $caption = 'Contents of ' . basename($params[0]); } $data = array( 'caption' => $caption, 'border' => true, 'headline' => $headings); if ($info->getPackagexmlVersion() == '1.0' || $installed) { foreach ($list as $file => $att) { if ($installed) { if (empty($att['installed_as'])) { continue; } $data['data'][] = array($att['role'], $att['installed_as']); } else { if (isset($att['baseinstalldir']) && !in_array($att['role'], array('test', 'data', 'doc'))) { $dest = $att['baseinstalldir'] . DIRECTORY_SEPARATOR . $file; } else { $dest = $file; } switch ($att['role']) { case 'test': case 'data': case 'doc': $role = $att['role']; if ($role == 'test') { $role .= 's'; } $dest = $this->config->get($role . '_dir') . DIRECTORY_SEPARATOR . $info->getPackage() . DIRECTORY_SEPARATOR . $dest; break; case 'php': default: $dest = $this->config->get('php_dir') . DIRECTORY_SEPARATOR . $dest; } $ds2 = DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR; $dest = preg_replace(array('!\\\\+!', '!/!', "!$ds2+!"), array(DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR), $dest); $file = preg_replace('!/+!', '/', $file); $data['data'][] = array($file, $dest); } } } else { // package.xml 2.0, not installed if (!isset($list['dir']['file'][0])) { $list['dir']['file'] = array($list['dir']['file']); } foreach ($list['dir']['file'] as $att) { $att = $att['attribs']; $file = $att['name']; $role = &PEAR_Installer_Role::factory($info, $att['role'], $this->config); $role->setup($this, $info, $att, $file); if (!$role->isInstallable()) { $dest = '(not installable)'; } else { $dest = $role->processInstallation($info, $att, $file, ''); if (PEAR::isError($dest)) { $dest = '(Unknown role "' . $att['role'] . ')'; } else { list(,, $dest) = $dest; } } $data['data'][] = array($file, $dest); } } $this->ui->outputData($data, $command); return true; } function doShellTest($command, $options, $params) { if (count($params) < 1) { return PEAR::raiseError('ERROR, usage: pear shell-test packagename [[relation] version]'); } PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); $reg = &$this->config->getRegistry(); $info = $reg->parsePackageName($params[0], $this->config->get('default_channel')); if (PEAR::isError($info)) { exit(1); // invalid package name } $package = $info['package']; $channel = $info['channel']; // "pear shell-test Foo" if (!$reg->packageExists($package, $channel)) { if ($channel == 'pecl.php.net') { if ($reg->packageExists($package, 'pear.php.net')) { $channel = 'pear.php.net'; // magically change channels for extensions } } } if (count($params) === 1) { if (!$reg->packageExists($package, $channel)) { exit(1); } // "pear shell-test Foo 1.0" } elseif (count($params) === 2) { $v = $reg->packageInfo($package, 'version', $channel); if (!$v || !version_compare("$v", "{$params[1]}", "ge")) { exit(1); } // "pear shell-test Foo ge 1.0" } elseif (count($params) === 3) { $v = $reg->packageInfo($package, 'version', $channel); if (!$v || !version_compare("$v", "{$params[2]}", $params[1])) { exit(1); } } else { PEAR::staticPopErrorHandling(); $this->raiseError("$command: expects 1 to 3 parameters"); exit(1); } } function doInfo($command, $options, $params) { if (count($params) !== 1) { return $this->raiseError('pear info expects 1 parameter'); } $info = $fp = false; $reg = &$this->config->getRegistry(); if (is_file($params[0]) && !is_dir($params[0]) && (file_exists($params[0]) || $fp = @fopen($params[0], 'r')) ) { if ($fp) { fclose($fp); } if (!class_exists('PEAR_PackageFile')) { require_once 'PEAR/PackageFile.php'; } $pkg = new PEAR_PackageFile($this->config, $this->_debug); PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); $obj = &$pkg->fromAnyFile($params[0], PEAR_VALIDATE_NORMAL); PEAR::staticPopErrorHandling(); if (PEAR::isError($obj)) { $uinfo = $obj->getUserInfo(); if (is_array($uinfo)) { foreach ($uinfo as $message) { if (is_array($message)) { $message = $message['message']; } $this->ui->outputData($message); } } return $this->raiseError($obj); } if ($obj->getPackagexmlVersion() != '1.0') { return $this->_doInfo2($command, $options, $params, $obj, false); } $info = $obj->toArray(); } else { $parsed = $reg->parsePackageName($params[0], $this->config->get('default_channel')); if (PEAR::isError($parsed)) { return $this->raiseError($parsed); } $package = $parsed['package']; $channel = $parsed['channel']; $info = $reg->packageInfo($package, null, $channel); if (isset($info['old'])) { $obj = $reg->getPackage($package, $channel); return $this->_doInfo2($command, $options, $params, $obj, true); } } if (PEAR::isError($info)) { return $info; } if (empty($info)) { $this->raiseError("No information found for `$params[0]'"); return; } unset($info['filelist']); unset($info['dirtree']); unset($info['changelog']); if (isset($info['xsdversion'])) { $info['package.xml version'] = $info['xsdversion']; unset($info['xsdversion']); } if (isset($info['packagerversion'])) { $info['packaged with PEAR version'] = $info['packagerversion']; unset($info['packagerversion']); } $keys = array_keys($info); $longtext = array('description', 'summary'); foreach ($keys as $key) { if (is_array($info[$key])) { switch ($key) { case 'maintainers': { $i = 0; $mstr = ''; foreach ($info[$key] as $m) { if ($i++ > 0) { $mstr .= "\n"; } $mstr .= $m['name'] . " <"; if (isset($m['email'])) { $mstr .= $m['email']; } else { $mstr .= $m['handle'] . '@php.net'; } $mstr .= "> ($m[role])"; } $info[$key] = $mstr; break; } case 'release_deps': { $i = 0; $dstr = ''; foreach ($info[$key] as $d) { if (isset($this->_deps_rel_trans[$d['rel']])) { $rel = $this->_deps_rel_trans[$d['rel']]; } else { $rel = $d['rel']; } if (isset($this->_deps_type_trans[$d['type']])) { $type = ucfirst($this->_deps_type_trans[$d['type']]); } else { $type = $d['type']; } if (isset($d['name'])) { $name = $d['name'] . ' '; } else { $name = ''; } if (isset($d['version'])) { $version = $d['version'] . ' '; } else { $version = ''; } if (isset($d['optional']) && $d['optional'] == 'yes') { $optional = ' (optional)'; } else { $optional = ''; } $dstr .= "$type $name$rel $version$optional\n"; } $info[$key] = $dstr; break; } case 'provides' : { $debug = $this->config->get('verbose'); if ($debug < 2) { $pstr = 'Classes: '; } else { $pstr = ''; } $i = 0; foreach ($info[$key] as $p) { if ($debug < 2 && $p['type'] != "class") { continue; } // Only print classes when verbosity mode is < 2 if ($debug < 2) { if ($i++ > 0) { $pstr .= ", "; } $pstr .= $p['name']; } else { if ($i++ > 0) { $pstr .= "\n"; } $pstr .= ucfirst($p['type']) . " " . $p['name']; if (isset($p['explicit']) && $p['explicit'] == 1) { $pstr .= " (explicit)"; } } } $info[$key] = $pstr; break; } case 'configure_options' : { foreach ($info[$key] as $i => $p) { $info[$key][$i] = array_map(null, array_keys($p), array_values($p)); $info[$key][$i] = array_map( function($a) { return join(" = ", $a); }, $info[$key][$i]); $info[$key][$i] = implode(', ', $info[$key][$i]); } $info[$key] = implode("\n", $info[$key]); break; } default: { $info[$key] = implode(", ", $info[$key]); break; } } } if ($key == '_lastmodified') { $hdate = date('Y-m-d', $info[$key]); unset($info[$key]); $info['Last Modified'] = $hdate; } elseif ($key == '_lastversion') { $info['Previous Installed Version'] = $info[$key] ? $info[$key] : '- None -'; unset($info[$key]); } else { $info[$key] = trim($info[$key]); if (in_array($key, $longtext)) { $info[$key] = preg_replace('/ +/', ' ', $info[$key]); } } } $caption = 'About ' . $info['package'] . '-' . $info['version']; $data = array( 'caption' => $caption, 'border' => true); foreach ($info as $key => $value) { $key = ucwords(trim(str_replace('_', ' ', $key))); $data['data'][] = array($key, $value); } $data['raw'] = $info; $this->ui->outputData($data, 'package-info'); } /** * @access private */ function _doInfo2($command, $options, $params, &$obj, $installed) { $reg = &$this->config->getRegistry(); $caption = 'About ' . $obj->getChannel() . '/' .$obj->getPackage() . '-' . $obj->getVersion(); $data = array( 'caption' => $caption, 'border' => true); switch ($obj->getPackageType()) { case 'php' : $release = 'PEAR-style PHP-based Package'; break; case 'extsrc' : $release = 'PECL-style PHP extension (source code)'; break; case 'zendextsrc' : $release = 'PECL-style Zend extension (source code)'; break; case 'extbin' : $release = 'PECL-style PHP extension (binary)'; break; case 'zendextbin' : $release = 'PECL-style Zend extension (binary)'; break; case 'bundle' : $release = 'Package bundle (collection of packages)'; break; } $extends = $obj->getExtends(); $extends = $extends ? $obj->getPackage() . ' (extends ' . $extends . ')' : $obj->getPackage(); if ($src = $obj->getSourcePackage()) { $extends .= ' (source package ' . $src['channel'] . '/' . $src['package'] . ')'; } $info = array( 'Release Type' => $release, 'Name' => $extends, 'Channel' => $obj->getChannel(), 'Summary' => preg_replace('/ +/', ' ', $obj->getSummary()), 'Description' => preg_replace('/ +/', ' ', $obj->getDescription()), ); $info['Maintainers'] = ''; foreach (array('lead', 'developer', 'contributor', 'helper') as $role) { $leads = $obj->{"get{$role}s"}(); if (!$leads) { continue; } if (isset($leads['active'])) { $leads = array($leads); } foreach ($leads as $lead) { if (!empty($info['Maintainers'])) { $info['Maintainers'] .= "\n"; } $active = $lead['active'] == 'no' ? ', inactive' : ''; $info['Maintainers'] .= $lead['name'] . ' <'; $info['Maintainers'] .= $lead['email'] . "> ($role$active)"; } } $info['Release Date'] = $obj->getDate(); if ($time = $obj->getTime()) { $info['Release Date'] .= ' ' . $time; } $info['Release Version'] = $obj->getVersion() . ' (' . $obj->getState() . ')'; $info['API Version'] = $obj->getVersion('api') . ' (' . $obj->getState('api') . ')'; $info['License'] = $obj->getLicense(); $uri = $obj->getLicenseLocation(); if ($uri) { if (isset($uri['uri'])) { $info['License'] .= ' (' . $uri['uri'] . ')'; } else { $extra = $obj->getInstalledLocation($info['filesource']); if ($extra) { $info['License'] .= ' (' . $uri['filesource'] . ')'; } } } $info['Release Notes'] = $obj->getNotes(); if ($compat = $obj->getCompatible()) { if (!isset($compat[0])) { $compat = array($compat); } $info['Compatible with'] = ''; foreach ($compat as $package) { $info['Compatible with'] .= $package['channel'] . '/' . $package['name'] . "\nVersions >= " . $package['min'] . ', <= ' . $package['max']; if (isset($package['exclude'])) { if (is_array($package['exclude'])) { $package['exclude'] = implode(', ', $package['exclude']); } if (!isset($info['Not Compatible with'])) { $info['Not Compatible with'] = ''; } else { $info['Not Compatible with'] .= "\n"; } $info['Not Compatible with'] .= $package['channel'] . '/' . $package['name'] . "\nVersions " . $package['exclude']; } } } $usesrole = $obj->getUsesrole(); if ($usesrole) { if (!isset($usesrole[0])) { $usesrole = array($usesrole); } foreach ($usesrole as $roledata) { if (isset($info['Uses Custom Roles'])) { $info['Uses Custom Roles'] .= "\n"; } else { $info['Uses Custom Roles'] = ''; } if (isset($roledata['package'])) { $rolepackage = $reg->parsedPackageNameToString($roledata, true); } else { $rolepackage = $roledata['uri']; } $info['Uses Custom Roles'] .= $roledata['role'] . ' (' . $rolepackage . ')'; } } $usestask = $obj->getUsestask(); if ($usestask) { if (!isset($usestask[0])) { $usestask = array($usestask); } foreach ($usestask as $taskdata) { if (isset($info['Uses Custom Tasks'])) { $info['Uses Custom Tasks'] .= "\n"; } else { $info['Uses Custom Tasks'] = ''; } if (isset($taskdata['package'])) { $taskpackage = $reg->parsedPackageNameToString($taskdata, true); } else { $taskpackage = $taskdata['uri']; } $info['Uses Custom Tasks'] .= $taskdata['task'] . ' (' . $taskpackage . ')'; } } $deps = $obj->getDependencies(); $info['Required Dependencies'] = 'PHP version ' . $deps['required']['php']['min']; if (isset($deps['required']['php']['max'])) { $info['Required Dependencies'] .= '-' . $deps['required']['php']['max'] . "\n"; } else { $info['Required Dependencies'] .= "\n"; } if (isset($deps['required']['php']['exclude'])) { if (!isset($info['Not Compatible with'])) { $info['Not Compatible with'] = ''; } else { $info['Not Compatible with'] .= "\n"; } if (is_array($deps['required']['php']['exclude'])) { $deps['required']['php']['exclude'] = implode(', ', $deps['required']['php']['exclude']); } $info['Not Compatible with'] .= "PHP versions\n " . $deps['required']['php']['exclude']; } $info['Required Dependencies'] .= 'PEAR installer version'; if (isset($deps['required']['pearinstaller']['max'])) { $info['Required Dependencies'] .= 's ' . $deps['required']['pearinstaller']['min'] . '-' . $deps['required']['pearinstaller']['max']; } else { $info['Required Dependencies'] .= ' ' . $deps['required']['pearinstaller']['min'] . ' or newer'; } if (isset($deps['required']['pearinstaller']['exclude'])) { if (!isset($info['Not Compatible with'])) { $info['Not Compatible with'] = ''; } else { $info['Not Compatible with'] .= "\n"; } if (is_array($deps['required']['pearinstaller']['exclude'])) { $deps['required']['pearinstaller']['exclude'] = implode(', ', $deps['required']['pearinstaller']['exclude']); } $info['Not Compatible with'] .= "PEAR installer\n Versions " . $deps['required']['pearinstaller']['exclude']; } foreach (array('Package', 'Extension') as $type) { $index = strtolower($type); if (isset($deps['required'][$index])) { if (isset($deps['required'][$index]['name'])) { $deps['required'][$index] = array($deps['required'][$index]); } foreach ($deps['required'][$index] as $package) { if (isset($package['conflicts'])) { $infoindex = 'Not Compatible with'; if (!isset($info['Not Compatible with'])) { $info['Not Compatible with'] = ''; } else { $info['Not Compatible with'] .= "\n"; } } else { $infoindex = 'Required Dependencies'; $info[$infoindex] .= "\n"; } if ($index == 'extension') { $name = $package['name']; } else { if (isset($package['channel'])) { $name = $package['channel'] . '/' . $package['name']; } else { $name = '__uri/' . $package['name'] . ' (static URI)'; } } $info[$infoindex] .= "$type $name"; if (isset($package['uri'])) { $info[$infoindex] .= "\n Download URI: $package[uri]"; continue; } if (isset($package['max']) && isset($package['min'])) { $info[$infoindex] .= " \n Versions " . $package['min'] . '-' . $package['max']; } elseif (isset($package['min'])) { $info[$infoindex] .= " \n Version " . $package['min'] . ' or newer'; } elseif (isset($package['max'])) { $info[$infoindex] .= " \n Version " . $package['max'] . ' or older'; } if (isset($package['recommended'])) { $info[$infoindex] .= "\n Recommended version: $package[recommended]"; } if (isset($package['exclude'])) { if (!isset($info['Not Compatible with'])) { $info['Not Compatible with'] = ''; } else { $info['Not Compatible with'] .= "\n"; } if (is_array($package['exclude'])) { $package['exclude'] = implode(', ', $package['exclude']); } $package['package'] = $package['name']; // for parsedPackageNameToString if (isset($package['conflicts'])) { $info['Not Compatible with'] .= '=> except '; } $info['Not Compatible with'] .= 'Package ' . $reg->parsedPackageNameToString($package, true); $info['Not Compatible with'] .= "\n Versions " . $package['exclude']; } } } } if (isset($deps['required']['os'])) { if (isset($deps['required']['os']['name'])) { $dep['required']['os']['name'] = array($dep['required']['os']['name']); } foreach ($dep['required']['os'] as $os) { if (isset($os['conflicts']) && $os['conflicts'] == 'yes') { if (!isset($info['Not Compatible with'])) { $info['Not Compatible with'] = ''; } else { $info['Not Compatible with'] .= "\n"; } $info['Not Compatible with'] .= "$os[name] Operating System"; } else { $info['Required Dependencies'] .= "\n"; $info['Required Dependencies'] .= "$os[name] Operating System"; } } } if (isset($deps['required']['arch'])) { if (isset($deps['required']['arch']['pattern'])) { $dep['required']['arch']['pattern'] = array($dep['required']['os']['pattern']); } foreach ($dep['required']['arch'] as $os) { if (isset($os['conflicts']) && $os['conflicts'] == 'yes') { if (!isset($info['Not Compatible with'])) { $info['Not Compatible with'] = ''; } else { $info['Not Compatible with'] .= "\n"; } $info['Not Compatible with'] .= "OS/Arch matching pattern '/$os[pattern]/'"; } else { $info['Required Dependencies'] .= "\n"; $info['Required Dependencies'] .= "OS/Arch matching pattern '/$os[pattern]/'"; } } } if (isset($deps['optional'])) { foreach (array('Package', 'Extension') as $type) { $index = strtolower($type); if (isset($deps['optional'][$index])) { if (isset($deps['optional'][$index]['name'])) { $deps['optional'][$index] = array($deps['optional'][$index]); } foreach ($deps['optional'][$index] as $package) { if (isset($package['conflicts']) && $package['conflicts'] == 'yes') { $infoindex = 'Not Compatible with'; if (!isset($info['Not Compatible with'])) { $info['Not Compatible with'] = ''; } else { $info['Not Compatible with'] .= "\n"; } } else { $infoindex = 'Optional Dependencies'; if (!isset($info['Optional Dependencies'])) { $info['Optional Dependencies'] = ''; } else { $info['Optional Dependencies'] .= "\n"; } } if ($index == 'extension') { $name = $package['name']; } else { if (isset($package['channel'])) { $name = $package['channel'] . '/' . $package['name']; } else { $name = '__uri/' . $package['name'] . ' (static URI)'; } } $info[$infoindex] .= "$type $name"; if (isset($package['uri'])) { $info[$infoindex] .= "\n Download URI: $package[uri]"; continue; } if ($infoindex == 'Not Compatible with') { // conflicts is only used to say that all versions conflict continue; } if (isset($package['max']) && isset($package['min'])) { $info[$infoindex] .= " \n Versions " . $package['min'] . '-' . $package['max']; } elseif (isset($package['min'])) { $info[$infoindex] .= " \n Version " . $package['min'] . ' or newer'; } elseif (isset($package['max'])) { $info[$infoindex] .= " \n Version " . $package['min'] . ' or older'; } if (isset($package['recommended'])) { $info[$infoindex] .= "\n Recommended version: $package[recommended]"; } if (isset($package['exclude'])) { if (!isset($info['Not Compatible with'])) { $info['Not Compatible with'] = ''; } else { $info['Not Compatible with'] .= "\n"; } if (is_array($package['exclude'])) { $package['exclude'] = implode(', ', $package['exclude']); } $info['Not Compatible with'] .= "Package $package\n Versions " . $package['exclude']; } } } } } if (isset($deps['group'])) { if (!isset($deps['group'][0])) { $deps['group'] = array($deps['group']); } foreach ($deps['group'] as $group) { $info['Dependency Group ' . $group['attribs']['name']] = $group['attribs']['hint']; $groupindex = $group['attribs']['name'] . ' Contents'; $info[$groupindex] = ''; foreach (array('Package', 'Extension') as $type) { $index = strtolower($type); if (isset($group[$index])) { if (isset($group[$index]['name'])) { $group[$index] = array($group[$index]); } foreach ($group[$index] as $package) { if (!empty($info[$groupindex])) { $info[$groupindex] .= "\n"; } if ($index == 'extension') { $name = $package['name']; } else { if (isset($package['channel'])) { $name = $package['channel'] . '/' . $package['name']; } else { $name = '__uri/' . $package['name'] . ' (static URI)'; } } if (isset($package['uri'])) { if (isset($package['conflicts']) && $package['conflicts'] == 'yes') { $info[$groupindex] .= "Not Compatible with $type $name"; } else { $info[$groupindex] .= "$type $name"; } $info[$groupindex] .= "\n Download URI: $package[uri]"; continue; } if (isset($package['conflicts']) && $package['conflicts'] == 'yes') { $info[$groupindex] .= "Not Compatible with $type $name"; continue; } $info[$groupindex] .= "$type $name"; if (isset($package['max']) && isset($package['min'])) { $info[$groupindex] .= " \n Versions " . $package['min'] . '-' . $package['max']; } elseif (isset($package['min'])) { $info[$groupindex] .= " \n Version " . $package['min'] . ' or newer'; } elseif (isset($package['max'])) { $info[$groupindex] .= " \n Version " . $package['min'] . ' or older'; } if (isset($package['recommended'])) { $info[$groupindex] .= "\n Recommended version: $package[recommended]"; } if (isset($package['exclude'])) { if (!isset($info['Not Compatible with'])) { $info['Not Compatible with'] = ''; } else { $info[$groupindex] .= "Not Compatible with\n"; } if (is_array($package['exclude'])) { $package['exclude'] = implode(', ', $package['exclude']); } $info[$groupindex] .= " Package $package\n Versions " . $package['exclude']; } } } } } } if ($obj->getPackageType() == 'bundle') { $info['Bundled Packages'] = ''; foreach ($obj->getBundledPackages() as $package) { if (!empty($info['Bundled Packages'])) { $info['Bundled Packages'] .= "\n"; } if (isset($package['uri'])) { $info['Bundled Packages'] .= '__uri/' . $package['name']; $info['Bundled Packages'] .= "\n (URI: $package[uri]"; } else { $info['Bundled Packages'] .= $package['channel'] . '/' . $package['name']; } } } $info['package.xml version'] = '2.0'; if ($installed) { if ($obj->getLastModified()) { $info['Last Modified'] = date('Y-m-d H:i', $obj->getLastModified()); } $v = $obj->getLastInstalledVersion(); $info['Previous Installed Version'] = $v ? $v : '- None -'; } foreach ($info as $key => $value) { $data['data'][] = array($key, $value); } $data['raw'] = $obj->getArray(); // no validation needed $this->ui->outputData($data, 'package-info'); } } PKu]݄ Downloads each available package from the default channel doDownloadAll da c specify a channel other than the default channel CHAN Requests a list of available packages from the default channel ({config default_channel}) and downloads them to current working directory. Note: only packages within preferred_state ({config preferred_state}) will be downloaded PKu]%qPEAR/Command/Channels.phpnu[ * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ /** * base class */ require_once 'PEAR/Command/Common.php'; define('PEAR_COMMAND_CHANNELS_CHANNEL_EXISTS', -500); /** * PEAR commands for managing channels. * * @category pear * @package PEAR * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ class PEAR_Command_Channels extends PEAR_Command_Common { var $commands = array( 'list-channels' => array( 'summary' => 'List Available Channels', 'function' => 'doList', 'shortcut' => 'lc', 'options' => array(), 'doc' => ' List all available channels for installation. ', ), 'update-channels' => array( 'summary' => 'Update the Channel List', 'function' => 'doUpdateAll', 'shortcut' => 'uc', 'options' => array(), 'doc' => ' List all installed packages in all channels. ' ), 'channel-delete' => array( 'summary' => 'Remove a Channel From the List', 'function' => 'doDelete', 'shortcut' => 'cde', 'options' => array(), 'doc' => ' Delete a channel from the registry. You may not remove any channel that has installed packages. ' ), 'channel-add' => array( 'summary' => 'Add a Channel', 'function' => 'doAdd', 'shortcut' => 'ca', 'options' => array(), 'doc' => ' Add a private channel to the channel list. Note that all public channels should be synced using "update-channels". Parameter may be either a local file or remote URL to a channel.xml. ' ), 'channel-update' => array( 'summary' => 'Update an Existing Channel', 'function' => 'doUpdate', 'shortcut' => 'cu', 'options' => array( 'force' => array( 'shortopt' => 'f', 'doc' => 'will force download of new channel.xml if an existing channel name is used', ), 'channel' => array( 'shortopt' => 'c', 'arg' => 'CHANNEL', 'doc' => 'will force download of new channel.xml if an existing channel name is used', ), ), 'doc' => '[|] Update a channel in the channel list directly. Note that all public channels can be synced using "update-channels". Parameter may be a local or remote channel.xml, or the name of an existing channel. ' ), 'channel-info' => array( 'summary' => 'Retrieve Information on a Channel', 'function' => 'doInfo', 'shortcut' => 'ci', 'options' => array(), 'doc' => ' List the files in an installed package. ' ), 'channel-alias' => array( 'summary' => 'Specify an alias to a channel name', 'function' => 'doAlias', 'shortcut' => 'cha', 'options' => array(), 'doc' => ' Specify a specific alias to use for a channel name. The alias may not be an existing channel name or alias. ' ), 'channel-discover' => array( 'summary' => 'Initialize a Channel from its server', 'function' => 'doDiscover', 'shortcut' => 'di', 'options' => array(), 'doc' => '[|] Initialize a channel from its server and create a local channel.xml. If is in the format ":@" then and will be set as the login username/password for . Use caution when passing the username/password in this way, as it may allow other users on your computer to briefly view your username/ password via the system\'s process list. ' ), 'channel-login' => array( 'summary' => 'Connects and authenticates to remote channel server', 'shortcut' => 'cli', 'function' => 'doLogin', 'options' => array(), 'doc' => ' Log in to a remote channel server. If is not supplied, the default channel is used. To use remote functions in the installer that require any kind of privileges, you need to log in first. The username and password you enter here will be stored in your per-user PEAR configuration (~/.pearrc on Unix-like systems). After logging in, your username and password will be sent along in subsequent operations on the remote server.', ), 'channel-logout' => array( 'summary' => 'Logs out from the remote channel server', 'shortcut' => 'clo', 'function' => 'doLogout', 'options' => array(), 'doc' => ' Logs out from a remote channel server. If is not supplied, the default channel is used. This command does not actually connect to the remote server, it only deletes the stored username and password from your user configuration.', ), ); /** * PEAR_Command_Registry constructor. * * @access public */ function __construct(&$ui, &$config) { parent::__construct($ui, $config); } function _sortChannels($a, $b) { return strnatcasecmp($a->getName(), $b->getName()); } function doList($command, $options, $params) { $reg = &$this->config->getRegistry(); $registered = $reg->getChannels(); usort($registered, array(&$this, '_sortchannels')); $i = $j = 0; $data = array( 'caption' => 'Registered Channels:', 'border' => true, 'headline' => array('Channel', 'Alias', 'Summary') ); foreach ($registered as $channel) { $data['data'][] = array($channel->getName(), $channel->getAlias(), $channel->getSummary()); } if (count($registered) === 0) { $data = '(no registered channels)'; } $this->ui->outputData($data, $command); return true; } function doUpdateAll($command, $options, $params) { $reg = &$this->config->getRegistry(); $channels = $reg->getChannels(); $success = true; foreach ($channels as $channel) { if ($channel->getName() != '__uri') { PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); $err = $this->doUpdate('channel-update', $options, array($channel->getName())); if (PEAR::isError($err)) { $this->ui->outputData($err->getMessage(), $command); $success = false; } else { $success &= $err; } } } return $success; } function doInfo($command, $options, $params) { if (count($params) !== 1) { return $this->raiseError("No channel specified"); } $reg = &$this->config->getRegistry(); $channel = strtolower($params[0]); if ($reg->channelExists($channel)) { $chan = $reg->getChannel($channel); if (PEAR::isError($chan)) { return $this->raiseError($chan); } } else { if (strpos($channel, '://')) { $downloader = &$this->getDownloader(); $tmpdir = $this->config->get('temp_dir'); PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); $loc = $downloader->downloadHttp($channel, $this->ui, $tmpdir); PEAR::staticPopErrorHandling(); if (PEAR::isError($loc)) { return $this->raiseError('Cannot open "' . $channel . '" (' . $loc->getMessage() . ')'); } else { $contents = implode('', file($loc)); } } else { if (!file_exists($params[0])) { return $this->raiseError('Unknown channel "' . $channel . '"'); } $fp = fopen($params[0], 'r'); if (!$fp) { return $this->raiseError('Cannot open "' . $params[0] . '"'); } $contents = ''; while (!feof($fp)) { $contents .= fread($fp, 1024); } fclose($fp); } if (!class_exists('PEAR_ChannelFile')) { require_once 'PEAR/ChannelFile.php'; } $chan = new PEAR_ChannelFile; $chan->fromXmlString($contents); $chan->validate(); if ($errs = $chan->getErrors(true)) { foreach ($errs as $err) { $this->ui->outputData($err['level'] . ': ' . $err['message']); } return $this->raiseError('Channel file "' . $params[0] . '" is not valid'); } } if (!$chan) { return $this->raiseError('Serious error: Channel "' . $params[0] . '" has a corrupted registry entry'); } $channel = $chan->getName(); $caption = 'Channel ' . $channel . ' Information:'; $data1 = array( 'caption' => $caption, 'border' => true); $data1['data']['server'] = array('Name and Server', $chan->getName()); if ($chan->getAlias() != $chan->getName()) { $data1['data']['alias'] = array('Alias', $chan->getAlias()); } $data1['data']['summary'] = array('Summary', $chan->getSummary()); $validate = $chan->getValidationPackage(); $data1['data']['vpackage'] = array('Validation Package Name', $validate['_content']); $data1['data']['vpackageversion'] = array('Validation Package Version', $validate['attribs']['version']); $d = array(); $d['main'] = $data1; $data['data'] = array(); $data['caption'] = 'Server Capabilities'; $data['headline'] = array('Type', 'Version/REST type', 'Function Name/REST base'); if ($chan->supportsREST()) { if ($chan->supportsREST()) { $funcs = $chan->getFunctions('rest'); if (!isset($funcs[0])) { $funcs = array($funcs); } foreach ($funcs as $protocol) { $data['data'][] = array('rest', $protocol['attribs']['type'], $protocol['_content']); } } } else { $data['data'][] = array('No supported protocols'); } $d['protocols'] = $data; $data['data'] = array(); $mirrors = $chan->getMirrors(); if ($mirrors) { $data['caption'] = 'Channel ' . $channel . ' Mirrors:'; unset($data['headline']); foreach ($mirrors as $mirror) { $data['data'][] = array($mirror['attribs']['host']); $d['mirrors'] = $data; } foreach ($mirrors as $i => $mirror) { $data['data'] = array(); $data['caption'] = 'Mirror ' . $mirror['attribs']['host'] . ' Capabilities'; $data['headline'] = array('Type', 'Version/REST type', 'Function Name/REST base'); if ($chan->supportsREST($mirror['attribs']['host'])) { if ($chan->supportsREST($mirror['attribs']['host'])) { $funcs = $chan->getFunctions('rest', $mirror['attribs']['host']); if (!isset($funcs[0])) { $funcs = array($funcs); } foreach ($funcs as $protocol) { $data['data'][] = array('rest', $protocol['attribs']['type'], $protocol['_content']); } } } else { $data['data'][] = array('No supported protocols'); } $d['mirrorprotocols' . $i] = $data; } } $this->ui->outputData($d, 'channel-info'); } // }}} function doDelete($command, $options, $params) { if (count($params) !== 1) { return $this->raiseError('channel-delete: no channel specified'); } $reg = &$this->config->getRegistry(); if (!$reg->channelExists($params[0])) { return $this->raiseError('channel-delete: channel "' . $params[0] . '" does not exist'); } $channel = $reg->channelName($params[0]); if ($channel == 'pear.php.net') { return $this->raiseError('Cannot delete the pear.php.net channel'); } if ($channel == 'pecl.php.net') { return $this->raiseError('Cannot delete the pecl.php.net channel'); } if ($channel == 'doc.php.net') { return $this->raiseError('Cannot delete the doc.php.net channel'); } if ($channel == '__uri') { return $this->raiseError('Cannot delete the __uri pseudo-channel'); } if (PEAR::isError($err = $reg->listPackages($channel))) { return $err; } if (count($err)) { return $this->raiseError('Channel "' . $channel . '" has installed packages, cannot delete'); } if (!$reg->deleteChannel($channel)) { return $this->raiseError('Channel "' . $channel . '" deletion failed'); } else { $this->config->deleteChannel($channel); $this->ui->outputData('Channel "' . $channel . '" deleted', $command); } } function doAdd($command, $options, $params) { if (count($params) !== 1) { return $this->raiseError('channel-add: no channel file specified'); } if (strpos($params[0], '://')) { $downloader = &$this->getDownloader(); $tmpdir = $this->config->get('temp_dir'); if (!file_exists($tmpdir)) { require_once 'System.php'; PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); $err = System::mkdir(array('-p', $tmpdir)); PEAR::staticPopErrorHandling(); if (PEAR::isError($err)) { return $this->raiseError('channel-add: temp_dir does not exist: "' . $tmpdir . '" - You can change this location with "pear config-set temp_dir"'); } } if (!is_writable($tmpdir)) { return $this->raiseError('channel-add: temp_dir is not writable: "' . $tmpdir . '" - You can change this location with "pear config-set temp_dir"'); } PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); $loc = $downloader->downloadHttp($params[0], $this->ui, $tmpdir, null, false); PEAR::staticPopErrorHandling(); if (PEAR::isError($loc)) { return $this->raiseError('channel-add: Cannot open "' . $params[0] . '" (' . $loc->getMessage() . ')'); } list($loc, $lastmodified) = $loc; $contents = implode('', file($loc)); } else { $lastmodified = $fp = false; if (file_exists($params[0])) { $fp = fopen($params[0], 'r'); } if (!$fp) { return $this->raiseError('channel-add: cannot open "' . $params[0] . '"'); } $contents = ''; while (!feof($fp)) { $contents .= fread($fp, 1024); } fclose($fp); } if (!class_exists('PEAR_ChannelFile')) { require_once 'PEAR/ChannelFile.php'; } $channel = new PEAR_ChannelFile; PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); $result = $channel->fromXmlString($contents); PEAR::staticPopErrorHandling(); if (!$result) { $exit = false; if (count($errors = $channel->getErrors(true))) { foreach ($errors as $error) { $this->ui->outputData(ucfirst($error['level'] . ': ' . $error['message'])); if (!$exit) { $exit = $error['level'] == 'error' ? true : false; } } if ($exit) { return $this->raiseError('channel-add: invalid channel.xml file'); } } } $reg = &$this->config->getRegistry(); if ($reg->channelExists($channel->getName())) { return $this->raiseError('channel-add: Channel "' . $channel->getName() . '" exists, use channel-update to update entry', PEAR_COMMAND_CHANNELS_CHANNEL_EXISTS); } $ret = $reg->addChannel($channel, $lastmodified); if (PEAR::isError($ret)) { return $ret; } if (!$ret) { return $this->raiseError('channel-add: adding Channel "' . $channel->getName() . '" to registry failed'); } $this->config->setChannels($reg->listChannels()); $this->config->writeConfigFile(); $this->ui->outputData('Adding Channel "' . $channel->getName() . '" succeeded', $command); } function doUpdate($command, $options, $params) { if (count($params) !== 1) { return $this->raiseError("No channel file specified"); } $tmpdir = $this->config->get('temp_dir'); if (!file_exists($tmpdir)) { require_once 'System.php'; PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); $err = System::mkdir(array('-p', $tmpdir)); PEAR::staticPopErrorHandling(); if (PEAR::isError($err)) { return $this->raiseError('channel-add: temp_dir does not exist: "' . $tmpdir . '" - You can change this location with "pear config-set temp_dir"'); } } if (!is_writable($tmpdir)) { return $this->raiseError('channel-add: temp_dir is not writable: "' . $tmpdir . '" - You can change this location with "pear config-set temp_dir"'); } $reg = &$this->config->getRegistry(); $lastmodified = false; if ((!file_exists($params[0]) || is_dir($params[0])) && $reg->channelExists(strtolower($params[0]))) { $c = $reg->getChannel(strtolower($params[0])); if (PEAR::isError($c)) { return $this->raiseError($c); } $this->ui->outputData("Updating channel \"$params[0]\"", $command); $dl = &$this->getDownloader(array()); // if force is specified, use a timestamp of "1" to force retrieval $lastmodified = isset($options['force']) ? false : $c->lastModified(); PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); $contents = $dl->downloadHttp('http://' . $c->getName() . '/channel.xml', $this->ui, $tmpdir, null, $lastmodified); PEAR::staticPopErrorHandling(); if (PEAR::isError($contents)) { // Attempt to fall back to https $this->ui->outputData("Channel \"$params[0]\" is not responding over http://, failed with message: " . $contents->getMessage()); $this->ui->outputData("Trying channel \"$params[0]\" over https:// instead"); PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); $contents = $dl->downloadHttp('https://' . $c->getName() . '/channel.xml', $this->ui, $tmpdir, null, $lastmodified); PEAR::staticPopErrorHandling(); if (PEAR::isError($contents)) { return $this->raiseError('Cannot retrieve channel.xml for channel "' . $c->getName() . '" (' . $contents->getMessage() . ')'); } } list($contents, $lastmodified) = $contents; if (!$contents) { $this->ui->outputData("Channel \"$params[0]\" is up to date"); return; } $contents = implode('', file($contents)); if (!class_exists('PEAR_ChannelFile')) { require_once 'PEAR/ChannelFile.php'; } $channel = new PEAR_ChannelFile; $channel->fromXmlString($contents); if (!$channel->getErrors()) { // security check: is the downloaded file for the channel we got it from? if (strtolower($channel->getName()) != strtolower($c->getName())) { if (!isset($options['force'])) { return $this->raiseError('ERROR: downloaded channel definition file' . ' for channel "' . $channel->getName() . '" from channel "' . strtolower($c->getName()) . '"'); } $this->ui->log(0, 'WARNING: downloaded channel definition file' . ' for channel "' . $channel->getName() . '" from channel "' . strtolower($c->getName()) . '"'); } } } else { if (strpos($params[0], '://')) { $dl = &$this->getDownloader(); PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); $loc = $dl->downloadHttp($params[0], $this->ui, $tmpdir, null, $lastmodified); PEAR::staticPopErrorHandling(); if (PEAR::isError($loc)) { return $this->raiseError("Cannot open " . $params[0] . ' (' . $loc->getMessage() . ')'); } list($loc, $lastmodified) = $loc; $contents = implode('', file($loc)); } else { $fp = false; if (file_exists($params[0])) { $fp = fopen($params[0], 'r'); } if (!$fp) { return $this->raiseError("Cannot open " . $params[0]); } $contents = ''; while (!feof($fp)) { $contents .= fread($fp, 1024); } fclose($fp); } if (!class_exists('PEAR_ChannelFile')) { require_once 'PEAR/ChannelFile.php'; } $channel = new PEAR_ChannelFile; $channel->fromXmlString($contents); } $exit = false; if (count($errors = $channel->getErrors(true))) { foreach ($errors as $error) { $this->ui->outputData(ucfirst($error['level'] . ': ' . $error['message'])); if (!$exit) { $exit = $error['level'] == 'error' ? true : false; } } if ($exit) { return $this->raiseError('Invalid channel.xml file'); } } if (!$reg->channelExists($channel->getName())) { return $this->raiseError('Error: Channel "' . $channel->getName() . '" does not exist, use channel-add to add an entry'); } $ret = $reg->updateChannel($channel, $lastmodified); if (PEAR::isError($ret)) { return $ret; } if (!$ret) { return $this->raiseError('Updating Channel "' . $channel->getName() . '" in registry failed'); } $this->config->setChannels($reg->listChannels()); $this->config->writeConfigFile(); $this->ui->outputData('Update of Channel "' . $channel->getName() . '" succeeded'); } function &getDownloader() { if (!class_exists('PEAR_Downloader')) { require_once 'PEAR/Downloader.php'; } $a = new PEAR_Downloader($this->ui, array(), $this->config); return $a; } function doAlias($command, $options, $params) { if (count($params) === 1) { return $this->raiseError('No channel alias specified'); } if (count($params) !== 2 || (!empty($params[1]) && $params[1][0] == '-')) { return $this->raiseError( 'Invalid format, correct is: channel-alias channel alias'); } $reg = &$this->config->getRegistry(); if (!$reg->channelExists($params[0], true)) { $extra = ''; if ($reg->isAlias($params[0])) { $extra = ' (use "channel-alias ' . $reg->channelName($params[0]) . ' ' . strtolower($params[1]) . '")'; } return $this->raiseError('"' . $params[0] . '" is not a valid channel' . $extra); } if ($reg->isAlias($params[1])) { return $this->raiseError('Channel "' . $reg->channelName($params[1]) . '" is ' . 'already aliased to "' . strtolower($params[1]) . '", cannot re-alias'); } $chan = $reg->getChannel($params[0]); if (PEAR::isError($chan)) { return $this->raiseError('Corrupt registry? Error retrieving channel "' . $params[0] . '" information (' . $chan->getMessage() . ')'); } // make it a local alias if (!$chan->setAlias(strtolower($params[1]), true)) { return $this->raiseError('Alias "' . strtolower($params[1]) . '" is not a valid channel alias'); } $reg->updateChannel($chan); $this->ui->outputData('Channel "' . $chan->getName() . '" aliased successfully to "' . strtolower($params[1]) . '"'); } /** * The channel-discover command * * @param string $command command name * @param array $options option_name => value * @param array $params list of additional parameters. * $params[0] should contain a string with either: * - or * - :@ * @return null|PEAR_Error */ function doDiscover($command, $options, $params) { if (count($params) !== 1) { return $this->raiseError("No channel server specified"); } // Look for the possible input format ":@" if (preg_match('/^(.+):(.+)@(.+)\\z/', $params[0], $matches)) { $username = $matches[1]; $password = $matches[2]; $channel = $matches[3]; } else { $channel = $params[0]; } $reg = &$this->config->getRegistry(); if ($reg->channelExists($channel)) { if (!$reg->isAlias($channel)) { return $this->raiseError("Channel \"$channel\" is already initialized", PEAR_COMMAND_CHANNELS_CHANNEL_EXISTS); } return $this->raiseError("A channel alias named \"$channel\" " . 'already exists, aliasing channel "' . $reg->channelName($channel) . '"'); } $this->pushErrorHandling(PEAR_ERROR_RETURN); $err = $this->doAdd($command, $options, array('http://' . $channel . '/channel.xml')); $this->popErrorHandling(); if (PEAR::isError($err)) { if ($err->getCode() === PEAR_COMMAND_CHANNELS_CHANNEL_EXISTS) { return $this->raiseError("Discovery of channel \"$channel\" failed (" . $err->getMessage() . ')'); } // Attempt fetch via https $this->ui->outputData("Discovering channel $channel over http:// failed with message: " . $err->getMessage()); $this->ui->outputData("Trying to discover channel $channel over https:// instead"); $this->pushErrorHandling(PEAR_ERROR_RETURN); $err = $this->doAdd($command, $options, array('https://' . $channel . '/channel.xml')); $this->popErrorHandling(); if (PEAR::isError($err)) { return $this->raiseError("Discovery of channel \"$channel\" failed (" . $err->getMessage() . ')'); } } // Store username/password if they were given // Arguably we should do a logintest on the channel here, but since // that's awkward on a REST-based channel (even "pear login" doesn't // do it for those), and XML-RPC is deprecated, it's fairly pointless. if (isset($username)) { $this->config->set('username', $username, 'user', $channel); $this->config->set('password', $password, 'user', $channel); $this->config->store(); $this->ui->outputData("Stored login for channel \"$channel\" using username \"$username\"", $command); } $this->ui->outputData("Discovery of channel \"$channel\" succeeded", $command); } /** * Execute the 'login' command. * * @param string $command command name * @param array $options option_name => value * @param array $params list of additional parameters * * @return bool TRUE on success or * a PEAR error on failure * * @access public */ function doLogin($command, $options, $params) { $reg = &$this->config->getRegistry(); // If a parameter is supplied, use that as the channel to log in to $channel = isset($params[0]) ? $params[0] : $this->config->get('default_channel'); $chan = $reg->getChannel($channel); if (PEAR::isError($chan)) { return $this->raiseError($chan); } $server = $this->config->get('preferred_mirror', null, $channel); $username = $this->config->get('username', null, $channel); if (empty($username)) { $username = isset($_ENV['USER']) ? $_ENV['USER'] : null; } $this->ui->outputData("Logging in to $server.", $command); list($username, $password) = $this->ui->userDialog( $command, array('Username', 'Password'), array('text', 'password'), array($username, '') ); $username = trim($username); $password = trim($password); $ourfile = $this->config->getConfFile('user'); if (!$ourfile) { $ourfile = $this->config->getConfFile('system'); } $this->config->set('username', $username, 'user', $channel); $this->config->set('password', $password, 'user', $channel); if ($chan->supportsREST()) { $ok = true; } if ($ok !== true) { return $this->raiseError('Login failed!'); } $this->ui->outputData("Logged in.", $command); // avoid changing any temporary settings changed with -d $ourconfig = new PEAR_Config($ourfile, $ourfile); $ourconfig->set('username', $username, 'user', $channel); $ourconfig->set('password', $password, 'user', $channel); $ourconfig->store(); return true; } /** * Execute the 'logout' command. * * @param string $command command name * @param array $options option_name => value * @param array $params list of additional parameters * * @return bool TRUE on success or * a PEAR error on failure * * @access public */ function doLogout($command, $options, $params) { $reg = &$this->config->getRegistry(); // If a parameter is supplied, use that as the channel to log in to $channel = isset($params[0]) ? $params[0] : $this->config->get('default_channel'); $chan = $reg->getChannel($channel); if (PEAR::isError($chan)) { return $this->raiseError($chan); } $server = $this->config->get('preferred_mirror', null, $channel); $this->ui->outputData("Logging out from $server.", $command); $this->config->remove('username', 'user', $channel); $this->config->remove('password', 'user', $channel); $this->config->store(); return true; } } PKu]Z h66PEAR/Command/Package.xmlnu[ Build Package doPackage p Z Do not gzip the package file n Print the name of the packaged file. [descfile] [descfile2] Creates a PEAR package from its description file (usually called package.xml). If a second packagefile is passed in, then the packager will check to make sure that one is a package.xml version 1.0, and the other is a package.xml version 2.0. The package.xml version 1.0 will be saved as "package.xml" in the archive, and the other as "package2.xml" in the archive" Validate Package Consistency doPackageValidate pv Run a "cvs diff" for all files in a package doCvsDiff cd q Be quiet Q Be really quiet D Diff against revision of DATE DATE R Diff against tag for package release REL REL r Diff against revision REV REV c Generate context diff u Generate unified diff i Ignore case, consider upper- and lower-case letters equivalent b Ignore changes in amount of white space B Ignore changes that insert or delete blank lines Report only whether the files differ, no details n Don't do anything, just pretend <package.xml> Compares all the files in a package. Without any options, this command will compare the current code with the last checked-in code. Using the -r or -R option you may compare the current code with that of a specific release. Set SVN Release Tag doSvnTag sv q Be quiet F Move (slide) tag if it exists d Remove tag n Don't do anything, just pretend <package.xml> [files...] Sets a SVN tag on all files in a package. Use this command after you have packaged a distribution tarball with the "package" command to tag what revisions of what files were in that release. If need to fix something after running svntag once, but before the tarball is released to the public, use the "slide" option to move the release tag. to include files (such as a second package.xml, or tests not included in the release), pass them as additional parameters. Set CVS Release Tag doCvsTag ct q Be quiet Q Be really quiet F Move (slide) tag if it exists d Remove tag n Don't do anything, just pretend <package.xml> [files...] Sets a CVS tag on all files in a package. Use this command after you have packaged a distribution tarball with the "package" command to tag what revisions of what files were in that release. If need to fix something after running cvstag once, but before the tarball is released to the public, use the "slide" option to move the release tag. to include files (such as a second package.xml, or tests not included in the release), pass them as additional parameters. Show package dependencies doPackageDependencies pd <package-file> or <package.xml> or <install-package-name> List all dependencies the package has. Can take a tgz / tar file, package.xml or a package name of an installed package. Sign a package distribution file doSign si v Display GnuPG output <package-file> Signs a package distribution (.tar or .tgz) file with GnuPG. Builds an RPM spec file from a PEAR package doMakeRPM rpm t Use FILE as RPM spec file template FILE p Use FORMAT as format string for RPM package name, %s is replaced by the PEAR package name, defaults to "PEAR::%s". FORMAT <package-file> Creates an RPM .spec file for wrapping a PEAR package inside an RPM package. Intended to be used from the SPECS directory, with the PEAR package tarball in the SOURCES directory: $ pear makerpm ../SOURCES/Net_Socket-1.0.tgz Wrote RPM spec file PEAR::Net_Geo-1.0.spec $ rpm -bb PEAR::Net_Socket-1.0.spec ... Wrote: /usr/src/redhat/RPMS/i386/PEAR::Net_Socket-1.0-1.i386.rpm Convert a package.xml 1.0 to package.xml 2.0 format doConvert c2 f do not beautify the filelist. [descfile] [descfile2] Converts a package.xml in 1.0 format into a package.xml in 2.0 format. The new file will be named package2.xml by default, and package.xml will be used as the old file by default. This is not the most intelligent conversion, and should only be used for automated conversion or learning the format. PKu]%FiiPEAR/Command/Test.xmlnu[ Run Regression Tests doRunTests rt r Run tests in child directories, recursively. 4 dirs deep maximum i actual string of settings to pass to php in format " -d setting=blah" SETTINGS l Log test runs/results as they are run q Only display detail for failed tests s Display simple output for all tests p Treat parameters as installed packages from which to run tests u Search parameters for AllTests.php, and use that to run phpunit-based tests If none is found, all .phpt tests will be tried instead. t Output run-tests.log in TAP-compliant format c CGI php executable (needed for tests with POST/GET section) PHPCGI x Generate a code coverage report (requires Xdebug 2.0.0+) [testfile|dir ...] Run regression tests with PHP's regression testing script (run-tests.php). PKu]+9 ҜҜPEAR/Command/Package.phpnu[ * @author Martin Jansen * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 0.1 */ /** * base class */ require_once 'PEAR/Command/Common.php'; /** * PEAR commands for login/logout * * @category pear * @package PEAR * @author Stig Bakken * @author Martin Jansen * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 0.1 */ class PEAR_Command_Package extends PEAR_Command_Common { var $commands = array( 'package' => array( 'summary' => 'Build Package', 'function' => 'doPackage', 'shortcut' => 'p', 'options' => array( 'nocompress' => array( 'shortopt' => 'Z', 'doc' => 'Do not gzip the package file' ), 'showname' => array( 'shortopt' => 'n', 'doc' => 'Print the name of the packaged file.', ), ), 'doc' => '[descfile] [descfile2] Creates a PEAR package from its description file (usually called package.xml). If a second packagefile is passed in, then the packager will check to make sure that one is a package.xml version 1.0, and the other is a package.xml version 2.0. The package.xml version 1.0 will be saved as "package.xml" in the archive, and the other as "package2.xml" in the archive" ' ), 'package-validate' => array( 'summary' => 'Validate Package Consistency', 'function' => 'doPackageValidate', 'shortcut' => 'pv', 'options' => array(), 'doc' => ' ', ), 'cvsdiff' => array( 'summary' => 'Run a "cvs diff" for all files in a package', 'function' => 'doCvsDiff', 'shortcut' => 'cd', 'options' => array( 'quiet' => array( 'shortopt' => 'q', 'doc' => 'Be quiet', ), 'reallyquiet' => array( 'shortopt' => 'Q', 'doc' => 'Be really quiet', ), 'date' => array( 'shortopt' => 'D', 'doc' => 'Diff against revision of DATE', 'arg' => 'DATE', ), 'release' => array( 'shortopt' => 'R', 'doc' => 'Diff against tag for package release REL', 'arg' => 'REL', ), 'revision' => array( 'shortopt' => 'r', 'doc' => 'Diff against revision REV', 'arg' => 'REV', ), 'context' => array( 'shortopt' => 'c', 'doc' => 'Generate context diff', ), 'unified' => array( 'shortopt' => 'u', 'doc' => 'Generate unified diff', ), 'ignore-case' => array( 'shortopt' => 'i', 'doc' => 'Ignore case, consider upper- and lower-case letters equivalent', ), 'ignore-whitespace' => array( 'shortopt' => 'b', 'doc' => 'Ignore changes in amount of white space', ), 'ignore-blank-lines' => array( 'shortopt' => 'B', 'doc' => 'Ignore changes that insert or delete blank lines', ), 'brief' => array( 'doc' => 'Report only whether the files differ, no details', ), 'dry-run' => array( 'shortopt' => 'n', 'doc' => 'Don\'t do anything, just pretend', ), ), 'doc' => ' Compares all the files in a package. Without any options, this command will compare the current code with the last checked-in code. Using the -r or -R option you may compare the current code with that of a specific release. ', ), 'svntag' => array( 'summary' => 'Set SVN Release Tag', 'function' => 'doSvnTag', 'shortcut' => 'sv', 'options' => array( 'quiet' => array( 'shortopt' => 'q', 'doc' => 'Be quiet', ), 'slide' => array( 'shortopt' => 'F', 'doc' => 'Move (slide) tag if it exists', ), 'delete' => array( 'shortopt' => 'd', 'doc' => 'Remove tag', ), 'dry-run' => array( 'shortopt' => 'n', 'doc' => 'Don\'t do anything, just pretend', ), ), 'doc' => ' [files...] Sets a SVN tag on all files in a package. Use this command after you have packaged a distribution tarball with the "package" command to tag what revisions of what files were in that release. If need to fix something after running svntag once, but before the tarball is released to the public, use the "slide" option to move the release tag. to include files (such as a second package.xml, or tests not included in the release), pass them as additional parameters. ', ), 'cvstag' => array( 'summary' => 'Set CVS Release Tag', 'function' => 'doCvsTag', 'shortcut' => 'ct', 'options' => array( 'quiet' => array( 'shortopt' => 'q', 'doc' => 'Be quiet', ), 'reallyquiet' => array( 'shortopt' => 'Q', 'doc' => 'Be really quiet', ), 'slide' => array( 'shortopt' => 'F', 'doc' => 'Move (slide) tag if it exists', ), 'delete' => array( 'shortopt' => 'd', 'doc' => 'Remove tag', ), 'dry-run' => array( 'shortopt' => 'n', 'doc' => 'Don\'t do anything, just pretend', ), ), 'doc' => ' [files...] Sets a CVS tag on all files in a package. Use this command after you have packaged a distribution tarball with the "package" command to tag what revisions of what files were in that release. If need to fix something after running cvstag once, but before the tarball is released to the public, use the "slide" option to move the release tag. to include files (such as a second package.xml, or tests not included in the release), pass them as additional parameters. ', ), 'package-dependencies' => array( 'summary' => 'Show package dependencies', 'function' => 'doPackageDependencies', 'shortcut' => 'pd', 'options' => array(), 'doc' => ' or or List all dependencies the package has. Can take a tgz / tar file, package.xml or a package name of an installed package.' ), 'sign' => array( 'summary' => 'Sign a package distribution file', 'function' => 'doSign', 'shortcut' => 'si', 'options' => array( 'verbose' => array( 'shortopt' => 'v', 'doc' => 'Display GnuPG output', ), ), 'doc' => ' Signs a package distribution (.tar or .tgz) file with GnuPG.', ), 'makerpm' => array( 'summary' => 'Builds an RPM spec file from a PEAR package', 'function' => 'doMakeRPM', 'shortcut' => 'rpm', 'options' => array( 'spec-template' => array( 'shortopt' => 't', 'arg' => 'FILE', 'doc' => 'Use FILE as RPM spec file template' ), 'rpm-pkgname' => array( 'shortopt' => 'p', 'arg' => 'FORMAT', 'doc' => 'Use FORMAT as format string for RPM package name, %s is replaced by the PEAR package name, defaults to "PEAR::%s".', ), ), 'doc' => ' Creates an RPM .spec file for wrapping a PEAR package inside an RPM package. Intended to be used from the SPECS directory, with the PEAR package tarball in the SOURCES directory: $ pear makerpm ../SOURCES/Net_Socket-1.0.tgz Wrote RPM spec file PEAR::Net_Geo-1.0.spec $ rpm -bb PEAR::Net_Socket-1.0.spec ... Wrote: /usr/src/redhat/RPMS/i386/PEAR::Net_Socket-1.0-1.i386.rpm ', ), 'convert' => array( 'summary' => 'Convert a package.xml 1.0 to package.xml 2.0 format', 'function' => 'doConvert', 'shortcut' => 'c2', 'options' => array( 'flat' => array( 'shortopt' => 'f', 'doc' => 'do not beautify the filelist.', ), ), 'doc' => '[descfile] [descfile2] Converts a package.xml in 1.0 format into a package.xml in 2.0 format. The new file will be named package2.xml by default, and package.xml will be used as the old file by default. This is not the most intelligent conversion, and should only be used for automated conversion or learning the format. ' ), ); var $output; /** * PEAR_Command_Package constructor. * * @access public */ function __construct(&$ui, &$config) { parent::__construct($ui, $config); } function _displayValidationResults($err, $warn, $strict = false) { foreach ($err as $e) { $this->output .= "Error: $e\n"; } foreach ($warn as $w) { $this->output .= "Warning: $w\n"; } $this->output .= sprintf('Validation: %d error(s), %d warning(s)'."\n", sizeof($err), sizeof($warn)); if ($strict && count($err) > 0) { $this->output .= "Fix these errors and try again."; return false; } return true; } function &getPackager() { if (!class_exists('PEAR_Packager')) { require_once 'PEAR/Packager.php'; } $a = new PEAR_Packager; return $a; } function &getPackageFile($config, $debug = false) { if (!class_exists('PEAR_Common')) { require_once 'PEAR/Common.php'; } if (!class_exists('PEAR_PackageFile')) { require_once 'PEAR/PackageFile.php'; } $a = new PEAR_PackageFile($config, $debug); $common = new PEAR_Common; $common->ui = $this->ui; $a->setLogger($common); return $a; } function doPackage($command, $options, $params) { $this->output = ''; $pkginfofile = isset($params[0]) ? $params[0] : 'package.xml'; $pkg2 = isset($params[1]) ? $params[1] : null; if (!$pkg2 && !isset($params[0]) && file_exists('package2.xml')) { $pkg2 = 'package2.xml'; } $packager = &$this->getPackager(); $compress = empty($options['nocompress']) ? true : false; $result = $packager->package($pkginfofile, $compress, $pkg2); if (PEAR::isError($result)) { return $this->raiseError($result); } // Don't want output, only the package file name just created if (isset($options['showname'])) { $this->output = $result; } if ($this->output) { $this->ui->outputData($this->output, $command); } return true; } function doPackageValidate($command, $options, $params) { $this->output = ''; if (count($params) < 1) { $params[0] = 'package.xml'; } $obj = &$this->getPackageFile($this->config, $this->_debug); $obj->rawReturn(); PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); $info = $obj->fromTgzFile($params[0], PEAR_VALIDATE_NORMAL); if (PEAR::isError($info)) { $info = $obj->fromPackageFile($params[0], PEAR_VALIDATE_NORMAL); } else { $archive = $info->getArchiveFile(); $tar = new Archive_Tar($archive); $tar->extract(dirname($info->getPackageFile())); $info->setPackageFile(dirname($info->getPackageFile()) . DIRECTORY_SEPARATOR . $info->getPackage() . '-' . $info->getVersion() . DIRECTORY_SEPARATOR . basename($info->getPackageFile())); } PEAR::staticPopErrorHandling(); if (PEAR::isError($info)) { return $this->raiseError($info); } $valid = false; if ($info->getPackagexmlVersion() == '2.0') { if ($valid = $info->validate(PEAR_VALIDATE_NORMAL)) { $info->flattenFileList(); $valid = $info->validate(PEAR_VALIDATE_PACKAGING); } } else { $valid = $info->validate(PEAR_VALIDATE_PACKAGING); } $err = $warn = array(); if ($errors = $info->getValidationWarnings()) { foreach ($errors as $error) { if ($error['level'] == 'warning') { $warn[] = $error['message']; } else { $err[] = $error['message']; } } } $this->_displayValidationResults($err, $warn); $this->ui->outputData($this->output, $command); return true; } function doSvnTag($command, $options, $params) { $this->output = ''; $_cmd = $command; if (count($params) < 1) { $help = $this->getHelp($command); return $this->raiseError("$command: missing parameter: $help[0]"); } $packageFile = realpath($params[0]); $dir = dirname($packageFile); $dir = substr($dir, strrpos($dir, DIRECTORY_SEPARATOR) + 1); $obj = &$this->getPackageFile($this->config, $this->_debug); $info = $obj->fromAnyFile($packageFile, PEAR_VALIDATE_NORMAL); if (PEAR::isError($info)) { return $this->raiseError($info); } $err = $warn = array(); if (!$info->validate()) { foreach ($info->getValidationWarnings() as $error) { if ($error['level'] == 'warning') { $warn[] = $error['message']; } else { $err[] = $error['message']; } } } if (!$this->_displayValidationResults($err, $warn, true)) { $this->ui->outputData($this->output, $command); return $this->raiseError('SVN tag failed'); } $version = $info->getVersion(); $package = $info->getName(); $svntag = "$package-$version"; if (isset($options['delete'])) { return $this->_svnRemoveTag($version, $package, $svntag, $packageFile, $options); } $path = $this->_svnFindPath($packageFile); // Check if there are any modified files $fp = popen('svn st --xml ' . dirname($packageFile), "r"); $out = ''; while ($line = fgets($fp, 1024)) { $out .= rtrim($line)."\n"; } pclose($fp); if (!isset($options['quiet']) && strpos($out, 'item="modified"')) { $params = array(array( 'name' => 'modified', 'type' => 'yesno', 'default' => 'no', 'prompt' => 'You have files in your SVN checkout (' . $path['from'] . ') that have been modified but not committed, do you still want to tag ' . $version . '?', )); $answers = $this->ui->confirmDialog($params); if (!in_array($answers['modified'], array('y', 'yes', 'on', '1'))) { return true; } } if (isset($options['slide'])) { $this->_svnRemoveTag($version, $package, $svntag, $packageFile, $options); } // Check if tag already exists $releaseTag = $path['local']['base'] . 'tags' . DIRECTORY_SEPARATOR . $svntag; $existsCommand = 'svn ls ' . $path['base'] . 'tags/'; $fp = popen($existsCommand, "r"); $out = ''; while ($line = fgets($fp, 1024)) { $out .= rtrim($line)."\n"; } pclose($fp); if (in_array($svntag . DIRECTORY_SEPARATOR, explode("\n", $out))) { $this->ui->outputData($this->output, $command); return $this->raiseError('SVN tag ' . $svntag . ' for ' . $package . ' already exists.'); } elseif (file_exists($path['local']['base'] . 'tags') === false) { return $this->raiseError('Can not locate the tags directory at ' . $path['local']['base'] . 'tags'); } elseif (is_writeable($path['local']['base'] . 'tags') === false) { return $this->raiseError('Can not write to the tag directory at ' . $path['local']['base'] . 'tags'); } else { $makeCommand = 'svn mkdir ' . $releaseTag; $this->output .= "+ $makeCommand\n"; if (empty($options['dry-run'])) { // We need to create the tag dir. $fp = popen($makeCommand, "r"); $out = ''; while ($line = fgets($fp, 1024)) { $out .= rtrim($line)."\n"; } pclose($fp); $this->output .= "$out\n"; } } $command = 'svn'; if (isset($options['quiet'])) { $command .= ' -q'; } $command .= ' copy --parents '; $dir = dirname($packageFile); $dir = substr($dir, strrpos($dir, DIRECTORY_SEPARATOR) + 1); $files = array_keys($info->getFilelist()); if (!in_array(basename($packageFile), $files)) { $files[] = basename($packageFile); } array_shift($params); if (count($params)) { // add in additional files to be tagged (package files and such) $files = array_merge($files, $params); } $commands = array(); foreach ($files as $file) { if (!file_exists($file)) { $file = $dir . DIRECTORY_SEPARATOR . $file; } $commands[] = $command . ' ' . escapeshellarg($file) . ' ' . escapeshellarg($releaseTag . DIRECTORY_SEPARATOR . $file); } $this->output .= implode("\n", $commands) . "\n"; if (empty($options['dry-run'])) { foreach ($commands as $command) { $fp = popen($command, "r"); while ($line = fgets($fp, 1024)) { $this->output .= rtrim($line)."\n"; } pclose($fp); } } $command = 'svn ci -m "Tagging the ' . $version . ' release" ' . $releaseTag . "\n"; $this->output .= "+ $command\n"; if (empty($options['dry-run'])) { $fp = popen($command, "r"); while ($line = fgets($fp, 1024)) { $this->output .= rtrim($line)."\n"; } pclose($fp); } $this->ui->outputData($this->output, $_cmd); return true; } function _svnFindPath($file) { $xml = ''; $command = "svn info --xml $file"; $fp = popen($command, "r"); while ($line = fgets($fp, 1024)) { $xml .= rtrim($line)."\n"; } pclose($fp); $url_tag = strpos($xml, ''); $url = substr($xml, $url_tag + 5, strpos($xml, '', $url_tag + 5) - ($url_tag + 5)); $path = array(); $path['from'] = substr($url, 0, strrpos($url, '/')); $path['base'] = substr($path['from'], 0, strrpos($path['from'], '/') + 1); // Figure out the local paths - see http://pear.php.net/bugs/17463 $pos = strpos($file, DIRECTORY_SEPARATOR . 'trunk' . DIRECTORY_SEPARATOR); if ($pos === false) { $pos = strpos($file, DIRECTORY_SEPARATOR . 'branches' . DIRECTORY_SEPARATOR); } $path['local']['base'] = substr($file, 0, $pos + 1); return $path; } function _svnRemoveTag($version, $package, $tag, $packageFile, $options) { $command = 'svn'; if (isset($options['quiet'])) { $command .= ' -q'; } $command .= ' remove'; $command .= ' -m "Removing tag for the ' . $version . ' release."'; $path = $this->_svnFindPath($packageFile); $command .= ' ' . $path['base'] . 'tags/' . $tag; if ($this->config->get('verbose') > 1) { $this->output .= "+ $command\n"; } $this->output .= "+ $command\n"; if (empty($options['dry-run'])) { $fp = popen($command, "r"); while ($line = fgets($fp, 1024)) { $this->output .= rtrim($line)."\n"; } pclose($fp); } $this->ui->outputData($this->output, $command); return true; } function doCvsTag($command, $options, $params) { $this->output = ''; $_cmd = $command; if (count($params) < 1) { $help = $this->getHelp($command); return $this->raiseError("$command: missing parameter: $help[0]"); } $packageFile = realpath($params[0]); $obj = &$this->getPackageFile($this->config, $this->_debug); $info = $obj->fromAnyFile($packageFile, PEAR_VALIDATE_NORMAL); if (PEAR::isError($info)) { return $this->raiseError($info); } $err = $warn = array(); if (!$info->validate()) { foreach ($info->getValidationWarnings() as $error) { if ($error['level'] == 'warning') { $warn[] = $error['message']; } else { $err[] = $error['message']; } } } if (!$this->_displayValidationResults($err, $warn, true)) { $this->ui->outputData($this->output, $command); return $this->raiseError('CVS tag failed'); } $version = $info->getVersion(); $cvsversion = preg_replace('/[^a-z0-9]/i', '_', $version); $cvstag = "RELEASE_$cvsversion"; $files = array_keys($info->getFilelist()); $command = 'cvs'; if (isset($options['quiet'])) { $command .= ' -q'; } if (isset($options['reallyquiet'])) { $command .= ' -Q'; } $command .= ' tag'; if (isset($options['slide'])) { $command .= ' -F'; } if (isset($options['delete'])) { $command .= ' -d'; } $command .= ' ' . $cvstag . ' ' . escapeshellarg($params[0]); array_shift($params); if (count($params)) { // add in additional files to be tagged $files = array_merge($files, $params); } $dir = dirname($packageFile); $dir = substr($dir, strrpos($dir, '/') + 1); foreach ($files as $file) { if (!file_exists($file)) { $file = $dir . DIRECTORY_SEPARATOR . $file; } $command .= ' ' . escapeshellarg($file); } if ($this->config->get('verbose') > 1) { $this->output .= "+ $command\n"; } $this->output .= "+ $command\n"; if (empty($options['dry-run'])) { $fp = popen($command, "r"); while ($line = fgets($fp, 1024)) { $this->output .= rtrim($line)."\n"; } pclose($fp); } $this->ui->outputData($this->output, $_cmd); return true; } function doCvsDiff($command, $options, $params) { $this->output = ''; if (sizeof($params) < 1) { $help = $this->getHelp($command); return $this->raiseError("$command: missing parameter: $help[0]"); } $file = realpath($params[0]); $obj = &$this->getPackageFile($this->config, $this->_debug); $info = $obj->fromAnyFile($file, PEAR_VALIDATE_NORMAL); if (PEAR::isError($info)) { return $this->raiseError($info); } $err = $warn = array(); if (!$info->validate()) { foreach ($info->getValidationWarnings() as $error) { if ($error['level'] == 'warning') { $warn[] = $error['message']; } else { $err[] = $error['message']; } } } if (!$this->_displayValidationResults($err, $warn, true)) { $this->ui->outputData($this->output, $command); return $this->raiseError('CVS diff failed'); } $info1 = $info->getFilelist(); $files = $info1; $cmd = "cvs"; if (isset($options['quiet'])) { $cmd .= ' -q'; unset($options['quiet']); } if (isset($options['reallyquiet'])) { $cmd .= ' -Q'; unset($options['reallyquiet']); } if (isset($options['release'])) { $cvsversion = preg_replace('/[^a-z0-9]/i', '_', $options['release']); $cvstag = "RELEASE_$cvsversion"; $options['revision'] = $cvstag; unset($options['release']); } $execute = true; if (isset($options['dry-run'])) { $execute = false; unset($options['dry-run']); } $cmd .= ' diff'; // the rest of the options are passed right on to "cvs diff" foreach ($options as $option => $optarg) { $arg = $short = false; if (isset($this->commands[$command]['options'][$option])) { $arg = $this->commands[$command]['options'][$option]['arg']; $short = $this->commands[$command]['options'][$option]['shortopt']; } $cmd .= $short ? " -$short" : " --$option"; if ($arg && $optarg) { $cmd .= ($short ? '' : '=') . escapeshellarg($optarg); } } foreach ($files as $file) { $cmd .= ' ' . escapeshellarg($file['name']); } if ($this->config->get('verbose') > 1) { $this->output .= "+ $cmd\n"; } if ($execute) { $fp = popen($cmd, "r"); while ($line = fgets($fp, 1024)) { $this->output .= rtrim($line)."\n"; } pclose($fp); } $this->ui->outputData($this->output, $command); return true; } function doPackageDependencies($command, $options, $params) { // $params[0] -> the PEAR package to list its information if (count($params) !== 1) { return $this->raiseError("bad parameter(s), try \"help $command\""); } $obj = &$this->getPackageFile($this->config, $this->_debug); if (is_file($params[0]) || strpos($params[0], '.xml') > 0) { $info = $obj->fromAnyFile($params[0], PEAR_VALIDATE_NORMAL); } else { $reg = $this->config->getRegistry(); $info = $obj->fromArray($reg->packageInfo($params[0])); } if (PEAR::isError($info)) { return $this->raiseError($info); } $deps = $info->getDeps(); if (is_array($deps)) { if ($info->getPackagexmlVersion() == '1.0') { $data = array( 'caption' => 'Dependencies for pear/' . $info->getPackage(), 'border' => true, 'headline' => array("Required?", "Type", "Name", "Relation", "Version"), ); foreach ($deps as $d) { if (isset($d['optional'])) { if ($d['optional'] == 'yes') { $req = 'No'; } else { $req = 'Yes'; } } else { $req = 'Yes'; } if (isset($this->_deps_rel_trans[$d['rel']])) { $rel = $this->_deps_rel_trans[$d['rel']]; } else { $rel = $d['rel']; } if (isset($this->_deps_type_trans[$d['type']])) { $type = ucfirst($this->_deps_type_trans[$d['type']]); } else { $type = $d['type']; } if (isset($d['name'])) { $name = $d['name']; } else { $name = ''; } if (isset($d['version'])) { $version = $d['version']; } else { $version = ''; } $data['data'][] = array($req, $type, $name, $rel, $version); } } else { // package.xml 2.0 dependencies display require_once 'PEAR/Dependency2.php'; $deps = $info->getDependencies(); $reg = &$this->config->getRegistry(); if (is_array($deps)) { $data = array( 'caption' => 'Dependencies for ' . $info->getPackage(), 'border' => true, 'headline' => array("Required?", "Type", "Name", 'Versioning', 'Group'), ); foreach ($deps as $type => $subd) { $req = ($type == 'required') ? 'Yes' : 'No'; if ($type == 'group' && isset($subd['attribs']['name'])) { $group = $subd['attribs']['name']; } else { $group = ''; } if (!isset($subd[0])) { $subd = array($subd); } foreach ($subd as $groupa) { foreach ($groupa as $deptype => $depinfo) { if ($deptype == 'attribs') { continue; } if ($deptype == 'pearinstaller') { $deptype = 'pear Installer'; } if (!isset($depinfo[0])) { $depinfo = array($depinfo); } foreach ($depinfo as $inf) { $name = ''; if (isset($inf['channel'])) { $alias = $reg->channelAlias($inf['channel']); if (!$alias) { $alias = '(channel?) ' .$inf['channel']; } $name = $alias . '/'; } if (isset($inf['name'])) { $name .= $inf['name']; } elseif (isset($inf['pattern'])) { $name .= $inf['pattern']; } else { $name .= ''; } if (isset($inf['uri'])) { $name .= ' [' . $inf['uri'] . ']'; } if (isset($inf['conflicts'])) { $ver = 'conflicts'; } else { $ver = PEAR_Dependency2::_getExtraString($inf); } $data['data'][] = array($req, ucfirst($deptype), $name, $ver, $group); } } } } } } $this->ui->outputData($data, $command); return true; } // Fallback $this->ui->outputData("This package does not have any dependencies.", $command); } function doSign($command, $options, $params) { // should move most of this code into PEAR_Packager // so it'll be easy to implement "pear package --sign" if (count($params) !== 1) { return $this->raiseError("bad parameter(s), try \"help $command\""); } require_once 'System.php'; require_once 'Archive/Tar.php'; if (!file_exists($params[0])) { return $this->raiseError("file does not exist: $params[0]"); } $obj = $this->getPackageFile($this->config, $this->_debug); $info = $obj->fromTgzFile($params[0], PEAR_VALIDATE_NORMAL); if (PEAR::isError($info)) { return $this->raiseError($info); } $tar = new Archive_Tar($params[0]); $tmpdir = $this->config->get('temp_dir'); $tmpdir = System::mktemp(' -t "' . $tmpdir . '" -d pearsign'); if (!$tar->extractList('package2.xml package.xml package.sig', $tmpdir)) { return $this->raiseError("failed to extract tar file"); } if (file_exists("$tmpdir/package.sig")) { return $this->raiseError("package already signed"); } $packagexml = 'package.xml'; if (file_exists("$tmpdir/package2.xml")) { $packagexml = 'package2.xml'; } if (file_exists("$tmpdir/package.sig")) { unlink("$tmpdir/package.sig"); } if (!file_exists("$tmpdir/$packagexml")) { return $this->raiseError("Extracted file $tmpdir/$packagexml not found."); } $input = $this->ui->userDialog($command, array('GnuPG Passphrase'), array('password')); if (!isset($input[0])) { //use empty passphrase $input[0] = ''; } $devnull = (isset($options['verbose'])) ? '' : ' 2>/dev/null'; $gpg = popen("gpg --batch --passphrase-fd 0 --armor --detach-sign --output $tmpdir/package.sig $tmpdir/$packagexml" . $devnull, "w"); if (!$gpg) { return $this->raiseError("gpg command failed"); } fwrite($gpg, "$input[0]\n"); if (pclose($gpg) || !file_exists("$tmpdir/package.sig")) { return $this->raiseError("gpg sign failed"); } if (!$tar->addModify("$tmpdir/package.sig", '', $tmpdir)) { return $this->raiseError('failed adding signature to file'); } $this->ui->outputData("Package signed.", $command); return true; } /** * For unit testing purposes */ function &getInstaller(&$ui) { if (!class_exists('PEAR_Installer')) { require_once 'PEAR/Installer.php'; } $a = new PEAR_Installer($ui); return $a; } /** * For unit testing purposes */ function &getCommandPackaging(&$ui, &$config) { if (!class_exists('PEAR_Command_Packaging')) { if ($fp = @fopen('PEAR/Command/Packaging.php', 'r', true)) { fclose($fp); include_once 'PEAR/Command/Packaging.php'; } } if (class_exists('PEAR_Command_Packaging')) { $a = new PEAR_Command_Packaging($ui, $config); } else { $a = null; } return $a; } function doMakeRPM($command, $options, $params) { // Check to see if PEAR_Command_Packaging is installed, and // transparently switch to use the "make-rpm-spec" command from it // instead, if it does. Otherwise, continue to use the old version // of "makerpm" supplied with this package (PEAR). $packaging_cmd = $this->getCommandPackaging($this->ui, $this->config); if ($packaging_cmd !== null) { $this->ui->outputData('PEAR_Command_Packaging is installed; using '. 'newer "make-rpm-spec" command instead'); return $packaging_cmd->run('make-rpm-spec', $options, $params); } $this->ui->outputData('WARNING: "pear makerpm" is no longer available; an '. 'improved version is available via "pear make-rpm-spec", which '. 'is available by installing PEAR_Command_Packaging'); return true; } function doConvert($command, $options, $params) { $packagexml = isset($params[0]) ? $params[0] : 'package.xml'; $newpackagexml = isset($params[1]) ? $params[1] : dirname($packagexml) . DIRECTORY_SEPARATOR . 'package2.xml'; $pkg = &$this->getPackageFile($this->config, $this->_debug); PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); $pf = $pkg->fromPackageFile($packagexml, PEAR_VALIDATE_NORMAL); PEAR::staticPopErrorHandling(); if (PEAR::isError($pf)) { if (is_array($pf->getUserInfo())) { foreach ($pf->getUserInfo() as $warning) { $this->ui->outputData($warning['message']); } } return $this->raiseError($pf); } if (is_a($pf, 'PEAR_PackageFile_v2')) { $this->ui->outputData($packagexml . ' is already a package.xml version 2.0'); return true; } $gen = &$pf->getDefaultGenerator(); $newpf = &$gen->toV2(); $newpf->setPackagefile($newpackagexml); $gen = &$newpf->getDefaultGenerator(); PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); $state = (isset($options['flat']) ? PEAR_VALIDATE_PACKAGING : PEAR_VALIDATE_NORMAL); $saved = $gen->toPackageFile(dirname($newpackagexml), $state, basename($newpackagexml)); PEAR::staticPopErrorHandling(); if (PEAR::isError($saved)) { if (is_array($saved->getUserInfo())) { foreach ($saved->getUserInfo() as $warning) { $this->ui->outputData($warning['message']); } } $this->ui->outputData($saved->getMessage()); return true; } $this->ui->outputData('Wrote new version 2.0 package.xml to "' . $saved . '"'); return true; } } PKu]4{PEAR/Command/Auth.xmlnu[ Connects and authenticates to remote server [Deprecated in favor of channel-login] doLogin li <channel name> WARNING: This function is deprecated in favor of using channel-login Log in to a remote channel server. If <channel name> is not supplied, the default channel is used. To use remote functions in the installer that require any kind of privileges, you need to log in first. The username and password you enter here will be stored in your per-user PEAR configuration (~/.pearrc on Unix-like systems). After logging in, your username and password will be sent along in subsequent operations on the remote server. Logs out from the remote server [Deprecated in favor of channel-logout] doLogout lo WARNING: This function is deprecated in favor of using channel-logout Logs out from the remote server. This command does not actually connect to the remote server, it only deletes the stored username and password from your user configuration. PKu]zk<k<PEAR/Command/Config.phpnu[ * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 0.1 */ /** * base class */ require_once 'PEAR/Command/Common.php'; /** * PEAR commands for managing configuration data. * * @category pear * @package PEAR * @author Stig Bakken * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 0.1 */ class PEAR_Command_Config extends PEAR_Command_Common { var $commands = array( 'config-show' => array( 'summary' => 'Show All Settings', 'function' => 'doConfigShow', 'shortcut' => 'csh', 'options' => array( 'channel' => array( 'shortopt' => 'c', 'doc' => 'show configuration variables for another channel', 'arg' => 'CHAN', ), ), 'doc' => '[layer] Displays all configuration values. An optional argument may be used to tell which configuration layer to display. Valid configuration layers are "user", "system" and "default". To display configurations for different channels, set the default_channel configuration variable and run config-show again. ', ), 'config-get' => array( 'summary' => 'Show One Setting', 'function' => 'doConfigGet', 'shortcut' => 'cg', 'options' => array( 'channel' => array( 'shortopt' => 'c', 'doc' => 'show configuration variables for another channel', 'arg' => 'CHAN', ), ), 'doc' => ' [layer] Displays the value of one configuration parameter. The first argument is the name of the parameter, an optional second argument may be used to tell which configuration layer to look in. Valid configuration layers are "user", "system" and "default". If no layer is specified, a value will be picked from the first layer that defines the parameter, in the order just specified. The configuration value will be retrieved for the channel specified by the default_channel configuration variable. ', ), 'config-set' => array( 'summary' => 'Change Setting', 'function' => 'doConfigSet', 'shortcut' => 'cs', 'options' => array( 'channel' => array( 'shortopt' => 'c', 'doc' => 'show configuration variables for another channel', 'arg' => 'CHAN', ), ), 'doc' => ' [layer] Sets the value of one configuration parameter. The first argument is the name of the parameter, the second argument is the new value. Some parameters are subject to validation, and the command will fail with an error message if the new value does not make sense. An optional third argument may be used to specify in which layer to set the configuration parameter. The default layer is "user". The configuration value will be set for the current channel, which is controlled by the default_channel configuration variable. ', ), 'config-help' => array( 'summary' => 'Show Information About Setting', 'function' => 'doConfigHelp', 'shortcut' => 'ch', 'options' => array(), 'doc' => '[parameter] Displays help for a configuration parameter. Without arguments it displays help for all configuration parameters. ', ), 'config-create' => array( 'summary' => 'Create a Default configuration file', 'function' => 'doConfigCreate', 'shortcut' => 'coc', 'options' => array( 'windows' => array( 'shortopt' => 'w', 'doc' => 'create a config file for a windows install', ), ), 'doc' => ' Create a default configuration file with all directory configuration variables set to subdirectories of , and save it as . This is useful especially for creating a configuration file for a remote PEAR installation (using the --remoteconfig option of install, upgrade, and uninstall). ', ), ); /** * PEAR_Command_Config constructor. * * @access public */ function __construct(&$ui, &$config) { parent::__construct($ui, $config); } function doConfigShow($command, $options, $params) { $layer = null; if (is_array($params)) { $layer = isset($params[0]) ? $params[0] : null; } // $params[0] -> the layer if ($error = $this->_checkLayer($layer)) { return $this->raiseError("config-show:$error"); } $keys = $this->config->getKeys(); sort($keys); $channel = isset($options['channel']) ? $options['channel'] : $this->config->get('default_channel'); $reg = &$this->config->getRegistry(); if (!$reg->channelExists($channel)) { return $this->raiseError('Channel "' . $channel . '" does not exist'); } $channel = $reg->channelName($channel); $data = array('caption' => 'Configuration (channel ' . $channel . '):'); foreach ($keys as $key) { $type = $this->config->getType($key); $value = $this->config->get($key, $layer, $channel); if ($type == 'password' && $value) { $value = '********'; } if ($value === false) { $value = 'false'; } elseif ($value === true) { $value = 'true'; } $data['data'][$this->config->getGroup($key)][] = array($this->config->getPrompt($key) , $key, $value); } foreach ($this->config->getLayers() as $layer) { $data['data']['Config Files'][] = array(ucfirst($layer) . ' Configuration File', 'Filename' , $this->config->getConfFile($layer)); } $this->ui->outputData($data, $command); return true; } function doConfigGet($command, $options, $params) { $args_cnt = is_array($params) ? count($params) : 0; switch ($args_cnt) { case 1: $config_key = $params[0]; $layer = null; break; case 2: $config_key = $params[0]; $layer = $params[1]; if ($error = $this->_checkLayer($layer)) { return $this->raiseError("config-get:$error"); } break; case 0: default: return $this->raiseError("config-get expects 1 or 2 parameters"); } $reg = &$this->config->getRegistry(); $channel = isset($options['channel']) ? $options['channel'] : $this->config->get('default_channel'); if (!$reg->channelExists($channel)) { return $this->raiseError('Channel "' . $channel . '" does not exist'); } $channel = $reg->channelName($channel); $this->ui->outputData($this->config->get($config_key, $layer, $channel), $command); return true; } function doConfigSet($command, $options, $params) { // $param[0] -> a parameter to set // $param[1] -> the value for the parameter // $param[2] -> the layer $failmsg = ''; if (count($params) < 2 || count($params) > 3) { $failmsg .= "config-set expects 2 or 3 parameters"; return PEAR::raiseError($failmsg); } if (isset($params[2]) && ($error = $this->_checkLayer($params[2]))) { $failmsg .= $error; return PEAR::raiseError("config-set:$failmsg"); } $channel = isset($options['channel']) ? $options['channel'] : $this->config->get('default_channel'); $reg = &$this->config->getRegistry(); if (!$reg->channelExists($channel)) { return $this->raiseError('Channel "' . $channel . '" does not exist'); } $channel = $reg->channelName($channel); if ($params[0] == 'default_channel' && !$reg->channelExists($params[1])) { return $this->raiseError('Channel "' . $params[1] . '" does not exist'); } if ($params[0] == 'preferred_mirror' && ( !$reg->mirrorExists($channel, $params[1]) && (!$reg->channelExists($params[1]) || $channel != $params[1]) ) ) { $msg = 'Channel Mirror "' . $params[1] . '" does not exist'; $msg .= ' in your registry for channel "' . $channel . '".'; $msg .= "\n" . 'Attempt to run "pear channel-update ' . $channel .'"'; $msg .= ' if you believe this mirror should exist as you may'; $msg .= ' have outdated channel information.'; return $this->raiseError($msg); } if (count($params) == 2) { array_push($params, 'user'); $layer = 'user'; } else { $layer = $params[2]; } array_push($params, $channel); if (!call_user_func_array(array(&$this->config, 'set'), $params)) { array_pop($params); $failmsg = "config-set (" . implode(", ", $params) . ") failed, channel $channel"; } else { $this->config->store($layer); } if ($failmsg) { return $this->raiseError($failmsg); } $this->ui->outputData('config-set succeeded', $command); return true; } function doConfigHelp($command, $options, $params) { if (empty($params)) { $params = $this->config->getKeys(); } $data['caption'] = "Config help" . ((count($params) == 1) ? " for $params[0]" : ''); $data['headline'] = array('Name', 'Type', 'Description'); $data['border'] = true; foreach ($params as $name) { $type = $this->config->getType($name); $docs = $this->config->getDocs($name); if ($type == 'set') { $docs = rtrim($docs) . "\nValid set: " . implode(' ', $this->config->getSetValues($name)); } $data['data'][] = array($name, $type, $docs); } $this->ui->outputData($data, $command); } function doConfigCreate($command, $options, $params) { if (count($params) != 2) { return PEAR::raiseError('config-create: must have 2 parameters, root path and ' . 'filename to save as'); } $root = $params[0]; // Clean up the DIRECTORY_SEPARATOR mess $ds2 = DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR; $root = preg_replace(array('!\\\\+!', '!/+!', "!$ds2+!"), array('/', '/', '/'), $root); if ($root[0] != '/') { if (!isset($options['windows'])) { return PEAR::raiseError('Root directory must be an absolute path beginning ' . 'with "/", was: "' . $root . '"'); } if (!preg_match('/^[A-Za-z]:/', $root)) { return PEAR::raiseError('Root directory must be an absolute path beginning ' . 'with "\\" or "C:\\", was: "' . $root . '"'); } } $windows = isset($options['windows']); if ($windows) { $root = str_replace('/', '\\', $root); } if (!file_exists($params[1]) && !@touch($params[1])) { return PEAR::raiseError('Could not create "' . $params[1] . '"'); } $params[1] = realpath($params[1]); $config = new PEAR_Config($params[1], '#no#system#config#', false, false); if ($root[strlen($root) - 1] == '/') { $root = substr($root, 0, strlen($root) - 1); } $config->noRegistry(); $config->set('php_dir', $windows ? "$root\\pear\\php" : "$root/pear/php", 'user'); $config->set('data_dir', $windows ? "$root\\pear\\data" : "$root/pear/data"); $config->set('www_dir', $windows ? "$root\\pear\\www" : "$root/pear/www"); $config->set('cfg_dir', $windows ? "$root\\pear\\cfg" : "$root/pear/cfg"); $config->set('ext_dir', $windows ? "$root\\pear\\ext" : "$root/pear/ext"); $config->set('doc_dir', $windows ? "$root\\pear\\docs" : "$root/pear/docs"); $config->set('test_dir', $windows ? "$root\\pear\\tests" : "$root/pear/tests"); $config->set('cache_dir', $windows ? "$root\\pear\\cache" : "$root/pear/cache"); $config->set('download_dir', $windows ? "$root\\pear\\download" : "$root/pear/download"); $config->set('temp_dir', $windows ? "$root\\pear\\temp" : "$root/pear/temp"); $config->set('bin_dir', $windows ? "$root\\pear" : "$root/pear"); $config->set('man_dir', $windows ? "$root\\pear\\man" : "$root/pear/man"); $config->writeConfigFile(); $this->_showConfig($config); $this->ui->outputData('Successfully created default configuration file "' . $params[1] . '"', $command); } function _showConfig(&$config) { $params = array('user'); $keys = $config->getKeys(); sort($keys); $channel = 'pear.php.net'; $data = array('caption' => 'Configuration (channel ' . $channel . '):'); foreach ($keys as $key) { $type = $config->getType($key); $value = $config->get($key, 'user', $channel); if ($type == 'password' && $value) { $value = '********'; } if ($value === false) { $value = 'false'; } elseif ($value === true) { $value = 'true'; } $data['data'][$config->getGroup($key)][] = array($config->getPrompt($key) , $key, $value); } foreach ($config->getLayers() as $layer) { $data['data']['Config Files'][] = array(ucfirst($layer) . ' Configuration File', 'Filename' , $config->getConfFile($layer)); } $this->ui->outputData($data, 'config-show'); return true; } /** * Checks if a layer is defined or not * * @param string $layer The layer to search for * @return mixed False on no error or the error message */ function _checkLayer($layer = null) { if (!empty($layer) && $layer != 'default') { $layers = $this->config->getLayers(); if (!in_array($layer, $layers)) { return " only the layers: \"" . implode('" or "', $layers) . "\" are supported"; } } return false; } } PKu]%sp  PEAR/Command/Common.phpnu[ * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 0.1 */ /** * base class */ require_once 'PEAR.php'; /** * PEAR commands base class * * @category pear * @package PEAR * @author Stig Bakken * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 0.1 */ class PEAR_Command_Common extends PEAR { /** * PEAR_Config object used to pass user system and configuration * on when executing commands * * @var PEAR_Config */ var $config; /** * @var PEAR_Registry * @access protected */ var $_registry; /** * User Interface object, for all interaction with the user. * @var object */ var $ui; var $_deps_rel_trans = array( 'lt' => '<', 'le' => '<=', 'eq' => '=', 'ne' => '!=', 'gt' => '>', 'ge' => '>=', 'has' => '==' ); var $_deps_type_trans = array( 'pkg' => 'package', 'ext' => 'extension', 'php' => 'PHP', 'prog' => 'external program', 'ldlib' => 'external library for linking', 'rtlib' => 'external runtime library', 'os' => 'operating system', 'websrv' => 'web server', 'sapi' => 'SAPI backend' ); /** * PEAR_Command_Common constructor. * * @access public */ function __construct(&$ui, &$config) { parent::__construct(); $this->config = &$config; $this->ui = &$ui; } /** * Return a list of all the commands defined by this class. * @return array list of commands * @access public */ function getCommands() { $ret = array(); foreach (array_keys($this->commands) as $command) { $ret[$command] = $this->commands[$command]['summary']; } return $ret; } /** * Return a list of all the command shortcuts defined by this class. * @return array shortcut => command * @access public */ function getShortcuts() { $ret = array(); foreach (array_keys($this->commands) as $command) { if (isset($this->commands[$command]['shortcut'])) { $ret[$this->commands[$command]['shortcut']] = $command; } } return $ret; } function getOptions($command) { $shortcuts = $this->getShortcuts(); if (isset($shortcuts[$command])) { $command = $shortcuts[$command]; } if (isset($this->commands[$command]) && isset($this->commands[$command]['options'])) { return $this->commands[$command]['options']; } return null; } function getGetoptArgs($command, &$short_args, &$long_args) { $short_args = ''; $long_args = array(); if (empty($this->commands[$command]) || empty($this->commands[$command]['options'])) { return; } reset($this->commands[$command]['options']); foreach ($this->commands[$command]['options'] as $option => $info) { $larg = $sarg = ''; if (isset($info['arg'])) { if ($info['arg'][0] == '(') { $larg = '=='; $sarg = '::'; $arg = substr($info['arg'], 1, -1); } else { $larg = '='; $sarg = ':'; $arg = $info['arg']; } } if (isset($info['shortopt'])) { $short_args .= $info['shortopt'] . $sarg; } $long_args[] = $option . $larg; } } /** * Returns the help message for the given command * * @param string $command The command * @return mixed A fail string if the command does not have help or * a two elements array containing [0]=>help string, * [1]=> help string for the accepted cmd args */ function getHelp($command) { $config = &PEAR_Config::singleton(); if (!isset($this->commands[$command])) { return "No such command \"$command\""; } $help = null; if (isset($this->commands[$command]['doc'])) { $help = $this->commands[$command]['doc']; } if (empty($help)) { // XXX (cox) Fallback to summary if there is no doc (show both?) if (!isset($this->commands[$command]['summary'])) { return "No help for command \"$command\""; } $help = $this->commands[$command]['summary']; } if (preg_match_all('/{config\s+([^\}]+)}/', $help, $matches)) { foreach($matches[0] as $k => $v) { $help = preg_replace("/$v/", $config->get($matches[1][$k]), $help); } } return array($help, $this->getHelpArgs($command)); } /** * Returns the help for the accepted arguments of a command * * @param string $command * @return string The help string */ function getHelpArgs($command) { if (isset($this->commands[$command]['options']) && count($this->commands[$command]['options'])) { $help = "Options:\n"; foreach ($this->commands[$command]['options'] as $k => $v) { if (isset($v['arg'])) { if ($v['arg'][0] == '(') { $arg = substr($v['arg'], 1, -1); $sapp = " [$arg]"; $lapp = "[=$arg]"; } else { $sapp = " $v[arg]"; $lapp = "=$v[arg]"; } } else { $sapp = $lapp = ""; } if (isset($v['shortopt'])) { $s = $v['shortopt']; $help .= " -$s$sapp, --$k$lapp\n"; } else { $help .= " --$k$lapp\n"; } $p = " "; $doc = rtrim(str_replace("\n", "\n$p", $v['doc'])); $help .= " $doc\n"; } return $help; } return null; } function run($command, $options, $params) { if (empty($this->commands[$command]['function'])) { // look for shortcuts foreach (array_keys($this->commands) as $cmd) { if (isset($this->commands[$cmd]['shortcut']) && $this->commands[$cmd]['shortcut'] == $command) { if (empty($this->commands[$cmd]['function'])) { return $this->raiseError("unknown command `$command'"); } else { $func = $this->commands[$cmd]['function']; } $command = $cmd; //$command = $this->commands[$cmd]['function']; break; } } } else { $func = $this->commands[$command]['function']; } return $this->$func($command, $options, $params); } } PKu]nmi?;;PEAR/Command/Install.phpnu[ * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 0.1 */ /** * base class */ require_once 'PEAR/Command/Common.php'; /** * PEAR commands for installation or deinstallation/upgrading of * packages. * * @category pear * @package PEAR * @author Stig Bakken * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 0.1 */ class PEAR_Command_Install extends PEAR_Command_Common { // {{{ properties var $commands = array( 'install' => array( 'summary' => 'Install Package', 'function' => 'doInstall', 'shortcut' => 'i', 'options' => array( 'force' => array( 'shortopt' => 'f', 'doc' => 'will overwrite newer installed packages', ), 'loose' => array( 'shortopt' => 'l', 'doc' => 'do not check for recommended dependency version', ), 'nodeps' => array( 'shortopt' => 'n', 'doc' => 'ignore dependencies, install anyway', ), 'register-only' => array( 'shortopt' => 'r', 'doc' => 'do not install files, only register the package as installed', ), 'soft' => array( 'shortopt' => 's', 'doc' => 'soft install, fail silently, or upgrade if already installed', ), 'nobuild' => array( 'shortopt' => 'B', 'doc' => 'don\'t build C extensions', ), 'configureoptions' => array( 'shortopt' => 'D', 'arg' => 'OPTION1=VALUE[ OPTION2=VALUE]', 'doc' => 'space-delimited list of configure options', ), 'nocompress' => array( 'shortopt' => 'Z', 'doc' => 'request uncompressed files when downloading', ), 'installroot' => array( 'shortopt' => 'R', 'arg' => 'DIR', 'doc' => 'root directory used when installing files (ala PHP\'s INSTALL_ROOT), use packagingroot for RPM', ), 'packagingroot' => array( 'shortopt' => 'P', 'arg' => 'DIR', 'doc' => 'root directory used when packaging files, like RPM packaging', ), 'ignore-errors' => array( 'doc' => 'force install even if there were errors', ), 'alldeps' => array( 'shortopt' => 'a', 'doc' => 'install all required and optional dependencies', ), 'onlyreqdeps' => array( 'shortopt' => 'o', 'doc' => 'install all required dependencies', ), 'offline' => array( 'shortopt' => 'O', 'doc' => 'do not attempt to download any urls or contact channels', ), 'pretend' => array( 'shortopt' => 'p', 'doc' => 'Only list the packages that would be downloaded', ), ), 'doc' => '[channel/] ... Installs one or more PEAR packages. You can specify a package to install in four ways: "Package-1.0.tgz" : installs from a local file "http://example.com/Package-1.0.tgz" : installs from anywhere on the net. "package.xml" : installs the package described in package.xml. Useful for testing, or for wrapping a PEAR package in another package manager such as RPM. "Package[-version/state][.tar]" : queries your default channel\'s server ({config master_server}) and downloads the newest package with the preferred quality/state ({config preferred_state}). To retrieve Package version 1.1, use "Package-1.1," to retrieve Package state beta, use "Package-beta." To retrieve an uncompressed file, append .tar (make sure there is no file by the same name first) To download a package from another channel, prefix with the channel name like "channel/Package" More than one package may be specified at once. It is ok to mix these four ways of specifying packages. '), 'upgrade' => array( 'summary' => 'Upgrade Package', 'function' => 'doInstall', 'shortcut' => 'up', 'options' => array( 'channel' => array( 'shortopt' => 'c', 'doc' => 'upgrade packages from a specific channel', 'arg' => 'CHAN', ), 'force' => array( 'shortopt' => 'f', 'doc' => 'overwrite newer installed packages', ), 'loose' => array( 'shortopt' => 'l', 'doc' => 'do not check for recommended dependency version', ), 'nodeps' => array( 'shortopt' => 'n', 'doc' => 'ignore dependencies, upgrade anyway', ), 'register-only' => array( 'shortopt' => 'r', 'doc' => 'do not install files, only register the package as upgraded', ), 'nobuild' => array( 'shortopt' => 'B', 'doc' => 'don\'t build C extensions', ), 'nocompress' => array( 'shortopt' => 'Z', 'doc' => 'request uncompressed files when downloading', ), 'installroot' => array( 'shortopt' => 'R', 'arg' => 'DIR', 'doc' => 'root directory used when installing files (ala PHP\'s INSTALL_ROOT)', ), 'ignore-errors' => array( 'doc' => 'force install even if there were errors', ), 'alldeps' => array( 'shortopt' => 'a', 'doc' => 'install all required and optional dependencies', ), 'onlyreqdeps' => array( 'shortopt' => 'o', 'doc' => 'install all required dependencies', ), 'offline' => array( 'shortopt' => 'O', 'doc' => 'do not attempt to download any urls or contact channels', ), 'pretend' => array( 'shortopt' => 'p', 'doc' => 'Only list the packages that would be downloaded', ), ), 'doc' => ' ... Upgrades one or more PEAR packages. See documentation for the "install" command for ways to specify a package. When upgrading, your package will be updated if the provided new package has a higher version number (use the -f option if you need to upgrade anyway). More than one package may be specified at once. '), 'upgrade-all' => array( 'summary' => 'Upgrade All Packages [Deprecated in favor of calling upgrade with no parameters]', 'function' => 'doUpgradeAll', 'shortcut' => 'ua', 'options' => array( 'channel' => array( 'shortopt' => 'c', 'doc' => 'upgrade packages from a specific channel', 'arg' => 'CHAN', ), 'nodeps' => array( 'shortopt' => 'n', 'doc' => 'ignore dependencies, upgrade anyway', ), 'register-only' => array( 'shortopt' => 'r', 'doc' => 'do not install files, only register the package as upgraded', ), 'nobuild' => array( 'shortopt' => 'B', 'doc' => 'don\'t build C extensions', ), 'nocompress' => array( 'shortopt' => 'Z', 'doc' => 'request uncompressed files when downloading', ), 'installroot' => array( 'shortopt' => 'R', 'arg' => 'DIR', 'doc' => 'root directory used when installing files (ala PHP\'s INSTALL_ROOT), use packagingroot for RPM', ), 'ignore-errors' => array( 'doc' => 'force install even if there were errors', ), 'loose' => array( 'doc' => 'do not check for recommended dependency version', ), ), 'doc' => ' WARNING: This function is deprecated in favor of using the upgrade command with no params Upgrades all packages that have a newer release available. Upgrades are done only if there is a release available of the state specified in "preferred_state" (currently {config preferred_state}), or a state considered more stable. '), 'uninstall' => array( 'summary' => 'Un-install Package', 'function' => 'doUninstall', 'shortcut' => 'un', 'options' => array( 'nodeps' => array( 'shortopt' => 'n', 'doc' => 'ignore dependencies, uninstall anyway', ), 'register-only' => array( 'shortopt' => 'r', 'doc' => 'do not remove files, only register the packages as not installed', ), 'installroot' => array( 'shortopt' => 'R', 'arg' => 'DIR', 'doc' => 'root directory used when installing files (ala PHP\'s INSTALL_ROOT)', ), 'ignore-errors' => array( 'doc' => 'force install even if there were errors', ), 'offline' => array( 'shortopt' => 'O', 'doc' => 'do not attempt to uninstall remotely', ), ), 'doc' => '[channel/] ... Uninstalls one or more PEAR packages. More than one package may be specified at once. Prefix with channel name to uninstall from a channel not in your default channel ({config default_channel}) '), 'bundle' => array( 'summary' => 'Unpacks a Pecl Package', 'function' => 'doBundle', 'shortcut' => 'bun', 'options' => array( 'destination' => array( 'shortopt' => 'd', 'arg' => 'DIR', 'doc' => 'Optional destination directory for unpacking (defaults to current path or "ext" if exists)', ), 'force' => array( 'shortopt' => 'f', 'doc' => 'Force the unpacking even if there were errors in the package', ), ), 'doc' => ' Unpacks a Pecl Package into the selected location. It will download the package if needed. '), 'run-scripts' => array( 'summary' => 'Run Post-Install Scripts bundled with a package', 'function' => 'doRunScripts', 'shortcut' => 'rs', 'options' => array( ), 'doc' => ' Run post-installation scripts in package , if any exist. '), ); // }}} // {{{ constructor /** * PEAR_Command_Install constructor. * * @access public */ function __construct(&$ui, &$config) { parent::__construct($ui, $config); } // }}} /** * For unit testing purposes */ function &getDownloader(&$ui, $options, &$config) { if (!class_exists('PEAR_Downloader')) { require_once 'PEAR/Downloader.php'; } $a = new PEAR_Downloader($ui, $options, $config); return $a; } /** * For unit testing purposes */ function &getInstaller(&$ui) { if (!class_exists('PEAR_Installer')) { require_once 'PEAR/Installer.php'; } $a = new PEAR_Installer($ui); return $a; } function enableExtension($binaries, $type) { if (!($phpini = $this->config->get('php_ini', null, 'pear.php.net'))) { return PEAR::raiseError('configuration option "php_ini" is not set to php.ini location'); } $ini = $this->_parseIni($phpini); if (PEAR::isError($ini)) { return $ini; } $line = 0; if ($type == 'extsrc' || $type == 'extbin') { $search = 'extensions'; $enable = 'extension'; } else { $search = 'zend_extensions'; ob_start(); phpinfo(INFO_GENERAL); $info = ob_get_contents(); ob_end_clean(); $debug = function_exists('leak') ? '_debug' : ''; $ts = preg_match('/Thread Safety.+enabled/', $info) ? '_ts' : ''; $enable = 'zend_extension' . $debug . $ts; } foreach ($ini[$search] as $line => $extension) { if (in_array($extension, $binaries, true) || in_array( $ini['extension_dir'] . DIRECTORY_SEPARATOR . $extension, $binaries, true)) { // already enabled - assume if one is, all are return true; } } if ($line) { $newini = array_slice($ini['all'], 0, $line); } else { $newini = array(); } foreach ($binaries as $binary) { if ($ini['extension_dir']) { $binary = basename($binary); } $newini[] = $enable . '="' . $binary . '"' . (OS_UNIX ? "\n" : "\r\n"); } $newini = array_merge($newini, array_slice($ini['all'], $line)); $fp = @fopen($phpini, 'wb'); if (!$fp) { return PEAR::raiseError('cannot open php.ini "' . $phpini . '" for writing'); } foreach ($newini as $line) { fwrite($fp, $line); } fclose($fp); return true; } function disableExtension($binaries, $type) { if (!($phpini = $this->config->get('php_ini', null, 'pear.php.net'))) { return PEAR::raiseError('configuration option "php_ini" is not set to php.ini location'); } $ini = $this->_parseIni($phpini); if (PEAR::isError($ini)) { return $ini; } $line = 0; if ($type == 'extsrc' || $type == 'extbin') { $search = 'extensions'; $enable = 'extension'; } else { $search = 'zend_extensions'; ob_start(); phpinfo(INFO_GENERAL); $info = ob_get_contents(); ob_end_clean(); $debug = function_exists('leak') ? '_debug' : ''; $ts = preg_match('/Thread Safety.+enabled/', $info) ? '_ts' : ''; $enable = 'zend_extension' . $debug . $ts; } $found = false; foreach ($ini[$search] as $line => $extension) { if (in_array($extension, $binaries, true) || in_array( $ini['extension_dir'] . DIRECTORY_SEPARATOR . $extension, $binaries, true)) { $found = true; break; } } if (!$found) { // not enabled return true; } $fp = @fopen($phpini, 'wb'); if (!$fp) { return PEAR::raiseError('cannot open php.ini "' . $phpini . '" for writing'); } if ($line) { $newini = array_slice($ini['all'], 0, $line); // delete the enable line $newini = array_merge($newini, array_slice($ini['all'], $line + 1)); } else { $newini = array_slice($ini['all'], 1); } foreach ($newini as $line) { fwrite($fp, $line); } fclose($fp); return true; } function _parseIni($filename) { if (!file_exists($filename)) { return PEAR::raiseError('php.ini "' . $filename . '" does not exist'); } if (filesize($filename) > 300000) { return PEAR::raiseError('php.ini "' . $filename . '" is too large, aborting'); } ob_start(); phpinfo(INFO_GENERAL); $info = ob_get_contents(); ob_end_clean(); $debug = function_exists('leak') ? '_debug' : ''; $ts = preg_match('/Thread Safety.+enabled/', $info) ? '_ts' : ''; $zend_extension_line = 'zend_extension' . $debug . $ts; $all = @file($filename); if ($all === false) { return PEAR::raiseError('php.ini "' . $filename .'" could not be read'); } $zend_extensions = $extensions = array(); // assume this is right, but pull from the php.ini if it is found $extension_dir = ini_get('extension_dir'); foreach ($all as $linenum => $line) { $line = trim($line); if (!$line) { continue; } if ($line[0] == ';') { continue; } if (strtolower(substr($line, 0, 13)) == 'extension_dir') { $line = trim(substr($line, 13)); if ($line[0] == '=') { $x = trim(substr($line, 1)); $x = explode(';', $x); $extension_dir = str_replace('"', '', array_shift($x)); continue; } } if (strtolower(substr($line, 0, 9)) == 'extension') { $line = trim(substr($line, 9)); if ($line[0] == '=') { $x = trim(substr($line, 1)); $x = explode(';', $x); $extensions[$linenum] = str_replace('"', '', array_shift($x)); continue; } } if (strtolower(substr($line, 0, strlen($zend_extension_line))) == $zend_extension_line) { $line = trim(substr($line, strlen($zend_extension_line))); if ($line[0] == '=') { $x = trim(substr($line, 1)); $x = explode(';', $x); $zend_extensions[$linenum] = str_replace('"', '', array_shift($x)); continue; } } } return array( 'extensions' => $extensions, 'zend_extensions' => $zend_extensions, 'extension_dir' => $extension_dir, 'all' => $all, ); } // {{{ doInstall() function doInstall($command, $options, $params) { if (!class_exists('PEAR_PackageFile')) { require_once 'PEAR/PackageFile.php'; } if (isset($options['installroot']) && isset($options['packagingroot'])) { return $this->raiseError('ERROR: cannot use both --installroot and --packagingroot'); } $reg = &$this->config->getRegistry(); $channel = isset($options['channel']) ? $options['channel'] : $this->config->get('default_channel'); if (!$reg->channelExists($channel)) { return $this->raiseError('Channel "' . $channel . '" does not exist'); } if (empty($this->installer)) { $this->installer = &$this->getInstaller($this->ui); } if ($command == 'upgrade' || $command == 'upgrade-all') { // If people run the upgrade command but pass nothing, emulate a upgrade-all if ($command == 'upgrade' && empty($params)) { return $this->doUpgradeAll($command, $options, $params); } $options['upgrade'] = true; } else { $packages = $params; } $instreg = &$reg; // instreg used to check if package is installed if (isset($options['packagingroot']) && !isset($options['upgrade'])) { $packrootphp_dir = $this->installer->_prependPath( $this->config->get('php_dir', null, 'pear.php.net'), $options['packagingroot']); $metadata_dir = $this->config->get('metadata_dir', null, 'pear.php.net'); if ($metadata_dir) { $metadata_dir = $this->installer->_prependPath( $metadata_dir, $options['packagingroot']); } $instreg = new PEAR_Registry($packrootphp_dir, false, false, $metadata_dir); // other instreg! if ($this->config->get('verbose') > 2) { $this->ui->outputData('using package root: ' . $options['packagingroot']); } } $abstractpackages = $otherpackages = array(); // parse params PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); foreach ($params as $param) { if (strpos($param, 'http://') === 0) { $otherpackages[] = $param; continue; } if (strpos($param, 'channel://') === false && @file_exists($param)) { if (isset($options['force'])) { $otherpackages[] = $param; continue; } $pkg = new PEAR_PackageFile($this->config); $pf = $pkg->fromAnyFile($param, PEAR_VALIDATE_DOWNLOADING); if (PEAR::isError($pf)) { $otherpackages[] = $param; continue; } $exists = $reg->packageExists($pf->getPackage(), $pf->getChannel()); $pversion = $reg->packageInfo($pf->getPackage(), 'version', $pf->getChannel()); $version_compare = version_compare($pf->getVersion(), $pversion, '<='); if ($exists && $version_compare) { if ($this->config->get('verbose')) { $this->ui->outputData('Ignoring installed package ' . $reg->parsedPackageNameToString( array('package' => $pf->getPackage(), 'channel' => $pf->getChannel()), true)); } continue; } $otherpackages[] = $param; continue; } $e = $reg->parsePackageName($param, $channel); if (PEAR::isError($e)) { $otherpackages[] = $param; } else { $abstractpackages[] = $e; } } PEAR::staticPopErrorHandling(); // if there are any local package .tgz or remote static url, we can't // filter. The filter only works for abstract packages if (count($abstractpackages) && !isset($options['force'])) { // when not being forced, only do necessary upgrades/installs if (isset($options['upgrade'])) { $abstractpackages = $this->_filterUptodatePackages($abstractpackages, $command); } else { $count = count($abstractpackages); foreach ($abstractpackages as $i => $package) { if (isset($package['group'])) { // do not filter out install groups continue; } if ($instreg->packageExists($package['package'], $package['channel'])) { if ($count > 1) { if ($this->config->get('verbose')) { $this->ui->outputData('Ignoring installed package ' . $reg->parsedPackageNameToString($package, true)); } unset($abstractpackages[$i]); } elseif ($count === 1) { // Lets try to upgrade it since it's already installed $options['upgrade'] = true; } } } } $abstractpackages = array_map(array($reg, 'parsedPackageNameToString'), $abstractpackages); } elseif (count($abstractpackages)) { $abstractpackages = array_map(array($reg, 'parsedPackageNameToString'), $abstractpackages); } $packages = array_merge($abstractpackages, $otherpackages); if (!count($packages)) { $c = ''; if (isset($options['channel'])){ $c .= ' in channel "' . $options['channel'] . '"'; } $this->ui->outputData('Nothing to ' . $command . $c); return true; } $this->downloader = &$this->getDownloader($this->ui, $options, $this->config); $errors = $downloaded = $binaries = array(); $downloaded = &$this->downloader->download($packages); if (PEAR::isError($downloaded)) { return $this->raiseError($downloaded); } $errors = $this->downloader->getErrorMsgs(); if (count($errors)) { $err = array(); $err['data'] = array(); foreach ($errors as $error) { if ($error !== null) { $err['data'][] = array($error); } } if (!empty($err['data'])) { $err['headline'] = 'Install Errors'; $this->ui->outputData($err); } if (!count($downloaded)) { return $this->raiseError("$command failed"); } } $data = array( 'headline' => 'Packages that would be Installed' ); if (isset($options['pretend'])) { foreach ($downloaded as $package) { $data['data'][] = array($reg->parsedPackageNameToString($package->getParsedPackage())); } $this->ui->outputData($data, 'pretend'); return true; } $this->installer->setOptions($options); $this->installer->sortPackagesForInstall($downloaded); if (PEAR::isError($err = $this->installer->setDownloadedPackages($downloaded))) { $this->raiseError($err->getMessage()); return true; } $binaries = $extrainfo = array(); foreach ($downloaded as $param) { PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); $info = $this->installer->install($param, $options); PEAR::staticPopErrorHandling(); if (PEAR::isError($info)) { $oldinfo = $info; $pkg = &$param->getPackageFile(); if ($info->getCode() != PEAR_INSTALLER_NOBINARY) { if (!($info = $pkg->installBinary($this->installer))) { return $this->raiseError('ERROR: ' .$oldinfo->getMessage()); } // we just installed a different package than requested, // let's change the param and info so that the rest of this works $param = $info[0]; $info = $info[1]; } } if (!is_array($info)) { return $this->raiseError("$command failed"); } if ($param->getPackageType() == 'extsrc' || $param->getPackageType() == 'extbin' || $param->getPackageType() == 'zendextsrc' || $param->getPackageType() == 'zendextbin' ) { $pkg = &$param->getPackageFile(); if ($instbin = $pkg->getInstalledBinary()) { $instpkg = &$instreg->getPackage($instbin, $pkg->getChannel()); } else { $instpkg = &$instreg->getPackage($pkg->getPackage(), $pkg->getChannel()); } foreach ($instpkg->getFilelist() as $name => $atts) { $pinfo = pathinfo($atts['installed_as']); if (!isset($pinfo['extension']) || in_array($pinfo['extension'], array('c', 'h')) ) { continue; // make sure we don't match php_blah.h } if ((strpos($pinfo['basename'], 'php_') === 0 && $pinfo['extension'] == 'dll') || // most unices $pinfo['extension'] == 'so' || // hp-ux $pinfo['extension'] == 'sl') { $binaries[] = array($atts['installed_as'], $pinfo); break; } } if (count($binaries)) { foreach ($binaries as $pinfo) { PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); $ret = $this->enableExtension(array($pinfo[0]), $param->getPackageType()); PEAR::staticPopErrorHandling(); if (PEAR::isError($ret)) { $extrainfo[] = $ret->getMessage(); if ($param->getPackageType() == 'extsrc' || $param->getPackageType() == 'extbin') { $exttype = 'extension'; $extpath = $pinfo[1]['basename']; } else { $exttype = 'zend_extension'; $extpath = $atts['installed_as']; } $extrainfo[] = 'You should add "' . $exttype . '=' . $extpath . '" to php.ini'; } else { $extrainfo[] = 'Extension ' . $instpkg->getProvidesExtension() . ' enabled in php.ini'; } } } } if ($this->config->get('verbose') > 0) { $chan = $param->getChannel(); $label = $reg->parsedPackageNameToString( array( 'channel' => $chan, 'package' => $param->getPackage(), 'version' => $param->getVersion(), )); $out = array('data' => "$command ok: $label"); if (isset($info['release_warnings'])) { $out['release_warnings'] = $info['release_warnings']; } $this->ui->outputData($out, $command); if (!isset($options['register-only']) && !isset($options['offline'])) { if ($this->config->isDefinedLayer('ftp')) { PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); $info = $this->installer->ftpInstall($param); PEAR::staticPopErrorHandling(); if (PEAR::isError($info)) { $this->ui->outputData($info->getMessage()); $this->ui->outputData("remote install failed: $label"); } else { $this->ui->outputData("remote install ok: $label"); } } } } $deps = $param->getDeps(); if ($deps) { if (isset($deps['group'])) { $groups = $deps['group']; if (!isset($groups[0])) { $groups = array($groups); } foreach ($groups as $group) { if ($group['attribs']['name'] == 'default') { // default group is always installed, unless the user // explicitly chooses to install another group continue; } $extrainfo[] = $param->getPackage() . ': Optional feature ' . $group['attribs']['name'] . ' available (' . $group['attribs']['hint'] . ')'; } $extrainfo[] = $param->getPackage() . ': To install optional features use "pear install ' . $reg->parsedPackageNameToString( array('package' => $param->getPackage(), 'channel' => $param->getChannel()), true) . '#featurename"'; } } $pkg = &$instreg->getPackage($param->getPackage(), $param->getChannel()); // $pkg may be NULL if install is a 'fake' install via --packagingroot if (is_object($pkg)) { $pkg->setConfig($this->config); if ($list = $pkg->listPostinstallScripts()) { $pn = $reg->parsedPackageNameToString(array('channel' => $param->getChannel(), 'package' => $param->getPackage()), true); $extrainfo[] = $pn . ' has post-install scripts:'; foreach ($list as $file) { $extrainfo[] = $file; } $extrainfo[] = $param->getPackage() . ': Use "pear run-scripts ' . $pn . '" to finish setup.'; $extrainfo[] = 'DO NOT RUN SCRIPTS FROM UNTRUSTED SOURCES'; } } } if (count($extrainfo)) { foreach ($extrainfo as $info) { $this->ui->outputData($info); } } return true; } // }}} // {{{ doUpgradeAll() function doUpgradeAll($command, $options, $params) { $reg = &$this->config->getRegistry(); $upgrade = array(); if (isset($options['channel'])) { $channels = array($options['channel']); } else { $channels = $reg->listChannels(); } foreach ($channels as $channel) { if ($channel == '__uri') { continue; } // parse name with channel foreach ($reg->listPackages($channel) as $name) { $upgrade[] = $reg->parsedPackageNameToString(array( 'channel' => $channel, 'package' => $name )); } } $err = $this->doInstall($command, $options, $upgrade); if (PEAR::isError($err)) { $this->ui->outputData($err->getMessage(), $command); } } // }}} // {{{ doUninstall() function doUninstall($command, $options, $params) { if (count($params) < 1) { return $this->raiseError("Please supply the package(s) you want to uninstall"); } if (empty($this->installer)) { $this->installer = &$this->getInstaller($this->ui); } if (isset($options['remoteconfig'])) { $e = $this->config->readFTPConfigFile($options['remoteconfig']); if (!PEAR::isError($e)) { $this->installer->setConfig($this->config); } } $reg = &$this->config->getRegistry(); $newparams = array(); $binaries = array(); $badparams = array(); foreach ($params as $pkg) { $channel = $this->config->get('default_channel'); PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); $parsed = $reg->parsePackageName($pkg, $channel); PEAR::staticPopErrorHandling(); if (!$parsed || PEAR::isError($parsed)) { $badparams[] = $pkg; continue; } $package = $parsed['package']; $channel = $parsed['channel']; $info = &$reg->getPackage($package, $channel); if ($info === null && ($channel == 'pear.php.net' || $channel == 'pecl.php.net')) { // make sure this isn't a package that has flipped from pear to pecl but // used a package.xml 1.0 $testc = ($channel == 'pear.php.net') ? 'pecl.php.net' : 'pear.php.net'; $info = &$reg->getPackage($package, $testc); if ($info !== null) { $channel = $testc; } } if ($info === null) { $badparams[] = $pkg; } else { $newparams[] = &$info; // check for binary packages (this is an alias for those packages if so) if ($installedbinary = $info->getInstalledBinary()) { $this->ui->log('adding binary package ' . $reg->parsedPackageNameToString(array('channel' => $channel, 'package' => $installedbinary), true)); $newparams[] = &$reg->getPackage($installedbinary, $channel); } // add the contents of a dependency group to the list of installed packages if (isset($parsed['group'])) { $group = $info->getDependencyGroup($parsed['group']); if ($group) { $installed = $reg->getInstalledGroup($group); if ($installed) { foreach ($installed as $i => $p) { $newparams[] = &$installed[$i]; } } } } } } $err = $this->installer->sortPackagesForUninstall($newparams); if (PEAR::isError($err)) { $this->ui->outputData($err->getMessage(), $command); return true; } $params = $newparams; // twist this to use it to check on whether dependent packages are also being uninstalled // for circular dependencies like subpackages $this->installer->setUninstallPackages($newparams); $params = array_merge($params, $badparams); $binaries = array(); foreach ($params as $pkg) { $this->installer->pushErrorHandling(PEAR_ERROR_RETURN); if ($err = $this->installer->uninstall($pkg, $options)) { $this->installer->popErrorHandling(); if (PEAR::isError($err)) { $this->ui->outputData($err->getMessage(), $command); continue; } if ($pkg->getPackageType() == 'extsrc' || $pkg->getPackageType() == 'extbin' || $pkg->getPackageType() == 'zendextsrc' || $pkg->getPackageType() == 'zendextbin') { if ($instbin = $pkg->getInstalledBinary()) { continue; // this will be uninstalled later } foreach ($pkg->getFilelist() as $name => $atts) { $pinfo = pathinfo($atts['installed_as']); if (!isset($pinfo['extension']) || in_array($pinfo['extension'], array('c', 'h'))) { continue; // make sure we don't match php_blah.h } if ((strpos($pinfo['basename'], 'php_') === 0 && $pinfo['extension'] == 'dll') || // most unices $pinfo['extension'] == 'so' || // hp-ux $pinfo['extension'] == 'sl') { $binaries[] = array($atts['installed_as'], $pinfo); break; } } if (count($binaries)) { foreach ($binaries as $pinfo) { PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); $ret = $this->disableExtension(array($pinfo[0]), $pkg->getPackageType()); PEAR::staticPopErrorHandling(); if (PEAR::isError($ret)) { $extrainfo[] = $ret->getMessage(); if ($pkg->getPackageType() == 'extsrc' || $pkg->getPackageType() == 'extbin') { $exttype = 'extension'; } else { ob_start(); phpinfo(INFO_GENERAL); $info = ob_get_contents(); ob_end_clean(); $debug = function_exists('leak') ? '_debug' : ''; $ts = preg_match('/Thread Safety.+enabled/', $info) ? '_ts' : ''; $exttype = 'zend_extension' . $debug . $ts; } $this->ui->outputData('Unable to remove "' . $exttype . '=' . $pinfo[1]['basename'] . '" from php.ini', $command); } else { $this->ui->outputData('Extension ' . $pkg->getProvidesExtension() . ' disabled in php.ini', $command); } } } } $savepkg = $pkg; if ($this->config->get('verbose') > 0) { if (is_object($pkg)) { $pkg = $reg->parsedPackageNameToString($pkg); } $this->ui->outputData("uninstall ok: $pkg", $command); } if (!isset($options['offline']) && is_object($savepkg) && defined('PEAR_REMOTEINSTALL_OK')) { if ($this->config->isDefinedLayer('ftp')) { $this->installer->pushErrorHandling(PEAR_ERROR_RETURN); $info = $this->installer->ftpUninstall($savepkg); $this->installer->popErrorHandling(); if (PEAR::isError($info)) { $this->ui->outputData($info->getMessage()); $this->ui->outputData("remote uninstall failed: $pkg"); } else { $this->ui->outputData("remote uninstall ok: $pkg"); } } } } else { $this->installer->popErrorHandling(); if (!is_object($pkg)) { return $this->raiseError("uninstall failed: $pkg"); } $pkg = $reg->parsedPackageNameToString($pkg); } } return true; } // }}} // }}} // {{{ doBundle() /* (cox) It just downloads and untars the package, does not do any check that the PEAR_Installer::_installFile() does. */ function doBundle($command, $options, $params) { $opts = array( 'force' => true, 'nodeps' => true, 'soft' => true, 'downloadonly' => true ); $downloader = &$this->getDownloader($this->ui, $opts, $this->config); $reg = &$this->config->getRegistry(); if (count($params) < 1) { return $this->raiseError("Please supply the package you want to bundle"); } if (isset($options['destination'])) { if (!is_dir($options['destination'])) { System::mkdir('-p ' . $options['destination']); } $dest = realpath($options['destination']); } else { $pwd = getcwd(); $dir = $pwd . DIRECTORY_SEPARATOR . 'ext'; $dest = is_dir($dir) ? $dir : $pwd; } PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); $err = $downloader->setDownloadDir($dest); PEAR::staticPopErrorHandling(); if (PEAR::isError($err)) { return PEAR::raiseError('download directory "' . $dest . '" is not writeable.'); } $result = &$downloader->download(array($params[0])); if (PEAR::isError($result)) { return $result; } if (!isset($result[0])) { return $this->raiseError('unable to unpack ' . $params[0]); } $pkgfile = &$result[0]->getPackageFile(); $pkgname = $pkgfile->getName(); $pkgversion = $pkgfile->getVersion(); // Unpacking ------------------------------------------------- $dest .= DIRECTORY_SEPARATOR . $pkgname; $orig = $pkgname . '-' . $pkgversion; $tar = new Archive_Tar($pkgfile->getArchiveFile()); if (!$tar->extractModify($dest, $orig)) { return $this->raiseError('unable to unpack ' . $pkgfile->getArchiveFile()); } $this->ui->outputData("Package ready at '$dest'"); // }}} } // }}} function doRunScripts($command, $options, $params) { if (!isset($params[0])) { return $this->raiseError('run-scripts expects 1 parameter: a package name'); } $reg = &$this->config->getRegistry(); PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); $parsed = $reg->parsePackageName($params[0], $this->config->get('default_channel')); PEAR::staticPopErrorHandling(); if (PEAR::isError($parsed)) { return $this->raiseError($parsed); } $package = &$reg->getPackage($parsed['package'], $parsed['channel']); if (!is_object($package)) { return $this->raiseError('Could not retrieve package "' . $params[0] . '" from registry'); } $package->setConfig($this->config); $package->runPostinstallScripts(); $this->ui->outputData('Install scripts complete', $command); return true; } /** * Given a list of packages, filter out those ones that are already up to date * * @param $packages: packages, in parsed array format ! * @return list of packages that can be upgraded */ function _filterUptodatePackages($packages, $command) { $reg = &$this->config->getRegistry(); $latestReleases = array(); $ret = array(); foreach ($packages as $package) { if (isset($package['group'])) { $ret[] = $package; continue; } $channel = $package['channel']; $name = $package['package']; if (!$reg->packageExists($name, $channel)) { $ret[] = $package; continue; } if (!isset($latestReleases[$channel])) { // fill in cache for this channel $chan = $reg->getChannel($channel); if (PEAR::isError($chan)) { return $this->raiseError($chan); } $base2 = false; $preferred_mirror = $this->config->get('preferred_mirror', null, $channel); if ($chan->supportsREST($preferred_mirror) && ( //($base2 = $chan->getBaseURL('REST1.4', $preferred_mirror)) || ($base = $chan->getBaseURL('REST1.0', $preferred_mirror)) ) ) { $dorest = true; } PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); if (!isset($package['state'])) { $state = $this->config->get('preferred_state', null, $channel); } else { $state = $package['state']; } if ($dorest) { if ($base2) { $rest = &$this->config->getREST('1.4', array()); $base = $base2; } else { $rest = &$this->config->getREST('1.0', array()); } $installed = array_flip($reg->listPackages($channel)); $latest = $rest->listLatestUpgrades($base, $state, $installed, $channel, $reg); } PEAR::staticPopErrorHandling(); if (PEAR::isError($latest)) { $this->ui->outputData('Error getting channel info from ' . $channel . ': ' . $latest->getMessage()); continue; } $latestReleases[$channel] = array_change_key_case($latest); } // check package for latest release $name_lower = strtolower($name); if (isset($latestReleases[$channel][$name_lower])) { // if not set, up to date $inst_version = $reg->packageInfo($name, 'version', $channel); $channel_version = $latestReleases[$channel][$name_lower]['version']; if (version_compare($channel_version, $inst_version, 'le')) { // installed version is up-to-date continue; } // maintain BC if ($command == 'upgrade-all') { $this->ui->outputData(array('data' => 'Will upgrade ' . $reg->parsedPackageNameToString($package)), $command); } $ret[] = $package; } } return $ret; } } PKu]wzzPEAR/Command/Channels.xmlnu[ List Available Channels doList lc List all available channels for installation. Update the Channel List doUpdateAll uc List all installed packages in all channels. Remove a Channel From the List doDelete cde <channel name> Delete a channel from the registry. You may not remove any channel that has installed packages. Add a Channel doAdd ca <channel.xml> Add a private channel to the channel list. Note that all public channels should be synced using "update-channels". Parameter may be either a local file or remote URL to a channel.xml. Update an Existing Channel doUpdate cu f will force download of new channel.xml if an existing channel name is used c will force download of new channel.xml if an existing channel name is used CHANNEL [<channel.xml>|<channel name>] Update a channel in the channel list directly. Note that all public channels can be synced using "update-channels". Parameter may be a local or remote channel.xml, or the name of an existing channel. Retrieve Information on a Channel doInfo ci <package> List the files in an installed package. Specify an alias to a channel name doAlias cha <channel> <alias> Specify a specific alias to use for a channel name. The alias may not be an existing channel name or alias. Initialize a Channel from its server doDiscover di [<channel.xml>|<channel name>] Initialize a channel from its server and create a local channel.xml. If <channel name> is in the format "<username>:<password>@<channel>" then <username> and <password> will be set as the login username/password for <channel>. Use caution when passing the username/password in this way, as it may allow other users on your computer to briefly view your username/ password via the system's process list. Connects and authenticates to remote channel server doLogin cli <channel name> Log in to a remote channel server. If <channel name> is not supplied, the default channel is used. To use remote functions in the installer that require any kind of privileges, you need to log in first. The username and password you enter here will be stored in your per-user PEAR configuration (~/.pearrc on Unix-like systems). After logging in, your username and password will be sent along in subsequent operations on the remote server. Logs out from the remote channel server doLogout clo <channel name> Logs out from a remote channel server. If <channel name> is not supplied, the default channel is used. This command does not actually connect to the remote server, it only deletes the stored username and password from your user configuration. PKu]X PEAR/Command/Auth.phpnu[ * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 0.1 * @deprecated since 1.8.0alpha1 */ /** * base class */ require_once 'PEAR/Command/Channels.php'; /** * PEAR commands for login/logout * * @category pear * @package PEAR * @author Stig Bakken * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 0.1 * @deprecated since 1.8.0alpha1 */ class PEAR_Command_Auth extends PEAR_Command_Channels { var $commands = array( 'login' => array( 'summary' => 'Connects and authenticates to remote server [Deprecated in favor of channel-login]', 'shortcut' => 'li', 'function' => 'doLogin', 'options' => array(), 'doc' => ' WARNING: This function is deprecated in favor of using channel-login Log in to a remote channel server. If is not supplied, the default channel is used. To use remote functions in the installer that require any kind of privileges, you need to log in first. The username and password you enter here will be stored in your per-user PEAR configuration (~/.pearrc on Unix-like systems). After logging in, your username and password will be sent along in subsequent operations on the remote server.', ), 'logout' => array( 'summary' => 'Logs out from the remote server [Deprecated in favor of channel-logout]', 'shortcut' => 'lo', 'function' => 'doLogout', 'options' => array(), 'doc' => ' WARNING: This function is deprecated in favor of using channel-logout Logs out from the remote server. This command does not actually connect to the remote server, it only deletes the stored username and password from your user configuration.', ) ); /** * PEAR_Command_Auth constructor. * * @access public */ function __construct(&$ui, &$config) { parent::__construct($ui, $config); } } PKu] MdMdPEAR/Frontend/CLI.phpnu[ * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 0.1 */ /** * base class */ require_once 'PEAR/Frontend.php'; /** * Command-line Frontend for the PEAR Installer * @category pear * @package PEAR * @author Stig Bakken * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 0.1 */ class PEAR_Frontend_CLI extends PEAR_Frontend { /** * What type of user interface this frontend is for. * @var string * @access public */ var $type = 'CLI'; var $lp = ''; // line prefix var $params = array(); var $term = array( 'bold' => '', 'normal' => '', ); function __construct() { parent::__construct(); $term = getenv('TERM'); //(cox) $_ENV is empty for me in 4.1.1 if (function_exists('posix_isatty') && !posix_isatty(1)) { // output is being redirected to a file or through a pipe } elseif ($term) { if (preg_match('/^(xterm|vt220|linux)/', $term)) { $this->term['bold'] = sprintf("%c%c%c%c", 27, 91, 49, 109); $this->term['normal'] = sprintf("%c%c%c", 27, 91, 109); } elseif (preg_match('/^vt100/', $term)) { $this->term['bold'] = sprintf("%c%c%c%c%c%c", 27, 91, 49, 109, 0, 0); $this->term['normal'] = sprintf("%c%c%c%c%c", 27, 91, 109, 0, 0); } } elseif (OS_WINDOWS) { // XXX add ANSI codes here } } /** * @param object PEAR_Error object */ function displayError($e) { return $this->_displayLine($e->getMessage()); } /** * @param object PEAR_Error object */ function displayFatalError($eobj) { $this->displayError($eobj); if (class_exists('PEAR_Config')) { $config = &PEAR_Config::singleton(); if ($config->get('verbose') > 5) { if (function_exists('debug_print_backtrace')) { debug_print_backtrace(); exit(1); } $raised = false; foreach (debug_backtrace() as $i => $frame) { if (!$raised) { if (isset($frame['class']) && strtolower($frame['class']) == 'pear' && strtolower($frame['function']) == 'raiseerror' ) { $raised = true; } else { continue; } } $frame['class'] = !isset($frame['class']) ? '' : $frame['class']; $frame['type'] = !isset($frame['type']) ? '' : $frame['type']; $frame['function'] = !isset($frame['function']) ? '' : $frame['function']; $frame['line'] = !isset($frame['line']) ? '' : $frame['line']; $this->_displayLine("#$i: $frame[class]$frame[type]$frame[function] $frame[line]"); } } } exit(1); } /** * Instruct the runInstallScript method to skip a paramgroup that matches the * id value passed in. * * This method is useful for dynamically configuring which sections of a post-install script * will be run based on the user's setup, which is very useful for making flexible * post-install scripts without losing the cross-Frontend ability to retrieve user input * @param string */ function skipParamgroup($id) { $this->_skipSections[$id] = true; } function runPostinstallScripts(&$scripts) { foreach ($scripts as $i => $script) { $this->runInstallScript($scripts[$i]->_params, $scripts[$i]->_obj); } } /** * @param array $xml contents of postinstallscript tag * @param object $script post-installation script * @param string install|upgrade */ function runInstallScript($xml, &$script) { $this->_skipSections = array(); if (!is_array($xml) || !isset($xml['paramgroup'])) { $script->run(array(), '_default'); return; } $completedPhases = array(); if (!isset($xml['paramgroup'][0])) { $xml['paramgroup'] = array($xml['paramgroup']); } foreach ($xml['paramgroup'] as $group) { if (isset($this->_skipSections[$group['id']])) { // the post-install script chose to skip this section dynamically continue; } if (isset($group['name'])) { $paramname = explode('::', $group['name']); if ($lastgroup['id'] != $paramname[0]) { continue; } $group['name'] = $paramname[1]; if (!isset($answers)) { return; } if (isset($answers[$group['name']])) { switch ($group['conditiontype']) { case '=' : if ($answers[$group['name']] != $group['value']) { continue 2; } break; case '!=' : if ($answers[$group['name']] == $group['value']) { continue 2; } break; case 'preg_match' : if (!@preg_match('/' . $group['value'] . '/', $answers[$group['name']])) { continue 2; } break; default : return; } } } $lastgroup = $group; if (isset($group['instructions'])) { $this->_display($group['instructions']); } if (!isset($group['param'][0])) { $group['param'] = array($group['param']); } if (isset($group['param'])) { if (method_exists($script, 'postProcessPrompts')) { $prompts = $script->postProcessPrompts($group['param'], $group['id']); if (!is_array($prompts) || count($prompts) != count($group['param'])) { $this->outputData('postinstall', 'Error: post-install script did not ' . 'return proper post-processed prompts'); $prompts = $group['param']; } else { foreach ($prompts as $i => $var) { if (!is_array($var) || !isset($var['prompt']) || !isset($var['name']) || ($var['name'] != $group['param'][$i]['name']) || ($var['type'] != $group['param'][$i]['type']) ) { $this->outputData('postinstall', 'Error: post-install script ' . 'modified the variables or prompts, severe security risk. ' . 'Will instead use the defaults from the package.xml'); $prompts = $group['param']; } } } $answers = $this->confirmDialog($prompts); } else { $answers = $this->confirmDialog($group['param']); } } if ((isset($answers) && $answers) || !isset($group['param'])) { if (!isset($answers)) { $answers = array(); } array_unshift($completedPhases, $group['id']); if (!$script->run($answers, $group['id'])) { $script->run($completedPhases, '_undoOnError'); return; } } else { $script->run($completedPhases, '_undoOnError'); return; } } } /** * Ask for user input, confirm the answers and continue until the user is satisfied * @param array an array of arrays, format array('name' => 'paramname', 'prompt' => * 'text to display', 'type' => 'string'[, default => 'default value']) * @return array */ function confirmDialog($params) { $answers = $prompts = $types = array(); foreach ($params as $param) { $prompts[$param['name']] = $param['prompt']; $types[$param['name']] = $param['type']; $answers[$param['name']] = isset($param['default']) ? $param['default'] : ''; } $tried = false; do { if ($tried) { $i = 1; foreach ($answers as $var => $value) { if (!strlen($value)) { echo $this->bold("* Enter an answer for #" . $i . ": ({$prompts[$var]})\n"); } $i++; } } $answers = $this->userDialog('', $prompts, $types, $answers); $tried = true; } while (is_array($answers) && count(array_filter($answers)) != count($prompts)); return $answers; } function userDialog($command, $prompts, $types = array(), $defaults = array(), $screensize = 20) { if (!is_array($prompts)) { return array(); } $testprompts = array_keys($prompts); $result = $defaults; reset($prompts); if (count($prompts) === 1) { foreach ($prompts as $key => $prompt) { $type = $types[$key]; $default = @$defaults[$key]; print "$prompt "; if ($default) { print "[$default] "; } print ": "; $line = fgets(STDIN, 2048); $result[$key] = ($default && trim($line) == '') ? $default : trim($line); } return $result; } $first_run = true; while (true) { $descLength = max(array_map('strlen', $prompts)); $descFormat = "%-{$descLength}s"; $last = count($prompts); $i = 0; foreach ($prompts as $n => $var) { $res = isset($result[$n]) ? $result[$n] : null; printf("%2d. $descFormat : %s\n", ++$i, $prompts[$n], $res); } print "\n1-$last, 'all', 'abort', or Enter to continue: "; $tmp = trim(fgets(STDIN, 1024)); if (empty($tmp)) { break; } if ($tmp == 'abort') { return false; } if (isset($testprompts[(int)$tmp - 1])) { $var = $testprompts[(int)$tmp - 1]; $desc = $prompts[$var]; $current = @$result[$var]; print "$desc [$current] : "; $tmp = trim(fgets(STDIN, 1024)); if ($tmp !== '') { $result[$var] = $tmp; } } elseif ($tmp == 'all') { foreach ($prompts as $var => $desc) { $current = $result[$var]; print "$desc [$current] : "; $tmp = trim(fgets(STDIN, 1024)); if (trim($tmp) !== '') { $result[$var] = trim($tmp); } } } $first_run = false; } return $result; } function userConfirm($prompt, $default = 'yes') { trigger_error("PEAR_Frontend_CLI::userConfirm not yet converted", E_USER_ERROR); static $positives = array('y', 'yes', 'on', '1'); static $negatives = array('n', 'no', 'off', '0'); print "$this->lp$prompt [$default] : "; $fp = fopen("php://stdin", "r"); $line = fgets($fp, 2048); fclose($fp); $answer = strtolower(trim($line)); if (empty($answer)) { $answer = $default; } if (in_array($answer, $positives)) { return true; } if (in_array($answer, $negatives)) { return false; } if (in_array($default, $positives)) { return true; } return false; } function outputData($data, $command = '_default') { switch ($command) { case 'channel-info': foreach ($data as $type => $section) { if ($type == 'main') { $section['data'] = array_values($section['data']); } $this->outputData($section); } break; case 'install': case 'upgrade': case 'upgrade-all': if (is_array($data) && isset($data['release_warnings'])) { $this->_displayLine(''); $this->_startTable(array( 'border' => false, 'caption' => 'Release Warnings' )); $this->_tableRow(array($data['release_warnings']), null, array(1 => array('wrap' => 55))); $this->_endTable(); $this->_displayLine(''); } $this->_displayLine(is_array($data) ? $data['data'] : $data); break; case 'search': $this->_startTable($data); if (isset($data['headline']) && is_array($data['headline'])) { $this->_tableRow($data['headline'], array('bold' => true), array(1 => array('wrap' => 55))); } $packages = array(); foreach($data['data'] as $category) { foreach($category as $name => $pkg) { $packages[$pkg[0]] = $pkg; } } $p = array_keys($packages); natcasesort($p); foreach ($p as $name) { $this->_tableRow($packages[$name], null, array(1 => array('wrap' => 55))); } $this->_endTable(); break; case 'list-all': if (!isset($data['data'])) { $this->_displayLine('No packages in channel'); break; } $this->_startTable($data); if (isset($data['headline']) && is_array($data['headline'])) { $this->_tableRow($data['headline'], array('bold' => true), array(1 => array('wrap' => 55))); } $packages = array(); foreach($data['data'] as $category) { foreach($category as $name => $pkg) { $packages[$pkg[0]] = $pkg; } } $p = array_keys($packages); natcasesort($p); foreach ($p as $name) { $pkg = $packages[$name]; unset($pkg[4], $pkg[5]); $this->_tableRow($pkg, null, array(1 => array('wrap' => 55))); } $this->_endTable(); break; case 'config-show': $data['border'] = false; $opts = array( 0 => array('wrap' => 30), 1 => array('wrap' => 20), 2 => array('wrap' => 35) ); $this->_startTable($data); if (isset($data['headline']) && is_array($data['headline'])) { $this->_tableRow($data['headline'], array('bold' => true), $opts); } foreach ($data['data'] as $group) { foreach ($group as $value) { if ($value[2] == '') { $value[2] = ""; } $this->_tableRow($value, null, $opts); } } $this->_endTable(); break; case 'remote-info': $d = $data; $data = array( 'caption' => 'Package details:', 'border' => false, 'data' => array( array("Latest", $data['stable']), array("Installed", $data['installed']), array("Package", $data['name']), array("License", $data['license']), array("Category", $data['category']), array("Summary", $data['summary']), array("Description", $data['description']), ), ); if (isset($d['deprecated']) && $d['deprecated']) { $conf = &PEAR_Config::singleton(); $reg = $conf->getRegistry(); $name = $reg->parsedPackageNameToString($d['deprecated'], true); $data['data'][] = array('Deprecated! use', $name); } default: { if (is_array($data)) { $this->_startTable($data); $count = count($data['data'][0]); if ($count == 2) { $opts = array(0 => array('wrap' => 25), 1 => array('wrap' => 48) ); } elseif ($count == 3) { $opts = array(0 => array('wrap' => 30), 1 => array('wrap' => 20), 2 => array('wrap' => 35) ); } else { $opts = null; } if (isset($data['headline']) && is_array($data['headline'])) { $this->_tableRow($data['headline'], array('bold' => true), $opts); } if (is_array($data['data'])) { foreach($data['data'] as $row) { $this->_tableRow($row, null, $opts); } } else { $this->_tableRow(array($data['data']), null, $opts); } $this->_endTable(); } else { $this->_displayLine($data); } } } } function log($text, $append_crlf = true) { if ($append_crlf) { return $this->_displayLine($text); } return $this->_display($text); } function bold($text) { if (empty($this->term['bold'])) { return strtoupper($text); } return $this->term['bold'] . $text . $this->term['normal']; } function _displayHeading($title) { print $this->lp.$this->bold($title)."\n"; print $this->lp.str_repeat("=", strlen($title))."\n"; } function _startTable($params = array()) { $params['table_data'] = array(); $params['widest'] = array(); // indexed by column $params['highest'] = array(); // indexed by row $params['ncols'] = 0; $this->params = $params; } function _tableRow($columns, $rowparams = array(), $colparams = array()) { $highest = 1; for ($i = 0; $i < count($columns); $i++) { $col = &$columns[$i]; if (isset($colparams[$i]) && !empty($colparams[$i]['wrap'])) { $col = wordwrap($col, $colparams[$i]['wrap']); } if (strpos($col, "\n") !== false) { $multiline = explode("\n", $col); $w = 0; foreach ($multiline as $n => $line) { $len = strlen($line); if ($len > $w) { $w = $len; } } $lines = count($multiline); } else { $w = strlen($col); } if (isset($this->params['widest'][$i])) { if ($w > $this->params['widest'][$i]) { $this->params['widest'][$i] = $w; } } else { $this->params['widest'][$i] = $w; } $tmp = count_chars($columns[$i], 1); // handle unix, mac and windows formats $lines = (isset($tmp[10]) ? $tmp[10] : (isset($tmp[13]) ? $tmp[13] : 0)) + 1; if ($lines > $highest) { $highest = $lines; } } if (count($columns) > $this->params['ncols']) { $this->params['ncols'] = count($columns); } $new_row = array( 'data' => $columns, 'height' => $highest, 'rowparams' => $rowparams, 'colparams' => $colparams, ); $this->params['table_data'][] = $new_row; } function _endTable() { extract($this->params); if (!empty($caption)) { $this->_displayHeading($caption); } if (count($table_data) === 0) { return; } if (!isset($width)) { $width = $widest; } else { for ($i = 0; $i < $ncols; $i++) { if (!isset($width[$i])) { $width[$i] = $widest[$i]; } } } $border = false; if (empty($border)) { $cellstart = ''; $cellend = ' '; $rowend = ''; $padrowend = false; $borderline = ''; } else { $cellstart = '| '; $cellend = ' '; $rowend = '|'; $padrowend = true; $borderline = '+'; foreach ($width as $w) { $borderline .= str_repeat('-', $w + strlen($cellstart) + strlen($cellend) - 1); $borderline .= '+'; } } if ($borderline) { $this->_displayLine($borderline); } for ($i = 0; $i < count($table_data); $i++) { extract($table_data[$i]); if (!is_array($rowparams)) { $rowparams = array(); } if (!is_array($colparams)) { $colparams = array(); } $rowlines = array(); if ($height > 1) { for ($c = 0; $c < count($data); $c++) { $rowlines[$c] = preg_split('/(\r?\n|\r)/', $data[$c]); if (count($rowlines[$c]) < $height) { $rowlines[$c] = array_pad($rowlines[$c], $height, ''); } } } else { for ($c = 0; $c < count($data); $c++) { $rowlines[$c] = array($data[$c]); } } for ($r = 0; $r < $height; $r++) { $rowtext = ''; for ($c = 0; $c < count($data); $c++) { if (isset($colparams[$c])) { $attribs = array_merge($rowparams, $colparams); } else { $attribs = $rowparams; } $w = isset($width[$c]) ? $width[$c] : 0; //$cell = $data[$c]; $cell = $rowlines[$c][$r]; $l = strlen($cell); if ($l > $w) { $cell = substr($cell, 0, $w); } if (isset($attribs['bold'])) { $cell = $this->bold($cell); } if ($l < $w) { // not using str_pad here because we may // add bold escape characters to $cell $cell .= str_repeat(' ', $w - $l); } $rowtext .= $cellstart . $cell . $cellend; } if (!$border) { $rowtext = rtrim($rowtext); } $rowtext .= $rowend; $this->_displayLine($rowtext); } } if ($borderline) { $this->_displayLine($borderline); } } function _displayLine($text) { print "$this->lp$text\n"; } function _display($text) { print $text; } } PKu] PEAR/Task/Unixeol.phpnu[ * * PHP versions 4 and 5 * * @category pear * @package PEAR * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ /** * Base class */ require_once 'PEAR/Task/Common.php'; /** * Implements the unix line endings file task. * @category pear * @package PEAR * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ class PEAR_Task_Unixeol extends PEAR_Task_Common { public $type = 'simple'; public $phase = PEAR_TASK_PACKAGE; public $_replacements; /** * Validate the raw xml at parsing-time. * * @param PEAR_PackageFile_v2 * @param array raw, parsed xml * @param PEAR_Config */ public static function validateXml($pkg, $xml, $config, $fileXml) { if ($xml != '') { return array(PEAR_TASK_ERROR_INVALID, 'no attributes allowed'); } return true; } /** * Initialize a task instance with the parameters * @param array raw, parsed xml * @param unused * @param unused */ public function init($xml, $attribs, $lastVersion = null) { } /** * Replace all line endings with line endings customized for the current OS * * See validateXml() source for the complete list of allowed fields * * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 * @param string file contents * @param string the eventual final file location (informational only) * @return string|false|PEAR_Error false to skip this file, PEAR_Error to fail * (use $this->throwError), otherwise return the new contents */ public function startSession($pkg, $contents, $dest) { $this->logger->log(3, "replacing all line endings with \\n in $dest"); return preg_replace("/\r\n|\n\r|\r|\n/", "\n", $contents); } } PKu]\kPEAR/Task/Unixeol/rw.phpnu[ - read/write version * * PHP versions 4 and 5 * * @category pear * @package PEAR * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a10 */ /** * Base class */ require_once 'PEAR/Task/Unixeol.php'; /** * Abstracts the unixeol task xml. * @category pear * @package PEAR * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a10 */ class PEAR_Task_Unixeol_rw extends PEAR_Task_Unixeol { function __construct(&$pkg, &$config, &$logger, $fileXml) { parent::__construct($config, $logger, PEAR_TASK_PACKAGE); $this->_contents = $fileXml; $this->_pkg = &$pkg; $this->_params = array(); } public function validate() { return true; } public function getName() { return 'unixeol'; } public function getXml() { return ''; } } ?> PKu]ZEx9x9PEAR/Task/Postinstallscript.phpnu[ * * PHP versions 4 and 5 * * @category pear * @package PEAR * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ /** * Base class */ require_once 'PEAR/Task/Common.php'; /** * Implements the postinstallscript file task. * * Note that post-install scripts are handled separately from installation, by the * "pear run-scripts" command * * @category pear * @package PEAR * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ class PEAR_Task_Postinstallscript extends PEAR_Task_Common { public $type = 'script'; public $_class; public $_params; public $_obj; /** * * @var PEAR_PackageFile_v2 */ public $_pkg; public $_contents; public $phase = PEAR_TASK_INSTALL; /** * Validate the raw xml at parsing-time. * * This also attempts to validate the script to make sure it meets the criteria * for a post-install script * * @param PEAR_PackageFile_v2 * @param array The XML contents of the tag * @param PEAR_Config * @param array the entire parsed tag */ public static function validateXml($pkg, $xml, $config, $fileXml) { if ($fileXml['role'] != 'php') { return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "'. $fileXml['name'].'" must be role="php"', ); } PEAR::pushErrorHandling(PEAR_ERROR_RETURN); $file = $pkg->getFileContents($fileXml['name']); if (PEAR::isError($file)) { PEAR::popErrorHandling(); return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "'. $fileXml['name'].'" is not valid: '. $file->getMessage(), ); } elseif ($file === null) { return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "'. $fileXml['name'].'" could not be retrieved for processing!', ); } else { $analysis = $pkg->analyzeSourceCode($file, true); if (!$analysis) { PEAR::popErrorHandling(); $warnings = ''; foreach ($pkg->getValidationWarnings() as $warn) { $warnings .= $warn['message']."\n"; } return array(PEAR_TASK_ERROR_INVALID, 'Analysis of post-install script "'. $fileXml['name'].'" failed: '.$warnings, ); } if (count($analysis['declared_classes']) != 1) { PEAR::popErrorHandling(); return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "'. $fileXml['name'].'" must declare exactly 1 class', ); } $class = $analysis['declared_classes'][0]; if ($class != str_replace( array('/', '.php'), array('_', ''), $fileXml['name'] ).'_postinstall') { PEAR::popErrorHandling(); return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "'. $fileXml['name'].'" class "'.$class.'" must be named "'. str_replace( array('/', '.php'), array('_', ''), $fileXml['name'] ).'_postinstall"', ); } if (!isset($analysis['declared_methods'][$class])) { PEAR::popErrorHandling(); return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "'. $fileXml['name'].'" must declare methods init() and run()', ); } $methods = array('init' => 0, 'run' => 1); foreach ($analysis['declared_methods'][$class] as $method) { if (isset($methods[$method])) { unset($methods[$method]); } } if (count($methods)) { PEAR::popErrorHandling(); return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "'. $fileXml['name'].'" must declare methods init() and run()', ); } } PEAR::popErrorHandling(); $definedparams = array(); $tasksNamespace = $pkg->getTasksNs().':'; if (!isset($xml[$tasksNamespace.'paramgroup']) && isset($xml['paramgroup'])) { // in order to support the older betas, which did not expect internal tags // to also use the namespace $tasksNamespace = ''; } if (isset($xml[$tasksNamespace.'paramgroup'])) { $params = $xml[$tasksNamespace.'paramgroup']; if (!is_array($params) || !isset($params[0])) { $params = array($params); } foreach ($params as $param) { if (!isset($param[$tasksNamespace.'id'])) { return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "'. $fileXml['name'].'" must have '. 'an '.$tasksNamespace.'id> tag', ); } if (isset($param[$tasksNamespace.'name'])) { if (!in_array($param[$tasksNamespace.'name'], $definedparams)) { return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "'. $fileXml['name'].'" '.$tasksNamespace. 'paramgroup> id "'.$param[$tasksNamespace.'id']. '" parameter "'.$param[$tasksNamespace.'name']. '" has not been previously defined', ); } if (!isset($param[$tasksNamespace.'conditiontype'])) { return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "'. $fileXml['name'].'" '.$tasksNamespace. 'paramgroup> id "'.$param[$tasksNamespace.'id']. '" must have a '.$tasksNamespace. 'conditiontype> tag containing either "=", '. '"!=", or "preg_match"', ); } if (!in_array( $param[$tasksNamespace.'conditiontype'], array('=', '!=', 'preg_match') )) { return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "'. $fileXml['name'].'" '.$tasksNamespace. 'paramgroup> id "'.$param[$tasksNamespace.'id']. '" must have a '.$tasksNamespace. 'conditiontype> tag containing either "=", '. '"!=", or "preg_match"', ); } if (!isset($param[$tasksNamespace.'value'])) { return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "'. $fileXml['name'].'" '.$tasksNamespace. 'paramgroup> id "'.$param[$tasksNamespace.'id']. '" must have a '.$tasksNamespace. 'value> tag containing expected parameter value', ); } } if (isset($param[$tasksNamespace.'instructions'])) { if (!is_string($param[$tasksNamespace.'instructions'])) { return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "'. $fileXml['name'].'" '.$tasksNamespace. 'paramgroup> id "'.$param[$tasksNamespace.'id']. '" '.$tasksNamespace.'instructions> must be simple text', ); } } if (!isset($param[$tasksNamespace.'param'])) { continue; // is no longer required } $subparams = $param[$tasksNamespace.'param']; if (!is_array($subparams) || !isset($subparams[0])) { $subparams = array($subparams); } foreach ($subparams as $subparam) { if (!isset($subparam[$tasksNamespace.'name'])) { return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "'. $fileXml['name'].'" parameter for '. $tasksNamespace.'paramgroup> id "'. $param[$tasksNamespace.'id'].'" must have '. 'a '.$tasksNamespace.'name> tag', ); } if (!preg_match( '/[a-zA-Z0-9]+/', $subparam[$tasksNamespace.'name'] )) { return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "'. $fileXml['name'].'" parameter "'. $subparam[$tasksNamespace.'name']. '" for '.$tasksNamespace.'paramgroup> id "'. $param[$tasksNamespace.'id']. '" is not a valid name. Must contain only alphanumeric characters', ); } if (!isset($subparam[$tasksNamespace.'prompt'])) { return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "'. $fileXml['name'].'" parameter "'. $subparam[$tasksNamespace.'name']. '" for '.$tasksNamespace.'paramgroup> id "'. $param[$tasksNamespace.'id']. '" must have a '.$tasksNamespace.'prompt> tag', ); } if (!isset($subparam[$tasksNamespace.'type'])) { return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "'. $fileXml['name'].'" parameter "'. $subparam[$tasksNamespace.'name']. '" for '.$tasksNamespace.'paramgroup> id "'. $param[$tasksNamespace.'id']. '" must have a '.$tasksNamespace.'type> tag', ); } $definedparams[] = $param[$tasksNamespace.'id'].'::'. $subparam[$tasksNamespace.'name']; } } } return true; } /** * Initialize a task instance with the parameters * @param array $xml raw, parsed xml * @param array $fileattribs attributes from the tag containing * this task * @param string|null $lastversion last installed version of this package, * if any (useful for upgrades) */ public function init($xml, $fileattribs, $lastversion) { $this->_class = str_replace('/', '_', $fileattribs['name']); $this->_filename = $fileattribs['name']; $this->_class = str_replace('.php', '', $this->_class).'_postinstall'; $this->_params = $xml; $this->_lastversion = $lastversion; } /** * Strip the tasks: namespace from internal params * * @access private */ public function _stripNamespace($params = null) { if ($params === null) { $params = array(); if (!is_array($this->_params)) { return; } foreach ($this->_params as $i => $param) { if (is_array($param)) { $param = $this->_stripNamespace($param); } $params[str_replace($this->_pkg->getTasksNs().':', '', $i)] = $param; } $this->_params = $params; } else { $newparams = array(); foreach ($params as $i => $param) { if (is_array($param)) { $param = $this->_stripNamespace($param); } $newparams[str_replace($this->_pkg->getTasksNs().':', '', $i)] = $param; } return $newparams; } } /** * Unlike other tasks, the installed file name is passed in instead of the * file contents, because this task is handled post-installation * * @param mixed $pkg PEAR_PackageFile_v1|PEAR_PackageFile_v2 * @param string $contents file name * @param string $dest the eventual final file location (informational only) * * @return bool|PEAR_Error false to skip this file, PEAR_Error to fail * (use $this->throwError) */ public function startSession($pkg, $contents, $dest) { if ($this->installphase != PEAR_TASK_INSTALL) { return false; } // remove the tasks: namespace if present $this->_pkg = $pkg; $this->_stripNamespace(); $this->logger->log( 0, 'Including external post-installation script "'. $contents.'" - any errors are in this script' ); include_once $contents; if (class_exists($this->_class)) { $this->logger->log(0, 'Inclusion succeeded'); } else { return $this->throwError( 'init of post-install script class "'.$this->_class .'" failed' ); } $this->_obj = new $this->_class(); $this->logger->log(1, 'running post-install script "'.$this->_class.'->init()"'); PEAR::pushErrorHandling(PEAR_ERROR_RETURN); $res = $this->_obj->init($this->config, $pkg, $this->_lastversion); PEAR::popErrorHandling(); if ($res) { $this->logger->log(0, 'init succeeded'); } else { return $this->throwError( 'init of post-install script "'.$this->_class. '->init()" failed' ); } $this->_contents = $contents; return true; } /** * No longer used * * @see PEAR_PackageFile_v2::runPostinstallScripts() * @param array an array of tasks * @param string install or upgrade * @access protected */ public static function run($tasks) { } } PKu]&%75))PEAR/Task/Windowseol/rw.phpnu[ - read/write version * * PHP versions 4 and 5 * * @category pear * @package PEAR * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a10 */ /** * Base class */ require_once 'PEAR/Task/Windowseol.php'; /** * Abstracts the windowseol task xml. * * @category pear * @package PEAR * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a10 */ class PEAR_Task_Windowseol_rw extends PEAR_Task_Windowseol { function __construct(&$pkg, &$config, &$logger, $fileXml) { parent::__construct($config, $logger, PEAR_TASK_PACKAGE); $this->_contents = $fileXml; $this->_pkg = &$pkg; $this->_params = array(); } public function validate() { return true; } public function getName() { return 'windowseol'; } public function getXml() { return ''; } } ?> PKu]D$PEAR/Task/Windowseol.phpnu[ * * PHP versions 4 and 5 * * @category pear * @package PEAR * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ /** * Base class */ require_once 'PEAR/Task/Common.php'; /** * Implements the windows line endsings file task. * * @category pear * @package PEAR * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ class PEAR_Task_Windowseol extends PEAR_Task_Common { public $type = 'simple'; public $phase = PEAR_TASK_PACKAGE; public $_replacements; /** * Validate the raw xml at parsing-time. * * @param PEAR_PackageFile_v2 * @param array raw, parsed xml * @param PEAR_Config */ public static function validateXml($pkg, $xml, $config, $fileXml) { if ($xml != '') { return array(PEAR_TASK_ERROR_INVALID, 'no attributes allowed'); } return true; } /** * Initialize a task instance with the parameters * @param array raw, parsed xml * @param unused * @param unused */ public function init($xml, $attribs, $lastVersion = null) { } /** * Replace all line endings with windows line endings * * See validateXml() source for the complete list of allowed fields * * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 * @param string file contents * @param string the eventual final file location (informational only) * @return string|false|PEAR_Error false to skip this file, PEAR_Error to fail * (use $this->throwError), otherwise return the new contents */ public function startSession($pkg, $contents, $dest) { $this->logger->log(3, "replacing all line endings with \\r\\n in $dest"); return preg_replace("/\r\n|\n\r|\r|\n/", "\r\n", $contents); } } PKu]3}PEAR/Task/Replace/rw.phpnu[ - read/write version * * PHP versions 4 and 5 * * @category pear * @package PEAR * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a10 */ /** * Base class */ require_once 'PEAR/Task/Replace.php'; /** * Abstracts the replace task xml. * @category pear * @package PEAR * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a10 */ class PEAR_Task_Replace_rw extends PEAR_Task_Replace { public function __construct(&$pkg, &$config, &$logger, $fileXml) { parent::__construct($config, $logger, PEAR_TASK_PACKAGE); $this->_contents = $fileXml; $this->_pkg = &$pkg; $this->_params = array(); } public function validate() { return $this->validateXml($this->_pkg, $this->_params, $this->config, $this->_contents); } public function setInfo($from, $to, $type) { $this->_params = array('attribs' => array('from' => $from, 'to' => $to, 'type' => $type)); } public function getName() { return 'replace'; } public function getXml() { return $this->_params; } } PKu]& i."PEAR/Task/Postinstallscript/rw.phpnu[ - read/write version * * PHP versions 4 and 5 * * @category pear * @package PEAR * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a10 */ /** * Base class */ require_once 'PEAR/Task/Postinstallscript.php'; /** * Abstracts the postinstallscript file task xml. * @category pear * @package PEAR * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a10 */ class PEAR_Task_Postinstallscript_rw extends PEAR_Task_Postinstallscript { /** * parent package file object * * @var PEAR_PackageFile_v2_rw */ public $_pkg; /** * Enter description here... * * @param PEAR_PackageFile_v2_rw $pkg Package * @param PEAR_Config $config Config * @param PEAR_Frontend $logger Logger * @param array $fileXml XML * * @return PEAR_Task_Postinstallscript_rw */ function __construct(&$pkg, &$config, &$logger, $fileXml) { parent::__construct($config, $logger, PEAR_TASK_PACKAGE); $this->_contents = $fileXml; $this->_pkg = &$pkg; $this->_params = array(); } public function validate() { return $this->validateXml($this->_pkg, $this->_params, $this->config, $this->_contents); } public function getName() { return 'postinstallscript'; } /** * add a simple to the post-install script * * Order is significant, so call this method in the same * sequence the users should see the paramgroups. The $params * parameter should either be the result of a call to {@link getParam()} * or an array of calls to getParam(). * * Use {@link addConditionTypeGroup()} to add a containing * a tag * * @param string $id id as seen by the script * @param array|false $params array of getParam() calls, or false for no params * @param string|false $instructions */ public function addParamGroup($id, $params = false, $instructions = false) { if ($params && isset($params[0]) && !isset($params[1])) { $params = $params[0]; } $stuff = array( $this->_pkg->getTasksNs().':id' => $id, ); if ($instructions) { $stuff[$this->_pkg->getTasksNs().':instructions'] = $instructions; } if ($params) { $stuff[$this->_pkg->getTasksNs().':param'] = $params; } $this->_params[$this->_pkg->getTasksNs().':paramgroup'][] = $stuff; } /** * Add a complex to the post-install script with conditions * * This inserts a with * * Order is significant, so call this method in the same * sequence the users should see the paramgroups. The $params * parameter should either be the result of a call to {@link getParam()} * or an array of calls to getParam(). * * Use {@link addParamGroup()} to add a simple * * @param string $id id as seen by the script * @param string $oldgroup id of the section referenced by * * @param string $param name of the from the older section referenced * by * @param string $value value to match of the parameter * @param string $conditiontype one of '=', '!=', 'preg_match' * @param array|false $params array of getParam() calls, or false for no params * @param string|false $instructions */ public function addConditionTypeGroup($id, $oldgroup, $param, $value, $conditiontype = '=', $params = false, $instructions = false ) { if ($params && isset($params[0]) && !isset($params[1])) { $params = $params[0]; } $stuff = array( $this->_pkg->getTasksNs().':id' => $id, ); if ($instructions) { $stuff[$this->_pkg->getTasksNs().':instructions'] = $instructions; } $stuff[$this->_pkg->getTasksNs().':name'] = $oldgroup.'::'.$param; $stuff[$this->_pkg->getTasksNs().':conditiontype'] = $conditiontype; $stuff[$this->_pkg->getTasksNs().':value'] = $value; if ($params) { $stuff[$this->_pkg->getTasksNs().':param'] = $params; } $this->_params[$this->_pkg->getTasksNs().':paramgroup'][] = $stuff; } public function getXml() { return $this->_params; } /** * Use to set up a param tag for use in creating a paramgroup * * @param mixed $name Name of parameter * @param mixed $prompt Prompt * @param string $type Type, defaults to 'string' * @param mixed $default Default value * * @return array */ public function getParam( $name, $prompt, $type = 'string', $default = null ) { if ($default !== null) { return array( $this->_pkg->getTasksNs().':name' => $name, $this->_pkg->getTasksNs().':prompt' => $prompt, $this->_pkg->getTasksNs().':type' => $type, $this->_pkg->getTasksNs().':default' => $default, ); } return array( $this->_pkg->getTasksNs().':name' => $name, $this->_pkg->getTasksNs().':prompt' => $prompt, $this->_pkg->getTasksNs().':type' => $type, ); } } PKu]-!PEAR/Task/Common.phpnu[ * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ /**#@+ * Error codes for task validation routines */ define('PEAR_TASK_ERROR_NOATTRIBS', 1); define('PEAR_TASK_ERROR_MISSING_ATTRIB', 2); define('PEAR_TASK_ERROR_WRONG_ATTRIB_VALUE', 3); define('PEAR_TASK_ERROR_INVALID', 4); /**#@-*/ define('PEAR_TASK_PACKAGE', 1); define('PEAR_TASK_INSTALL', 2); define('PEAR_TASK_PACKAGEANDINSTALL', 3); /** * A task is an operation that manipulates the contents of a file. * * Simple tasks operate on 1 file. Multiple tasks are executed after all files have been * processed and installed, and are designed to operate on all files containing the task. * The Post-install script task simply takes advantage of the fact that it will be run * after installation, replace is a simple task. * * Combining tasks is possible, but ordering is significant. * * * * * * * This will first replace any instance of @data-dir@ in the test.php file * with the path to the current data directory. Then, it will include the * test.php file and run the script it contains to configure the package post-installation. * * @category pear * @package PEAR * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 * @abstract */ class PEAR_Task_Common { /** * Valid types for this version are 'simple' and 'multiple' * * - simple tasks operate on the contents of a file and write out changes to disk * - multiple tasks operate on the contents of many files and write out the * changes directly to disk * * Child task classes must override this property. * * @access protected */ protected $type = 'simple'; /** * Determines which install phase this task is executed under */ public $phase = PEAR_TASK_INSTALL; /** * @access protected */ protected $config; /** * @access protected */ protected $registry; /** * @access protected */ public $logger; /** * @access protected */ protected $installphase; /** * @param PEAR_Config * @param PEAR_Common */ function __construct(&$config, &$logger, $phase) { $this->config = &$config; $this->registry = &$config->getRegistry(); $this->logger = &$logger; $this->installphase = $phase; if ($this->type == 'multiple') { $GLOBALS['_PEAR_TASK_POSTINSTANCES'][get_class($this)][] = &$this; } } /** * Validate the basic contents of a task tag. * * @param PEAR_PackageFile_v2 * @param array * @param PEAR_Config * @param array the entire parsed tag * * @return true|array On error, return an array in format: * array(PEAR_TASK_ERROR_???[, param1][, param2][, ...]) * * For PEAR_TASK_ERROR_MISSING_ATTRIB, pass the attribute name in * For PEAR_TASK_ERROR_WRONG_ATTRIB_VALUE, pass the attribute name and * an array of legal values in * * @abstract */ public static function validateXml($pkg, $xml, $config, $fileXml) { } /** * Initialize a task instance with the parameters * * @param array raw, parsed xml * @param array attributes from the tag containing this task * @param string|null last installed version of this package * @abstract */ public function init($xml, $fileAttributes, $lastVersion) { } /** * Begin a task processing session. All multiple tasks will be processed * after each file has been successfully installed, all simple tasks should * perform their task here and return any errors using the custom * throwError() method to allow forward compatibility * * This method MUST NOT write out any changes to disk * * @param PEAR_PackageFile_v2 * @param string file contents * @param string the eventual final file location (informational only) * @return string|false|PEAR_Error false to skip this file, PEAR_Error to fail * (use $this->throwError), otherwise return the new contents * @abstract */ public function startSession($pkg, $contents, $dest) { } /** * This method is used to process each of the tasks for a particular * multiple class type. Simple tasks need not implement this method. * * @param array an array of tasks * @access protected */ public static function run($tasks) { } /** * @final */ public static function hasPostinstallTasks() { return isset($GLOBALS['_PEAR_TASK_POSTINSTANCES']); } /** * @final */ public static function runPostinstallTasks() { foreach ($GLOBALS['_PEAR_TASK_POSTINSTANCES'] as $class => $tasks) { $err = call_user_func( array($class, 'run'), $GLOBALS['_PEAR_TASK_POSTINSTANCES'][$class] ); if ($err) { return PEAR_Task_Common::throwError($err); } } unset($GLOBALS['_PEAR_TASK_POSTINSTANCES']); } /** * Determines whether a role is a script * @return bool */ public function isScript() { return $this->type == 'script'; } public function throwError($msg, $code = -1) { include_once 'PEAR.php'; return PEAR::raiseError($msg, $code); } } PKu]JDPEAR/Task/Replace.phpnu[ * * PHP versions 4 and 5 * * @category pear * @package PEAR * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ /** * Base class */ require_once 'PEAR/Task/Common.php'; /** * Implements the replace file task. * @category pear * @package PEAR * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ class PEAR_Task_Replace extends PEAR_Task_Common { public $type = 'simple'; public $phase = PEAR_TASK_PACKAGEANDINSTALL; public $_replacements; /** * Validate the raw xml at parsing-time. * * @param PEAR_PackageFile_v2 * @param array raw, parsed xml * @param PEAR_Config */ public static function validateXml($pkg, $xml, $config, $fileXml) { if (!isset($xml['attribs'])) { return array(PEAR_TASK_ERROR_NOATTRIBS); } if (!isset($xml['attribs']['type'])) { return array(PEAR_TASK_ERROR_MISSING_ATTRIB, 'type'); } if (!isset($xml['attribs']['to'])) { return array(PEAR_TASK_ERROR_MISSING_ATTRIB, 'to'); } if (!isset($xml['attribs']['from'])) { return array(PEAR_TASK_ERROR_MISSING_ATTRIB, 'from'); } if ($xml['attribs']['type'] == 'pear-config') { if (!in_array($xml['attribs']['to'], $config->getKeys())) { return array(PEAR_TASK_ERROR_WRONG_ATTRIB_VALUE, 'to', $xml['attribs']['to'], $config->getKeys(), ); } } elseif ($xml['attribs']['type'] == 'php-const') { if (defined($xml['attribs']['to'])) { return true; } else { return array(PEAR_TASK_ERROR_WRONG_ATTRIB_VALUE, 'to', $xml['attribs']['to'], array('valid PHP constant'), ); } } elseif ($xml['attribs']['type'] == 'package-info') { if (in_array( $xml['attribs']['to'], array('name', 'summary', 'channel', 'notes', 'extends', 'description', 'release_notes', 'license', 'release-license', 'license-uri', 'version', 'api-version', 'state', 'api-state', 'release_date', 'date', 'time', ) )) { return true; } else { return array(PEAR_TASK_ERROR_WRONG_ATTRIB_VALUE, 'to', $xml['attribs']['to'], array('name', 'summary', 'channel', 'notes', 'extends', 'description', 'release_notes', 'license', 'release-license', 'license-uri', 'version', 'api-version', 'state', 'api-state', 'release_date', 'date', 'time', ), ); } } else { return array(PEAR_TASK_ERROR_WRONG_ATTRIB_VALUE, 'type', $xml['attribs']['type'], array('pear-config', 'package-info', 'php-const'), ); } return true; } /** * Initialize a task instance with the parameters * @param array raw, parsed xml * @param unused * @param unused */ public function init($xml, $attribs, $lastVersion = null) { $this->_replacements = isset($xml['attribs']) ? array($xml) : $xml; } /** * Do a package.xml 1.0 replacement, with additional package-info fields available * * See validateXml() source for the complete list of allowed fields * * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 * @param string file contents * @param string the eventual final file location (informational only) * @return string|false|PEAR_Error false to skip this file, PEAR_Error to fail * (use $this->throwError), otherwise return the new contents */ public function startSession($pkg, $contents, $dest) { $subst_from = $subst_to = array(); foreach ($this->_replacements as $a) { $a = $a['attribs']; $to = ''; if ($a['type'] == 'pear-config') { if ($this->installphase == PEAR_TASK_PACKAGE) { return false; } if ($a['to'] == 'master_server') { $chan = $this->registry->getChannel($pkg->getChannel()); if (!PEAR::isError($chan)) { $to = $chan->getServer(); } else { $this->logger->log(0, "$dest: invalid pear-config replacement: $a[to]"); return false; } } else { if ($this->config->isDefinedLayer('ftp')) { // try the remote config file first $to = $this->config->get($a['to'], 'ftp', $pkg->getChannel()); if (is_null($to)) { // then default to local $to = $this->config->get($a['to'], null, $pkg->getChannel()); } } else { $to = $this->config->get($a['to'], null, $pkg->getChannel()); } } if (is_null($to)) { $this->logger->log(0, "$dest: invalid pear-config replacement: $a[to]"); return false; } } elseif ($a['type'] == 'php-const') { if ($this->installphase == PEAR_TASK_PACKAGE) { return false; } if (defined($a['to'])) { $to = constant($a['to']); } else { $this->logger->log(0, "$dest: invalid php-const replacement: $a[to]"); return false; } } else { if ($t = $pkg->packageInfo($a['to'])) { $to = $t; } else { $this->logger->log(0, "$dest: invalid package-info replacement: $a[to]"); return false; } } if (!is_null($to)) { $subst_from[] = $a['from']; $subst_to[] = $to; } } $this->logger->log( 3, "doing ".sizeof($subst_from). " substitution(s) for $dest" ); if (sizeof($subst_from)) { $contents = str_replace($subst_from, $subst_to, $contents); } return $contents; } } PKu]gkUUPEAR/Validate.phpnu[ * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ /**#@+ * Constants for install stage */ define('PEAR_VALIDATE_INSTALLING', 1); define('PEAR_VALIDATE_UNINSTALLING', 2); // this is not bit-mapped like the others define('PEAR_VALIDATE_NORMAL', 3); define('PEAR_VALIDATE_DOWNLOADING', 4); // this is not bit-mapped like the others define('PEAR_VALIDATE_PACKAGING', 7); /**#@-*/ require_once 'PEAR/Common.php'; require_once 'PEAR/Validator/PECL.php'; /** * Validation class for package.xml - channel-level advanced validation * @category pear * @package PEAR * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ class PEAR_Validate { var $packageregex = _PEAR_COMMON_PACKAGE_NAME_PREG; /** * @var PEAR_PackageFile_v1|PEAR_PackageFile_v2 */ var $_packagexml; /** * @var int one of the PEAR_VALIDATE_* constants */ var $_state = PEAR_VALIDATE_NORMAL; /** * Format: ('error' => array('field' => name, 'reason' => reason), 'warning' => same) * @var array * @access private */ var $_failures = array('error' => array(), 'warning' => array()); /** * Override this method to handle validation of normal package names * @param string * @return bool * @access protected */ function _validPackageName($name) { return (bool) preg_match('/^' . $this->packageregex . '\\z/', $name); } /** * @param string package name to validate * @param string name of channel-specific validation package * @final */ function validPackageName($name, $validatepackagename = false) { if ($validatepackagename) { if (strtolower($name) == strtolower($validatepackagename)) { return (bool) preg_match('/^[a-zA-Z0-9_]+(?:\.[a-zA-Z0-9_]+)*\\z/', $name); } } return $this->_validPackageName($name); } /** * This validates a bundle name, and bundle names must conform * to the PEAR naming convention, so the method is final and static. * @param string * @final */ public static function validGroupName($name) { return (bool) preg_match('/^' . _PEAR_COMMON_PACKAGE_NAME_PREG . '\\z/', $name); } /** * Determine whether $state represents a valid stability level * @param string * @return bool * @final */ public static function validState($state) { return in_array($state, array('snapshot', 'devel', 'alpha', 'beta', 'stable')); } /** * Get a list of valid stability levels * @return array * @final */ public static function getValidStates() { return array('snapshot', 'devel', 'alpha', 'beta', 'stable'); } /** * Determine whether a version is a properly formatted version number that can be used * by version_compare * @param string * @return bool * @final */ public static function validVersion($ver) { return (bool) preg_match(PEAR_COMMON_PACKAGE_VERSION_PREG, $ver); } /** * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 */ function setPackageFile(&$pf) { $this->_packagexml = &$pf; } /** * @access private */ function _addFailure($field, $reason) { $this->_failures['errors'][] = array('field' => $field, 'reason' => $reason); } /** * @access private */ function _addWarning($field, $reason) { $this->_failures['warnings'][] = array('field' => $field, 'reason' => $reason); } function getFailures() { $failures = $this->_failures; $this->_failures = array('warnings' => array(), 'errors' => array()); return $failures; } /** * @param int one of the PEAR_VALIDATE_* constants */ function validate($state = null) { if (!isset($this->_packagexml)) { return false; } if ($state !== null) { $this->_state = $state; } $this->_failures = array('warnings' => array(), 'errors' => array()); $this->validatePackageName(); $this->validateVersion(); $this->validateMaintainers(); $this->validateDate(); $this->validateSummary(); $this->validateDescription(); $this->validateLicense(); $this->validateNotes(); if ($this->_packagexml->getPackagexmlVersion() == '1.0') { $this->validateState(); $this->validateFilelist(); } elseif ($this->_packagexml->getPackagexmlVersion() == '2.0' || $this->_packagexml->getPackagexmlVersion() == '2.1') { $this->validateTime(); $this->validateStability(); $this->validateDeps(); $this->validateMainFilelist(); $this->validateReleaseFilelist(); //$this->validateGlobalTasks(); $this->validateChangelog(); } return !((bool) count($this->_failures['errors'])); } /** * @access protected */ function validatePackageName() { if ($this->_state == PEAR_VALIDATE_PACKAGING || $this->_state == PEAR_VALIDATE_NORMAL) { if (($this->_packagexml->getPackagexmlVersion() == '2.0' || $this->_packagexml->getPackagexmlVersion() == '2.1') && $this->_packagexml->getExtends()) { $version = $this->_packagexml->getVersion() . ''; $name = $this->_packagexml->getPackage(); $a = explode('.', $version); $test = array_shift($a); if ($test == '0') { return true; } $vlen = strlen($test); $majver = substr($name, strlen($name) - $vlen); while ($majver && !is_numeric($majver[0])) { $majver = substr($majver, 1); } if ($majver != $test) { $this->_addWarning('package', "package $name extends package " . $this->_packagexml->getExtends() . ' and so the name should ' . 'have a postfix equal to the major version like "' . $this->_packagexml->getExtends() . $test . '"'); return true; } elseif (substr($name, 0, strlen($name) - $vlen) != $this->_packagexml->getExtends()) { $this->_addWarning('package', "package $name extends package " . $this->_packagexml->getExtends() . ' and so the name must ' . 'be an extension like "' . $this->_packagexml->getExtends() . $test . '"'); return true; } } } if (!$this->validPackageName($this->_packagexml->getPackage())) { $this->_addFailure('name', 'package name "' . $this->_packagexml->getPackage() . '" is invalid'); return false; } } /** * @access protected */ function validateVersion() { if ($this->_state != PEAR_VALIDATE_PACKAGING) { if (!$this->validVersion($this->_packagexml->getVersion())) { $this->_addFailure('version', 'Invalid version number "' . $this->_packagexml->getVersion() . '"'); } return false; } $version = $this->_packagexml->getVersion(); $versioncomponents = explode('.', $version); if (count($versioncomponents) != 3) { $this->_addWarning('version', 'A version number should have 3 decimals (x.y.z)'); return true; } $name = $this->_packagexml->getPackage(); // version must be based upon state switch ($this->_packagexml->getState()) { case 'snapshot' : return true; case 'devel' : if ($versioncomponents[0] . 'a' == '0a') { return true; } if ($versioncomponents[0] == 0) { $versioncomponents[0] = '0'; $this->_addWarning('version', 'version "' . $version . '" should be "' . implode('.' ,$versioncomponents) . '"'); } else { $this->_addWarning('version', 'packages with devel stability must be < version 1.0.0'); } return true; break; case 'alpha' : case 'beta' : // check for a package that extends a package, // like Foo and Foo2 if ($this->_state == PEAR_VALIDATE_PACKAGING) { if (substr($versioncomponents[2], 1, 2) == 'rc') { $this->_addFailure('version', 'Release Candidate versions ' . 'must have capital RC, not lower-case rc'); return false; } } if (!$this->_packagexml->getExtends()) { if ($versioncomponents[0] == '1') { if ($versioncomponents[2][0] == '0') { if ($versioncomponents[2] == '0') { // version 1.*.0000 $this->_addWarning('version', 'version 1.' . $versioncomponents[1] . '.0 probably should not be alpha or beta'); return true; } elseif (strlen($versioncomponents[2]) > 1) { // version 1.*.0RC1 or 1.*.0beta24 etc. return true; } else { // version 1.*.0 $this->_addWarning('version', 'version 1.' . $versioncomponents[1] . '.0 probably should not be alpha or beta'); return true; } } else { $this->_addWarning('version', 'bugfix versions (1.3.x where x > 0) probably should ' . 'not be alpha or beta'); return true; } } elseif ($versioncomponents[0] != '0') { $this->_addWarning('version', 'major versions greater than 1 are not allowed for packages ' . 'without an tag or an identical postfix (foo2 v2.0.0)'); return true; } if ($versioncomponents[0] . 'a' == '0a') { return true; } if ($versioncomponents[0] == 0) { $versioncomponents[0] = '0'; $this->_addWarning('version', 'version "' . $version . '" should be "' . implode('.' ,$versioncomponents) . '"'); } } else { $vlen = strlen($versioncomponents[0] . ''); $majver = substr($name, strlen($name) - $vlen); while ($majver && !is_numeric($majver[0])) { $majver = substr($majver, 1); } if (($versioncomponents[0] != 0) && $majver != $versioncomponents[0]) { $this->_addWarning('version', 'first version number "' . $versioncomponents[0] . '" must match the postfix of ' . 'package name "' . $name . '" (' . $majver . ')'); return true; } if ($versioncomponents[0] == $majver) { if ($versioncomponents[2][0] == '0') { if ($versioncomponents[2] == '0') { // version 2.*.0000 $this->_addWarning('version', "version $majver." . $versioncomponents[1] . '.0 probably should not be alpha or beta'); return false; } elseif (strlen($versioncomponents[2]) > 1) { // version 2.*.0RC1 or 2.*.0beta24 etc. return true; } else { // version 2.*.0 $this->_addWarning('version', "version $majver." . $versioncomponents[1] . '.0 cannot be alpha or beta'); return true; } } else { $this->_addWarning('version', "bugfix versions ($majver.x.y where y > 0) should " . 'not be alpha or beta'); return true; } } elseif ($versioncomponents[0] != '0') { $this->_addWarning('version', "only versions 0.x.y and $majver.x.y are allowed for alpha/beta releases"); return true; } if ($versioncomponents[0] . 'a' == '0a') { return true; } if ($versioncomponents[0] == 0) { $versioncomponents[0] = '0'; $this->_addWarning('version', 'version "' . $version . '" should be "' . implode('.' ,$versioncomponents) . '"'); } } return true; break; case 'stable' : if ($versioncomponents[0] == '0') { $this->_addWarning('version', 'versions less than 1.0.0 cannot ' . 'be stable'); return true; } if (!is_numeric($versioncomponents[2])) { if (preg_match('/\d+(rc|a|alpha|b|beta)\d*/i', $versioncomponents[2])) { $this->_addWarning('version', 'version "' . $version . '" or any ' . 'RC/beta/alpha version cannot be stable'); return true; } } // check for a package that extends a package, // like Foo and Foo2 if ($this->_packagexml->getExtends()) { $vlen = strlen($versioncomponents[0] . ''); $majver = substr($name, strlen($name) - $vlen); while ($majver && !is_numeric($majver[0])) { $majver = substr($majver, 1); } if (($versioncomponents[0] != 0) && $majver != $versioncomponents[0]) { $this->_addWarning('version', 'first version number "' . $versioncomponents[0] . '" must match the postfix of ' . 'package name "' . $name . '" (' . $majver . ')'); return true; } } elseif ($versioncomponents[0] > 1) { $this->_addWarning('version', 'major version x in x.y.z may not be greater than ' . '1 for any package that does not have an tag'); } return true; break; default : return false; break; } } /** * @access protected */ function validateMaintainers() { // maintainers can only be truly validated server-side for most channels // but allow this customization for those who wish it return true; } /** * @access protected */ function validateDate() { if ($this->_state == PEAR_VALIDATE_NORMAL || $this->_state == PEAR_VALIDATE_PACKAGING) { if (!preg_match('/(\d\d\d\d)\-(\d\d)\-(\d\d)/', $this->_packagexml->getDate(), $res) || count($res) < 4 || !checkdate($res[2], $res[3], $res[1]) ) { $this->_addFailure('date', 'invalid release date "' . $this->_packagexml->getDate() . '"'); return false; } if ($this->_state == PEAR_VALIDATE_PACKAGING && $this->_packagexml->getDate() != date('Y-m-d')) { $this->_addWarning('date', 'Release Date "' . $this->_packagexml->getDate() . '" is not today'); } } return true; } /** * @access protected */ function validateTime() { if (!$this->_packagexml->getTime()) { // default of no time value set return true; } // packager automatically sets time, so only validate if pear validate is called if ($this->_state = PEAR_VALIDATE_NORMAL) { if (!preg_match('/\d\d:\d\d:\d\d/', $this->_packagexml->getTime())) { $this->_addFailure('time', 'invalid release time "' . $this->_packagexml->getTime() . '"'); return false; } $result = preg_match('|\d{2}\:\d{2}\:\d{2}|', $this->_packagexml->getTime(), $matches); if ($result === false || empty($matches)) { $this->_addFailure('time', 'invalid release time "' . $this->_packagexml->getTime() . '"'); return false; } } return true; } /** * @access protected */ function validateState() { // this is the closest to "final" php4 can get if (!PEAR_Validate::validState($this->_packagexml->getState())) { if (strtolower($this->_packagexml->getState() == 'rc')) { $this->_addFailure('state', 'RC is not a state, it is a version ' . 'postfix, use ' . $this->_packagexml->getVersion() . 'RC1, state beta'); } $this->_addFailure('state', 'invalid release state "' . $this->_packagexml->getState() . '", must be one of: ' . implode(', ', PEAR_Validate::getValidStates())); return false; } return true; } /** * @access protected */ function validateStability() { $ret = true; $packagestability = $this->_packagexml->getState(); $apistability = $this->_packagexml->getState('api'); if (!PEAR_Validate::validState($packagestability)) { $this->_addFailure('state', 'invalid release stability "' . $this->_packagexml->getState() . '", must be one of: ' . implode(', ', PEAR_Validate::getValidStates())); $ret = false; } $apistates = PEAR_Validate::getValidStates(); array_shift($apistates); // snapshot is not allowed if (!in_array($apistability, $apistates)) { $this->_addFailure('state', 'invalid API stability "' . $this->_packagexml->getState('api') . '", must be one of: ' . implode(', ', $apistates)); $ret = false; } return $ret; } /** * @access protected */ function validateSummary() { return true; } /** * @access protected */ function validateDescription() { return true; } /** * @access protected */ function validateLicense() { return true; } /** * @access protected */ function validateNotes() { return true; } /** * for package.xml 2.0 only - channels can't use package.xml 1.0 * @access protected */ function validateDependencies() { return true; } /** * for package.xml 1.0 only * @access private */ function _validateFilelist() { return true; // placeholder for now } /** * for package.xml 2.0 only * @access protected */ function validateMainFilelist() { return true; // placeholder for now } /** * for package.xml 2.0 only * @access protected */ function validateReleaseFilelist() { return true; // placeholder for now } /** * @access protected */ function validateChangelog() { return true; } /** * @access protected */ function validateFilelist() { return true; } /** * @access protected */ function validateDeps() { return true; } }PKu]J} } Auth/SASL/Anonymous.phpnu[ | // +-----------------------------------------------------------------------+ // // $Id$ /** * Implmentation of ANONYMOUS SASL mechanism * * @author Richard Heyes * @access public * @version 1.0 * @package Auth_SASL */ require_once('Auth/SASL/Common.php'); class Auth_SASL_Anonymous extends Auth_SASL_Common { /** * Not much to do here except return the token supplied. * No encoding, hashing or encryption takes place for this * mechanism, simply one of: * o An email address * o An opaque string not containing "@" that can be interpreted * by the sysadmin * o Nothing * * We could have some logic here for the second option, but this * would by no means create something interpretable. * * @param string $token Optional email address or string to provide * as trace information. * @return string The unaltered input token */ function getResponse($token = '') { return $token; } } ?>PKu]%ׅtg!g!Auth/SASL/DigestMD5.phpnu[ | // +-----------------------------------------------------------------------+ // // $Id$ /** * Implmentation of DIGEST-MD5 SASL mechanism * * @author Richard Heyes * @access public * @version 1.0 * @package Auth_SASL */ require_once('Auth/SASL/Common.php'); class Auth_SASL_DigestMD5 extends Auth_SASL_Common { /** * Provides the (main) client response for DIGEST-MD5 * requires a few extra parameters than the other * mechanisms, which are unavoidable. * * @param string $authcid Authentication id (username) * @param string $pass Password * @param string $challenge The digest challenge sent by the server * @param string $hostname The hostname of the machine you're connecting to * @param string $service The servicename (eg. imap, pop, acap etc) * @param string $authzid Authorization id (username to proxy as) * @return string The digest response (NOT base64 encoded) * @access public */ function getResponse($authcid, $pass, $challenge, $hostname, $service, $authzid = '') { $challenge = $this->_parseChallenge($challenge); $authzid_string = ''; if ($authzid != '') { $authzid_string = ',authzid="' . $authzid . '"'; } if (!empty($challenge)) { $cnonce = $this->_getCnonce(); $digest_uri = sprintf('%s/%s', $service, $hostname); $response_value = $this->_getResponseValue($authcid, $pass, $challenge['realm'], $challenge['nonce'], $cnonce, $digest_uri, $authzid); if ($challenge['realm']) { return sprintf('username="%s",realm="%s"' . $authzid_string . ',nonce="%s",cnonce="%s",nc=00000001,qop=auth,digest-uri="%s",response=%s,maxbuf=%d', $authcid, $challenge['realm'], $challenge['nonce'], $cnonce, $digest_uri, $response_value, $challenge['maxbuf']); } else { return sprintf('username="%s"' . $authzid_string . ',nonce="%s",cnonce="%s",nc=00000001,qop=auth,digest-uri="%s",response=%s,maxbuf=%d', $authcid, $challenge['nonce'], $cnonce, $digest_uri, $response_value, $challenge['maxbuf']); } } else { return PEAR::raiseError('Invalid digest challenge'); } } /** * Parses and verifies the digest challenge* * * @param string $challenge The digest challenge * @return array The parsed challenge as an assoc * array in the form "directive => value". * @access private */ function _parseChallenge($challenge) { $tokens = array(); while (preg_match('/^([a-z-]+)=("[^"]+(? PKu]vRr, , Auth/SASL/External.phpnu[ | // +-----------------------------------------------------------------------+ // // $Id$ /** * Implmentation of EXTERNAL SASL mechanism * * @author Christoph Schulz * @access public * @version 1.0.3 * @package Auth_SASL */ require_once('Auth/SASL/Common.php'); class Auth_SASL_External extends Auth_SASL_Common { /** * Returns EXTERNAL response * * @param string $authcid Authentication id (username) * @param string $pass Password * @param string $authzid Autorization id * @return string EXTERNAL Response */ function getResponse($authcid, $pass, $authzid = '') { return $authzid; } } ?> PKu]< O O Auth/SASL/Login.phpnu[ | // +-----------------------------------------------------------------------+ // // $Id$ /** * This is technically not a SASL mechanism, however * it's used by Net_Sieve, Net_Cyrus and potentially * other protocols , so here is a good place to abstract * it. * * @author Richard Heyes * @access public * @version 1.0 * @package Auth_SASL */ require_once('Auth/SASL/Common.php'); class Auth_SASL_Login extends Auth_SASL_Common { /** * Pseudo SASL LOGIN mechanism * * @param string $user Username * @param string $pass Password * @return string LOGIN string */ function getResponse($user, $pass) { return sprintf('LOGIN %s %s', $user, $pass); } } ?>PKu]ќ00Auth/SASL/SCRAM.phpnu[ * @access public * @version 1.0 * @package Auth_SASL */ require_once('Auth/SASL/Common.php'); class Auth_SASL_SCRAM extends Auth_SASL_Common { /** * Construct a SCRAM-H client where 'H' is a cryptographic hash function. * * @param string $hash The name cryptographic hash function 'H' as registered by IANA in the "Hash Function Textual * Names" registry. * @link http://www.iana.org/assignments/hash-function-text-names/hash-function-text-names.xml "Hash Function Textual * Names" * format of core PHP hash function. * @access public */ function __construct($hash) { // Though I could be strict, I will actually also accept the naming used in the PHP core hash framework. // For instance "sha1" is accepted, while the registered hash name should be "SHA-1". $hash = strtolower($hash); $hashes = array('md2' => 'md2', 'md5' => 'md5', 'sha-1' => 'sha1', 'sha1' => 'sha1', 'sha-224' > 'sha224', 'sha224' > 'sha224', 'sha-256' => 'sha256', 'sha256' => 'sha256', 'sha-384' => 'sha384', 'sha384' => 'sha384', 'sha-512' => 'sha512', 'sha512' => 'sha512'); if (function_exists('hash_hmac') && isset($hashes[$hash])) { $this->hash = create_function('$data', 'return hash("' . $hashes[$hash] . '", $data, TRUE);'); $this->hmac = create_function('$key,$str,$raw', 'return hash_hmac("' . $hashes[$hash] . '", $str, $key, $raw);'); } elseif ($hash == 'md5') { $this->hash = create_function('$data', 'return md5($data, true);'); $this->hmac = array($this, '_HMAC_MD5'); } elseif (in_array($hash, array('sha1', 'sha-1'))) { $this->hash = create_function('$data', 'return sha1($data, true);'); $this->hmac = array($this, '_HMAC_SHA1'); } else return PEAR::raiseError('Invalid SASL mechanism type'); } /** * Provides the (main) client response for SCRAM-H. * * @param string $authcid Authentication id (username) * @param string $pass Password * @param string $challenge The challenge sent by the server. * If the challenge is NULL or an empty string, the result will be the "initial response". * @param string $authzid Authorization id (username to proxy as) * @return string|false The response (binary, NOT base64 encoded) * @access public */ public function getResponse($authcid, $pass, $challenge = NULL, $authzid = NULL) { $authcid = $this->_formatName($authcid); if (empty($authcid)) { return false; } if (!empty($authzid)) { $authzid = $this->_formatName($authzid); if (empty($authzid)) { return false; } } if (empty($challenge)) { return $this->_generateInitialResponse($authcid, $authzid); } else { return $this->_generateResponse($challenge, $pass); } } /** * Prepare a name for inclusion in a SCRAM response. * * @param string $username a name to be prepared. * @return string the reformated name. * @access private */ private function _formatName($username) { // TODO: prepare through the SASLprep profile of the stringprep algorithm. // See RFC-4013. $username = str_replace('=', '=3D', $username); $username = str_replace(',', '=2C', $username); return $username; } /** * Generate the initial response which can be either sent directly in the first message or as a response to an empty * server challenge. * * @param string $authcid Prepared authentication identity. * @param string $authzid Prepared authorization identity. * @return string The SCRAM response to send. * @access private */ private function _generateInitialResponse($authcid, $authzid) { $init_rep = ''; $gs2_cbind_flag = 'n,'; // TODO: support channel binding. $this->gs2_header = $gs2_cbind_flag . (!empty($authzid)? 'a=' . $authzid : '') . ','; // I must generate a client nonce and "save" it for later comparison on second response. $this->cnonce = $this->_getCnonce(); // XXX: in the future, when mandatory and/or optional extensions are defined in any updated RFC, // this message can be updated. $this->first_message_bare = 'n=' . $authcid . ',r=' . $this->cnonce; return $this->gs2_header . $this->first_message_bare; } /** * Parses and verifies a non-empty SCRAM challenge. * * @param string $challenge The SCRAM challenge * @return string|false The response to send; false in case of wrong challenge or if an initial response has not * been generated first. * @access private */ private function _generateResponse($challenge, $password) { // XXX: as I don't support mandatory extension, I would fail on them. // And I simply ignore any optional extension. $server_message_regexp = "#^r=([\x21-\x2B\x2D-\x7E]+),s=((?:[A-Za-z0-9/+]{4})*(?:[A-Za-z0-9]{3}=|[A-Xa-z0-9]{2}==)?),i=([0-9]*)(,[A-Za-z]=[^,])*$#"; if (!isset($this->cnonce, $this->gs2_header) || !preg_match($server_message_regexp, $challenge, $matches)) { return false; } $nonce = $matches[1]; $salt = base64_decode($matches[2]); if (!$salt) { // Invalid Base64. return false; } $i = intval($matches[3]); $cnonce = substr($nonce, 0, strlen($this->cnonce)); if ($cnonce <> $this->cnonce) { // Invalid challenge! Are we under attack? return false; } $channel_binding = 'c=' . base64_encode($this->gs2_header); // TODO: support channel binding. $final_message = $channel_binding . ',r=' . $nonce; // XXX: no extension. // TODO: $password = $this->normalize($password); // SASLprep profile of stringprep. $saltedPassword = $this->hi($password, $salt, $i); $this->saltedPassword = $saltedPassword; $clientKey = call_user_func($this->hmac, $saltedPassword, "Client Key", TRUE); $storedKey = call_user_func($this->hash, $clientKey, TRUE); $authMessage = $this->first_message_bare . ',' . $challenge . ',' . $final_message; $this->authMessage = $authMessage; $clientSignature = call_user_func($this->hmac, $storedKey, $authMessage, TRUE); $clientProof = $clientKey ^ $clientSignature; $proof = ',p=' . base64_encode($clientProof); return $final_message . $proof; } /** * SCRAM has also a server verification step. On a successful outcome, it will send additional data which must * absolutely be checked against this function. If this fails, the entity which we are communicating with is probably * not the server as it has not access to your ServerKey. * * @param string $data The additional data sent along a successful outcome. * @return bool Whether the server has been authenticated. * If false, the client must close the connection and consider to be under a MITM attack. * @access public */ public function processOutcome($data) { $verifier_regexp = '#^v=((?:[A-Za-z0-9/+]{4})*(?:[A-Za-z0-9]{3}=|[A-Xa-z0-9]{2}==)?)$#'; if (!isset($this->saltedPassword, $this->authMessage) || !preg_match($verifier_regexp, $data, $matches)) { // This cannot be an outcome, you never sent the challenge's response. return false; } $verifier = $matches[1]; $proposed_serverSignature = base64_decode($verifier); $serverKey = call_user_func($this->hmac, $this->saltedPassword, "Server Key", true); $serverSignature = call_user_func($this->hmac, $serverKey, $this->authMessage, TRUE); return ($proposed_serverSignature === $serverSignature); } /** * Hi() call, which is essentially PBKDF2 (RFC-2898) with HMAC-H() as the pseudorandom function. * * @param string $str The string to hash. * @param string $hash The hash value. * @param int $i The iteration count. * @access private */ private function hi($str, $salt, $i) { $int1 = "\0\0\0\1"; $ui = call_user_func($this->hmac, $str, $salt . $int1, true); $result = $ui; for ($k = 1; $k < $i; $k++) { $ui = call_user_func($this->hmac, $str, $ui, true); $result = $result ^ $ui; } return $result; } /** * Creates the client nonce for the response * * @return string The cnonce value * @access private * @author Richard Heyes */ private function _getCnonce() { // TODO: I reused the nonce function from the DigestMD5 class. // I should probably make this a protected function in Common. if (@file_exists('/dev/urandom') && $fd = @fopen('/dev/urandom', 'r')) { return base64_encode(fread($fd, 32)); } elseif (@file_exists('/dev/random') && $fd = @fopen('/dev/random', 'r')) { return base64_encode(fread($fd, 32)); } else { $str = ''; for ($i=0; $i<32; $i++) { $str .= chr(mt_rand(0, 255)); } return base64_encode($str); } } } ?> PKu]= = Auth/SASL/Plain.phpnu[ | // +-----------------------------------------------------------------------+ // // $Id$ /** * Implmentation of PLAIN SASL mechanism * * @author Richard Heyes * @access public * @version 1.0 * @package Auth_SASL */ require_once('Auth/SASL/Common.php'); class Auth_SASL_Plain extends Auth_SASL_Common { /** * Returns PLAIN response * * @param string $authcid Authentication id (username) * @param string $pass Password * @param string $authzid Autorization id * @return string PLAIN Response */ function getResponse($authcid, $pass, $authzid = '') { return $authzid . chr(0) . $authcid . chr(0) . $pass; } } ?> PKu]TAuth/SASL/Common.phpnu[ | // +-----------------------------------------------------------------------+ // // $Id$ /** * Common functionality to SASL mechanisms * * @author Richard Heyes * @access public * @version 1.0 * @package Auth_SASL */ class Auth_SASL_Common { /** * Function which implements HMAC MD5 digest * * @param string $key The secret key * @param string $data The data to hash * @param bool $raw_output Whether the digest is returned in binary or hexadecimal format. * * @return string The HMAC-MD5 digest */ function _HMAC_MD5($key, $data, $raw_output = FALSE) { if (strlen($key) > 64) { $key = pack('H32', md5($key)); } if (strlen($key) < 64) { $key = str_pad($key, 64, chr(0)); } $k_ipad = substr($key, 0, 64) ^ str_repeat(chr(0x36), 64); $k_opad = substr($key, 0, 64) ^ str_repeat(chr(0x5C), 64); $inner = pack('H32', md5($k_ipad . $data)); $digest = md5($k_opad . $inner, $raw_output); return $digest; } /** * Function which implements HMAC-SHA-1 digest * * @param string $key The secret key * @param string $data The data to hash * @param bool $raw_output Whether the digest is returned in binary or hexadecimal format. * @return string The HMAC-SHA-1 digest * @author Jehan * @access protected */ protected function _HMAC_SHA1($key, $data, $raw_output = FALSE) { if (strlen($key) > 64) { $key = sha1($key, TRUE); } if (strlen($key) < 64) { $key = str_pad($key, 64, chr(0)); } $k_ipad = substr($key, 0, 64) ^ str_repeat(chr(0x36), 64); $k_opad = substr($key, 0, 64) ^ str_repeat(chr(0x5C), 64); $inner = pack('H40', sha1($k_ipad . $data)); $digest = sha1($k_opad . $inner, $raw_output); return $digest; } } ?> PKu]P(~T T Auth/SASL/CramMD5.phpnu[ | // +-----------------------------------------------------------------------+ // // $Id$ /** * Implmentation of CRAM-MD5 SASL mechanism * * @author Richard Heyes * @access public * @version 1.0 * @package Auth_SASL */ require_once('Auth/SASL/Common.php'); class Auth_SASL_CramMD5 extends Auth_SASL_Common { /** * Implements the CRAM-MD5 SASL mechanism * This DOES NOT base64 encode the return value, * you will need to do that yourself. * * @param string $user Username * @param string $pass Password * @param string $challenge The challenge supplied by the server. * this should be already base64_decoded. * * @return string The string to pass back to the server, of the form * " ". This is NOT base64_encoded. */ function getResponse($user, $pass, $challenge) { return $user . ' ' . $this->_HMAC_MD5($pass, $challenge); } } ?>PKu]2r Auth/SASL.phpnu[ | // +-----------------------------------------------------------------------+ // // $Id$ /** * Client implementation of various SASL mechanisms * * @author Richard Heyes * @access public * @version 1.0 * @package Auth_SASL */ require_once('PEAR.php'); class Auth_SASL { /** * Factory class. Returns an object of the request * type. * * @param string $type One of: Anonymous * Plain * CramMD5 * DigestMD5 * SCRAM-* (any mechanism of the SCRAM family) * Types are not case sensitive */ public static function factory($type) { switch (strtolower($type)) { case 'anonymous': $filename = 'Auth/SASL/Anonymous.php'; $classname = 'Auth_SASL_Anonymous'; break; case 'login': $filename = 'Auth/SASL/Login.php'; $classname = 'Auth_SASL_Login'; break; case 'plain': $filename = 'Auth/SASL/Plain.php'; $classname = 'Auth_SASL_Plain'; break; case 'external': $filename = 'Auth/SASL/External.php'; $classname = 'Auth_SASL_External'; break; case 'crammd5': // $msg = 'Deprecated mechanism name. Use IANA-registered name: CRAM-MD5.'; // trigger_error($msg, E_USER_DEPRECATED); case 'cram-md5': $filename = 'Auth/SASL/CramMD5.php'; $classname = 'Auth_SASL_CramMD5'; break; case 'digestmd5': // $msg = 'Deprecated mechanism name. Use IANA-registered name: DIGEST-MD5.'; // trigger_error($msg, E_USER_DEPRECATED); case 'digest-md5': // $msg = 'DIGEST-MD5 is a deprecated SASL mechanism as per RFC-6331. Using it could be a security risk.'; // trigger_error($msg, E_USER_NOTICE); $filename = 'Auth/SASL/DigestMD5.php'; $classname = 'Auth_SASL_DigestMD5'; break; default: $scram = '/^SCRAM-(.{1,9})$/i'; if (preg_match($scram, $type, $matches)) { $hash = $matches[1]; $filename = dirname(__FILE__) .'/SASL/SCRAM.php'; $classname = 'Auth_SASL_SCRAM'; $parameter = $hash; break; } return PEAR::raiseError('Invalid SASL mechanism type'); break; } require_once($filename); if (isset($parameter)) $obj = new $classname($parameter); else $obj = new $classname(); return $obj; } } ?> PKu]T,, OS/Guess.phpnu[ * @author Gregory Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since PEAR 0.1 */ // {{{ uname examples // php_uname() without args returns the same as 'uname -a', or a PHP-custom // string for Windows. // PHP versions prior to 4.3 return the uname of the host where PHP was built, // as of 4.3 it returns the uname of the host running the PHP code. // // PC RedHat Linux 7.1: // Linux host.example.com 2.4.2-2 #1 Sun Apr 8 20:41:30 EDT 2001 i686 unknown // // PC Debian Potato: // Linux host 2.4.17 #2 SMP Tue Feb 12 15:10:04 CET 2002 i686 unknown // // PC FreeBSD 3.3: // FreeBSD host.example.com 3.3-STABLE FreeBSD 3.3-STABLE #0: Mon Feb 21 00:42:31 CET 2000 root@example.com:/usr/src/sys/compile/CONFIG i386 // // PC FreeBSD 4.3: // FreeBSD host.example.com 4.3-RELEASE FreeBSD 4.3-RELEASE #1: Mon Jun 25 11:19:43 EDT 2001 root@example.com:/usr/src/sys/compile/CONFIG i386 // // PC FreeBSD 4.5: // FreeBSD host.example.com 4.5-STABLE FreeBSD 4.5-STABLE #0: Wed Feb 6 23:59:23 CET 2002 root@example.com:/usr/src/sys/compile/CONFIG i386 // // PC FreeBSD 4.5 w/uname from GNU shellutils: // FreeBSD host.example.com 4.5-STABLE FreeBSD 4.5-STABLE #0: Wed Feb i386 unknown // // HP 9000/712 HP-UX 10: // HP-UX iq B.10.10 A 9000/712 2008429113 two-user license // // HP 9000/712 HP-UX 10 w/uname from GNU shellutils: // HP-UX host B.10.10 A 9000/712 unknown // // IBM RS6000/550 AIX 4.3: // AIX host 3 4 000003531C00 // // AIX 4.3 w/uname from GNU shellutils: // AIX host 3 4 000003531C00 unknown // // SGI Onyx IRIX 6.5 w/uname from GNU shellutils: // IRIX64 host 6.5 01091820 IP19 mips // // SGI Onyx IRIX 6.5: // IRIX64 host 6.5 01091820 IP19 // // SparcStation 20 Solaris 8 w/uname from GNU shellutils: // SunOS host.example.com 5.8 Generic_108528-12 sun4m sparc // // SparcStation 20 Solaris 8: // SunOS host.example.com 5.8 Generic_108528-12 sun4m sparc SUNW,SPARCstation-20 // // Mac OS X (Darwin) // Darwin home-eden.local 7.5.0 Darwin Kernel Version 7.5.0: Thu Aug 5 19:26:16 PDT 2004; root:xnu/xnu-517.7.21.obj~3/RELEASE_PPC Power Macintosh // // Mac OS X early versions // // }}} /* TODO: * - define endianness, to allow matchSignature("bigend") etc. */ /** * Retrieves information about the current operating system * * This class uses php_uname() to grok information about the current OS * * @category pear * @package PEAR * @author Stig Bakken * @author Gregory Beaver * @copyright 1997-2020 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 0.1 */ class OS_Guess { var $sysname; var $nodename; var $cpu; var $release; var $extra; function __construct($uname = null) { list($this->sysname, $this->release, $this->cpu, $this->extra, $this->nodename) = $this->parseSignature($uname); } function parseSignature($uname = null) { static $sysmap = array( 'HP-UX' => 'hpux', 'IRIX64' => 'irix', ); static $cpumap = array( 'i586' => 'i386', 'i686' => 'i386', 'ppc' => 'powerpc', ); if ($uname === null) { $uname = php_uname(); } $parts = preg_split('/\s+/', trim($uname)); $n = count($parts); $release = $machine = $cpu = ''; $sysname = $parts[0]; $nodename = $parts[1]; $cpu = $parts[$n-1]; $extra = ''; if ($cpu == 'unknown') { $cpu = $parts[$n - 2]; } switch ($sysname) { case 'AIX' : $release = "$parts[3].$parts[2]"; break; case 'Windows' : $release = $parts[1]; if ($release == '95/98') { $release = '9x'; } $cpu = 'i386'; break; case 'Linux' : $extra = $this->_detectGlibcVersion(); // use only the first two digits from the kernel version $release = preg_replace('/^([0-9]+\.[0-9]+).*/', '\1', $parts[2]); break; case 'Mac' : $sysname = 'darwin'; $nodename = $parts[2]; $release = $parts[3]; $cpu = $this->_determineIfPowerpc($cpu, $parts); break; case 'Darwin' : $cpu = $this->_determineIfPowerpc($cpu, $parts); $release = preg_replace('/^([0-9]+\.[0-9]+).*/', '\1', $parts[2]); break; default: $release = preg_replace('/-.*/', '', $parts[2]); break; } if (isset($sysmap[$sysname])) { $sysname = $sysmap[$sysname]; } else { $sysname = strtolower($sysname); } if (isset($cpumap[$cpu])) { $cpu = $cpumap[$cpu]; } return array($sysname, $release, $cpu, $extra, $nodename); } function _determineIfPowerpc($cpu, $parts) { $n = count($parts); if ($cpu == 'Macintosh' && $parts[$n - 2] == 'Power') { $cpu = 'powerpc'; } return $cpu; } function _detectGlibcVersion() { static $glibc = false; if ($glibc !== false) { return $glibc; // no need to run this multiple times } $major = $minor = 0; include_once "System.php"; // Let's try reading possible libc.so.6 symlinks $libcs = array( '/lib64/libc.so.6', '/lib/libc.so.6', '/lib/i386-linux-gnu/libc.so.6' ); $versions = array(); foreach ($libcs as $file) { $versions = $this->_readGlibCVersionFromSymlink($file); if ($versions != []) { list($major, $minor) = $versions; break; } } // Use glibc's header file to // get major and minor version number: if (!($major && $minor)) { $versions = $this->_readGlibCVersionFromFeaturesHeaderFile(); } if (is_array($versions) && $versions != []) { list($major, $minor) = $versions; } if (!($major && $minor)) { return $glibc = ''; } return $glibc = "glibc{$major}.{$minor}"; } function _readGlibCVersionFromSymlink($file) { $versions = array(); if (@is_link($file) && (preg_match('/^libc-(.*)\.so$/', basename(readlink($file)), $matches)) ) { $versions = explode('.', $matches[1]); } return $versions; } function _readGlibCVersionFromFeaturesHeaderFile() { $features_header_file = '/usr/include/features.h'; if (!(@file_exists($features_header_file) && @is_readable($features_header_file)) ) { return array(); } if (!@file_exists('/usr/bin/cpp') || !@is_executable('/usr/bin/cpp')) { return $this->_parseFeaturesHeaderFile($features_header_file); } // no cpp return $this->_fromGlibCTest(); } function _parseFeaturesHeaderFile($features_header_file) { $features_file = fopen($features_header_file, 'rb'); while (!feof($features_file)) { $line = fgets($features_file, 8192); if (!$this->_IsADefinition($line)) { continue; } if (strpos($line, '__GLIBC__')) { // major version number #define __GLIBC__ version $line = preg_split('/\s+/', $line); $glibc_major = trim($line[2]); if (isset($glibc_minor)) { break; } continue; } if (strpos($line, '__GLIBC_MINOR__')) { // got the minor version number // #define __GLIBC_MINOR__ version $line = preg_split('/\s+/', $line); $glibc_minor = trim($line[2]); if (isset($glibc_major)) { break; } } } fclose($features_file); if (!isset($glibc_major) || !isset($glibc_minor)) { return array(); } return array(trim($glibc_major), trim($glibc_minor)); } function _IsADefinition($line) { if ($line === false) { return false; } return strpos(trim($line), '#define') !== false; } function _fromGlibCTest() { $major = null; $minor = null; $tmpfile = System::mktemp("glibctest"); $fp = fopen($tmpfile, "w"); fwrite($fp, "#include \n__GLIBC__ __GLIBC_MINOR__\n"); fclose($fp); $cpp = popen("/usr/bin/cpp $tmpfile", "r"); while ($line = fgets($cpp, 1024)) { if ($line[0] == '#' || trim($line) == '') { continue; } if (list($major, $minor) = explode(' ', trim($line))) { break; } } pclose($cpp); unlink($tmpfile); if ($major !== null && $minor !== null) { return [$major, $minor]; } } function getSignature() { if (empty($this->extra)) { return "{$this->sysname}-{$this->release}-{$this->cpu}"; } return "{$this->sysname}-{$this->release}-{$this->cpu}-{$this->extra}"; } function getSysname() { return $this->sysname; } function getNodename() { return $this->nodename; } function getCpu() { return $this->cpu; } function getRelease() { return $this->release; } function getExtra() { return $this->extra; } function matchSignature($match) { $fragments = is_array($match) ? $match : explode('-', $match); $n = count($fragments); $matches = 0; if ($n > 0) { $matches += $this->_matchFragment($fragments[0], $this->sysname); } if ($n > 1) { $matches += $this->_matchFragment($fragments[1], $this->release); } if ($n > 2) { $matches += $this->_matchFragment($fragments[2], $this->cpu); } if ($n > 3) { $matches += $this->_matchFragment($fragments[3], $this->extra); } return ($matches == $n); } function _matchFragment($fragment, $value) { if (strcspn($fragment, '*?') < strlen($fragment)) { $expression = str_replace( array('*', '?', '/'), array('.*', '.', '\\/'), $fragment ); $reg = '/^' . $expression . '\\z/'; return preg_match($reg, $value); } return ($fragment == '*' || !strcasecmp($fragment, $value)); } } /* * Local Variables: * indent-tabs-mode: nil * c-basic-offset: 4 * End: */ PKu]ҵ3>test/Mail_mimeDecode/tests/semicolon_content_type_bug1724.phptnu[--TEST-- Bug #1724 Quoted Semicolons in Content-Type --SKIPIF-- --FILE-- setTXTBody('Test message.'); $Mime->addAttachment('test file contents', 'text/plain; testparam="test1;semicolon"', 'test.txt', FALSE); $body = $Mime->get(); $hdrs = ''; foreach ($Mime->headers() AS $name => $val) { $hdrs .= "$name: $val\n"; } $hdrs .= "To: Receiver \n"; $hdrs .= "From: Sender \n"; $hdrs .= "Subject: PEAR::Mail_Mime test mail\n"; require_once('Mail/mimeDecode.php'); $mime_message = "$hdrs\n$body"; $Decoder = new Mail_mimeDecode($mime_message); $params = array( 'include_bodies' => TRUE, 'decode_bodies' => TRUE, 'decode_headers' => TRUE ); $Decoded = $Decoder->decode($params); $test_param = $Decoded->parts[1]->ctype_parameters['testparam']; echo $test_param; ?> --EXPECT-- test1;semicolon PKu]s%2test/Mail_mimeDecode/tests/parse_header_value.phptnu[--TEST-- Tests for _parseHeaderValue --SKIPIF-- --FILE-- setTXTBody('Test message.'); $contentAppend = 'testparam1="test1;semicolon";testparam2=two; testparam3="three"; ' .'testparam4="four\;4\;four"; testparam5=five\;5\;five; ' ."testparam6='six'; testparam7='seven;7';testparam8='eight\;8'; " .'testparam9="nine;9";testparam10="ten\;10"; ' .'testparam11=\'a "double" quote\'; testparam12="a \'simple\' quote"; ' .'testparam13=\'another " quote\'; testparam14="another \' quote";' .'testparam15=last'; $Mime->addAttachment('test file contents', "text/plain; $contentAppend", 'test.txt', FALSE); $body = $Mime->get(); $hdrs = ''; foreach ($Mime->headers() AS $name => $val) { $hdrs .= "$name: $val\n"; } $hdrs .= "To: Receiver \n"; $hdrs .= "From: Sender \n"; $hdrs .= "Subject: PEAR::Mail_Mime test mail\n"; require_once 'Mail/mimeDecode.php'; $mime_message = "$hdrs\n$body"; $Decoder = new Mail_mimeDecode($mime_message); $params = array( 'include_bodies' => TRUE, 'decode_bodies' => TRUE, 'decode_headers' => TRUE ); $Decoded = $Decoder->decode($params); $decodedParts = $Decoded->parts[1]->ctype_parameters; //Bug #4057: Content-type params now have a name attribute. unset($decodedParts['name']); print_r($decodedParts); ?> --EXPECT-- Array ( [testparam1] => test1;semicolon [testparam2] => two [testparam3] => three [testparam4] => four;4;four [testparam5] => five;5;five [testparam6] => six [testparam7] => seven;7 [testparam8] => eight;8 [testparam9] => nine;9 [testparam10] => ten;10 [testparam11] => a "double" quote [testparam12] => a 'simple' quote [testparam13] => another " quote [testparam14] => another ' quote [testparam15] => last ) PKu]Zx5test/Structures_LinkedList/tests/single_link_002.phptnu[--TEST-- single_link_002: Append links to an initially empty linked list --FILE-- appendNode($tester1); $xyy->appendNode($tester2); $xyy->appendNode($tester3); $xyy->insertNode($tester4, $tester2, true); $link = $xyy->current(); print $link->getNumb(); // test iteration with while() while ($link = $xyy->next()) { print $link->getNumb(); } $link = $xyy->rewind(); print "\n"; print $link->getNumb(); print "\n"; // test foreach() iteration foreach ($xyy as $bull) { print $bull->getNumb(); } ?> --EXPECT-- 1423 1 1423 PKu]骗.test/Structures_LinkedList/tests/link_006.phptnu[--TEST-- link_006: Corner case: add a node before the root --FILE-- prependNode($tester1); $xyy->appendNode($tester2); $xyy->appendNode($tester3); $xyy->insertNode($tester4, $tester2, true); // Ensure we can increment the current node without messing up the list print "\nCurrent: " . $xyy->current()->getNumb() . "\n"; $link = $xyy->next(); print "Current: " . $link->getNumb() . "\n"; $xyy->insertNode($tester5, $tester1, true); print "\n"; $link = $xyy->current(); print "Current: " . $link->getNumb(); print "\n\nWhile: "; // test iteration with while() $link = $xyy->rewind(); do { print $link->getNumb(); } while ($link = $xyy->next()); print "\n\nForeach: "; // test foreach() iteration foreach ($xyy as $bull) { print $bull->getNumb(); } ?> --EXPECT-- Current: 1 Current: 4 Current: 4 While: 51423 Foreach: 51423 PKu]o.test/Structures_LinkedList/tests/link_003.phptnu[--TEST-- link_003: Append links in a specific order --FILE-- appendNode($tester1); print $tester1->getNumb() . "\n"; // add after initial link $xyy->appendNode($tester2); print $tester2->getNumb() . "\n"; // add after initial link, bumping #2 up $xyy->insertNode($tester3, $tester1); print $tester3->getNumb() . "\n"; // add after link #3, bumping #2 up again $xyy->insertNode($tester4, $tester3); print $tester4->getNumb() . "\n"; print "\n"; $link = $xyy->current(); print $link->getNumb(); print "\n"; // test iteration with while() while ($link = $xyy->next()) { print $link->getNumb(); print "\n"; } $link = $xyy->rewind(); print "\n"; print $link->getNumb(); print "\n"; // test foreach() iteration foreach ($xyy as $bull) { print $bull->getNumb(); } ?> --EXPECT-- 1 2 3 4 1 3 4 2 1 1342 PKu]).test/Structures_LinkedList/tests/link_002.phptnu[--TEST-- link_002: Append links to an initially empty linked list --FILE-- appendNode($tester1); $xyy->appendNode($tester2); $xyy->appendNode($tester3); $xyy->insertNode($tester4, $tester2, true); $link = $xyy->current(); print $link->getNumb(); // test iteration with while() while ($link = $xyy->next()) { print $link->getNumb(); } $link = $xyy->rewind(); print "\n"; print $link->getNumb(); print "\n"; // test foreach() iteration foreach ($xyy as $bull) { print $bull->getNumb(); } ?> --EXPECT-- 1423 1 1423 PKu]15test/Structures_LinkedList/tests/single_link_007.phptnu[--TEST-- single_link_007: Test many corner cases --FILE-- prependNode($tester1); print "Current: {$xyy->current()->getNumb()}\n"; // prepend to a list with only one element: 21 $xyy->prependNode($tester2); print "Current: {$xyy->current()->getNumb()}\n"; // insert after tail node corner case: 213 $xyy->insertNode($tester3, $tester1); print "Current: {$xyy->current()->getNumb()}\n"; // insert before root node corner case: 4213 $xyy->insertNode($tester4, $tester2, true); print "Current: {$xyy->current()->getNumb()}\n"; // insert before tail node corner case: 42153 $xyy->insertNode($tester5, $tester3, true); print "Current: {$xyy->current()->getNumb()}\n"; print "Foreach: "; foreach ($xyy as $node) { print $node->getNumb(); } print "\nWhile (in reverse): "; // test reverse iteration with while() $link = $xyy->end(); do { print $link->getNumb(); } while ($link = $xyy->previous()); ?> --EXPECT-- Current: 1 Current: 1 Current: 1 Current: 1 Current: 1 Foreach: 42153 While (in reverse): 35124 PKu]45test/Structures_LinkedList/tests/single_link_001.phptnu[--TEST-- single_link_001: Test linked list constructed with an initial link --FILE-- appendNode($tester2); $xyy->appendNode($tester3); $xyy->appendNode($tester4); $link = $xyy->current(); print "Current: " . $link->getNumb() . "\n"; print "While: "; // test iteration with while() do { print $link->getNumb(); } while ($link = $xyy->next()); print "\nRewind: "; $link = $xyy->rewind(); print $link->getNumb(); print "\n"; print "Foreach: "; // test foreach() iteration foreach ($xyy as $bull) { print $bull->getNumb(); } print "\nEnd: "; $link = $xyy->end(); print $link->getNumb(); print "\n"; print "While (in reverse): "; // test iteration with while() do { print $link->getNumb(); } while ($link = $xyy->previous()); ?> --EXPECT-- Current: 1 While: 1234 Rewind: 1 Foreach: 1234 End: 4 While (in reverse): 4321 PKu] .test/Structures_LinkedList/tests/link_001.phptnu[--TEST-- link_001: Test linked list constructed with an initial link --FILE-- appendNode($tester2); $xyy->appendNode($tester3); $xyy->appendNode($tester4); $link = $xyy->current(); print "Current: " . $link->getNumb() . "\n"; print "While: "; // test iteration with while() do { print $link->getNumb(); } while ($link = $xyy->next()); print "\nRewind: "; $link = $xyy->rewind(); print $link->getNumb(); print "\n"; print "Foreach: "; // test foreach() iteration foreach ($xyy as $bull) { print $bull->getNumb(); } print "\nEnd: "; $link = $xyy->end(); print $link->getNumb(); print "\n"; print "While (in reverse): "; // test iteration with while() do { print $link->getNumb(); } while ($link = $xyy->previous()); ?> --EXPECT-- Current: 1 While: 1234 Rewind: 1 Foreach: 1234 End: 4 While (in reverse): 4321 PKu]K5test/Structures_LinkedList/tests/single_link_003.phptnu[--TEST-- single_link_003: Append links in a specific order --FILE-- appendNode($tester1); print $tester1->getNumb() . "\n"; // add after initial link $xyy->appendNode($tester2); print $tester2->getNumb() . "\n"; // add after initial link, bumping #2 up $xyy->insertNode($tester3, $tester1); print $tester3->getNumb() . "\n"; // add after link #3, bumping #2 up again $xyy->insertNode($tester4, $tester3); print $tester4->getNumb() . "\n"; print "\n"; $link = $xyy->current(); print $link->getNumb(); print "\n"; // test iteration with while() while ($link = $xyy->next()) { print $link->getNumb(); print "\n"; } $link = $xyy->rewind(); print "\n"; print $link->getNumb(); print "\n"; // test foreach() iteration foreach ($xyy as $bull) { print $bull->getNumb(); } ?> --EXPECT-- 1 2 3 4 1 3 4 2 1 1342 PKu])y--5test/Structures_LinkedList/tests/single_link_004.phptnu[--TEST-- single_link_004: Delete every link in the list --FILE-- appendNode($tester2); $xyy->appendNode($tester3); $xyy->appendNode($tester4); // Delete all nodes from the list while ($link = $xyy->rewind()) { print "Deleted " . $link->getNumb() . "\n"; $xyy->deleteNode($link); } $link = $xyy->rewind(); print "Done\n"; ?> --EXPECT-- Deleted 1 Deleted 2 Deleted 3 Deleted 4 Done PKu]|5test/Structures_LinkedList/tests/SingleLinkTester.phpnu[_my_number = $num; } function getNumb() { return $this->_my_number; } function setNumb($numb) { $this->_my_number = $numb; } } $tester1 = new LinkTester(1); $tester2 = new LinkTester(2); $tester3 = new LinkTester(3); $tester4 = new LinkTester(4); $tester5 = new LinkTester(5); ?> PKu]sDHH.test/Structures_LinkedList/tests/link_007.phptnu[--TEST-- link_007: Test many corner cases --FILE-- prependNode($tester1); print "Current: {$xyy->current()->getNumb()}\n"; // prepend to a list with only one element: 21 $xyy->prependNode($tester2); print "Current: {$xyy->current()->getNumb()}\n"; // insert after tail node corner case: 213 $xyy->insertNode($tester3, $tester1); print "Current: {$xyy->current()->getNumb()}\n"; // insert before root node corner case: 4213 $xyy->insertNode($tester4, $tester2, true); print "Current: {$xyy->current()->getNumb()}\n"; // insert before tail node corner case: 42153 $xyy->insertNode($tester5, $tester3, true); print "Current: {$xyy->current()->getNumb()}\n"; // insert after root node corner case: 421653 $xyy->insertNode($tester6, $tester1); print "Current: {$xyy->current()->getNumb()}\n"; print "Foreach: "; foreach ($xyy as $node) { print $node->getNumb(); } print "\nWhile (in reverse): "; // test reverse iteration with while() $link = $xyy->end(); do { print $link->getNumb(); } while ($link = $xyy->previous()); ?> --EXPECT-- Current: 1 Current: 1 Current: 1 Current: 1 Current: 1 Current: 1 Foreach: 421653 While (in reverse): 356124 PKu]髂[5test/Structures_LinkedList/tests/single_link_006.phptnu[--TEST-- single_link_006: Corner case: add a node before the root --FILE-- prependNode($tester1); $xyy->appendNode($tester2); $xyy->appendNode($tester3); $xyy->insertNode($tester4, $tester2, true); // Ensure we can increment the current node without messing up the list print "\nCurrent: " . $xyy->current()->getNumb() . "\n"; $link = $xyy->next(); print "Current: " . $link->getNumb() . "\n"; $xyy->insertNode($tester5, $tester1, true); print "\n"; $link = $xyy->current(); print "Current: " . $link->getNumb(); print "\n\nWhile: "; // test iteration with while() $link = $xyy->rewind(); do { print $link->getNumb(); } while ($link = $xyy->next()); print "\n\nForeach: "; // test foreach() iteration foreach ($xyy as $bull) { print $bull->getNumb(); } ?> --EXPECT-- Current: 1 Current: 4 Current: 4 While: 51423 Foreach: 51423 PKu].test/Structures_LinkedList/tests/link_005.phptnu[--TEST-- link_005: Pass different class types to constructors --FILE-- _my_number = $num; parent::__construct($tester); } } class TesterFail { protected $summary; protected $fulltext; function __construct($summary, $fulltext) { $this->summary = $summary; $this->fulltext = $fulltext; } } // This should work: TesterExtend extends the Structure_LinkedList_DoubleNode class $tester_extend = new TesterExtend(null, 1); $xyy = new Structures_LinkedList_Double($tester_extend); print "Checking for errors in the expected success case:\n"; // This should fail print "Checking for errors in the expected failure case:\n"; $tester_fail = new TesterFail(null, 1); $xyy_fail = new Structures_LinkedList_Double($tester_fail); ?> --EXPECTF-- Checking for errors in the expected success case: Checking for errors in the expected failure case: %satal error: Argument 1 passed to Structures_LinkedList_Double::__construct() must be an instance of Structures_LinkedList_DoubleNode%s PKu]#,E5test/Structures_LinkedList/tests/single_link_005.phptnu[--TEST-- single_link_005: Pass different class types to constructors --FILE-- _my_number = $num; parent::__construct($tester); } } class TesterFail { protected $summary; protected $fulltext; function __construct($summary, $fulltext) { $this->summary = $summary; $this->fulltext = $fulltext; } } // This should work: TesterExtend extends the Structure_LinkedList_SingleNode class $tester_extend = new TesterExtend(null, 1); $xyy = new Structures_LinkedList_Single($tester_extend); print "Checking for errors in the expected success case:\n"; // This should fail print "Checking for errors in the expected failure case:\n"; $tester_fail = new TesterFail(null, 1); $xyy_fail = new Structures_LinkedList_Single($tester_fail); ?> --EXPECTF-- Checking for errors in the expected success case: Checking for errors in the expected failure case: %satal error: Argument 1 passed to Structures_LinkedList_Single::__construct() must be an instance of Structures_LinkedList_SingleNode%s PKu](  .test/Structures_LinkedList/tests/link_004.phptnu[--TEST-- link_004: Delete every link in the list --FILE-- appendNode($tester2); $xyy->appendNode($tester3); $xyy->appendNode($tester4); // Delete all nodes from the list while ($link = $xyy->rewind()) { print "Deleted " . $link->getNumb() . "\n"; $xyy->deleteNode($link); } $link = $xyy->rewind(); print "Done\n"; ?> --EXPECT-- Deleted 1 Deleted 2 Deleted 3 Deleted 4 Done PKu]/test/Structures_LinkedList/tests/LinkTester.phpnu[_my_number = $num; } function getNumb() { return $this->_my_number; } function setNumb($numb) { $this->_my_number = $numb; } } $tester1 = new LinkTester(1); $tester2 = new LinkTester(2); $tester3 = new LinkTester(3); $tester4 = new LinkTester(4); $tester5 = new LinkTester(5); $tester6 = new LinkTester(6); ?> PKu]E mm&test/Net_IDNA2/tests/Net_IDNA2Test.phpnu[idn = new Net_IDNA2(); } /** * Test if a complete URL consisting also of port-number etc. will be decoded just fine, test 1 * * @return void */ public function testShouldDecodePortNumbersFragmentsAndUrisCorrectly1() { $result = $this->idn->decode('http://www.xn--ml-6kctd8d6a.org:8080/test.php?arg1=1&arg2=2#fragment'); $this->assertSame("http://www.\xD0\xB5\xD1\x85\xD0\xB0m\xD1\x80l\xD0\xB5.org:8080/test.php?arg1=1&arg2=2#fragment", $result); } /** * Test if a complete URL consisting also of port-number etc. will be decoded just fine, test 2 * * @return void */ public function testShouldDecodePortNumbersFragmentsAndUrisCorrectly2() { $result = $this->idn->decode('http://xn--tst-qla.example.com:8080/test.php?arg1=1&arg2=2#fragment'); $this->assertSame("http://täst.example.com:8080/test.php?arg1=1&arg2=2#fragment", $result); } /** * Test encoding of German letter Eszett according to the original standard (IDNA2003) * * @return void */ public function testEncodingForGermanEszettUsingIDNA2003() { // make sure to use 2003-encoding $this->idn->setParams('version', '2003'); $result = $this->idn->encode('http://www.straße.example.com/'); $this->assertSame("http://www.strasse.example.com/", $result); } /** * Test encoding of German letter Eszett according to the "new" standard (IDNA2005/IDNAbis) * * @return void */ public function testEncodingForGermanEszettUsingIDNA2008() { // make sure to use 2008-encoding $this->idn->setParams('version', '2008'); $result = $this->idn->encode('http://www.straße.example.com/'); // switch back for other testcases $this->idn->setParams('version', '2003'); $this->assertSame("http://www.xn--strae-oqa.example.com/", $result); } } PKu]?7EE9test/Net_IDNA2/tests/draft-josefsson-idn-test-vectors.phpnu[idn = new Net_IDNA2(); } static function unichr($chr) { return mb_convert_encoding('&#' . intval($chr) . ';', 'UTF-8', 'HTML-ENTITIES'); } private function hexarray2string($arr) { return implode('', array_map(array('self', 'unichr'), $arr)); } public function testDecode1() { // Arabic (Egyptian) $expected = $this->hexarray2string(array( 0x0644, 0x064A, 0x0647, 0x0645, 0x0627, 0x0628, 0x062A, 0x0643, 0x0644, 0x0645, 0x0648, 0x0634, 0x0639, 0x0631, 0x0628, 0x064A, 0x061F )); $result = $this->idn->decode(IDNA_ACE_PREFIX."egbpdaj6bu4bxfgehfvwxn"); $this->assertSame($expected, $result); } public function testDecode2() { // Chinese (simplified) $expected = $this->hexarray2string(array( 0x4ED6, 0x4EEC, 0x4E3A, 0x4EC0, 0x4E48, 0x4E0D, 0x8BF4, 0x4E2D, 0x6587 )); $result = $this->idn->decode(IDNA_ACE_PREFIX."ihqwcrb4cv8a8dqg056pqjye"); $this->assertSame($expected, $result); } public function testDecode3() { // Chinese (traditional) $expected = $this->hexarray2string(array( 0x4ED6, 0x5011, 0x7232, 0x4EC0, 0x9EBD, 0x4E0D, 0x8AAA, 0x4E2D, 0x6587 )); $result = $this->idn->decode(IDNA_ACE_PREFIX."ihqwctvzc91f659drss3x8bo0yb"); $this->assertSame($expected, $result); } public function testDecode4() { // Czech $expected = $this->hexarray2string(array( 0x0050, 0x0072, 0x006F, 0x010D, 0x0070, 0x0072, 0x006F, 0x0073, 0x0074, 0x011B, 0x006E, 0x0065, 0x006D, 0x006C, 0x0075, 0x0076, 0x00ED, 0x010D, 0x0065, 0x0073, 0x006B, 0x0079 )); $result = $this->idn->decode(IDNA_ACE_PREFIX."Proprostnemluvesky-uyb24dma41a"); $this->assertSame($expected, $result); } public function testDecode5() { // Hebrew $expected = $this->hexarray2string(array( 0x05DC, 0x05DE, 0x05D4, 0x05D4, 0x05DD, 0x05E4, 0x05E9, 0x05D5, 0x05D8, 0x05DC, 0x05D0, 0x05DE, 0x05D3, 0x05D1, 0x05E8, 0x05D9, 0x05DD, 0x05E2, 0x05D1, 0x05E8, 0x05D9, 0x05EA )); $result = $this->idn->decode(IDNA_ACE_PREFIX."4dbcagdahymbxekheh6e0a7fei0b"); $this->assertSame($expected, $result); } public function testDecode6() { // Hindi (Devanagari) $expected = $this->hexarray2string(array( 0x092F, 0x0939, 0x0932, 0x094B, 0x0917, 0x0939, 0x093F, 0x0928, 0x094D, 0x0926, 0x0940, 0x0915, 0x094D, 0x092F, 0x094B, 0x0902, 0x0928, 0x0939, 0x0940, 0x0902, 0x092C, 0x094B, 0x0932, 0x0938, 0x0915, 0x0924, 0x0947, 0x0939, 0x0948, 0x0902 )); $result = $this->idn->decode(IDNA_ACE_PREFIX."i1baa7eci9glrd9b2ae1bj0hfcgg6iyaf8o0a1dig0cd"); $this->assertSame($expected, $result); } public function testDecode7() { // Japanese (kanji and hiragana) $expected = $this->hexarray2string(array( 0x306A, 0x305C, 0x307F, 0x3093, 0x306A, 0x65E5, 0x672C, 0x8A9E, 0x3092, 0x8A71, 0x3057, 0x3066, 0x304F, 0x308C, 0x306A, 0x3044, 0x306E, 0x304B )); $result = $this->idn->decode(IDNA_ACE_PREFIX."n8jok5ay5dzabd5bym9f0cm5685rrjetr6pdxa"); $this->assertSame($expected, $result); } public function testDecode8() { // Russian (Cyrillic) $expected = $this->hexarray2string(array( 0x043F, 0x043E, 0x0447, 0x0435, 0x043C, 0x0443, 0x0436, 0x0435, 0x043E, 0x043D, 0x0438, 0x043D, 0x0435, 0x0433, 0x043E, 0x0432, 0x043E, 0x0440, 0x044F, 0x0442, 0x043F, 0x043E, 0x0440, 0x0443, 0x0441, 0x0441, 0x043A, 0x0438 )); $result = $this->idn->decode(IDNA_ACE_PREFIX."b1abfaaepdrnnbgefbadotcwatmq2g4l"); $this->assertSame($expected, $result); } public function testDecode9() { // Spanish $expected = $this->hexarray2string(array( 0x0050, 0x006F, 0x0072, 0x0071, 0x0075, 0x00E9, 0x006E, 0x006F, 0x0070, 0x0075, 0x0065, 0x0064, 0x0065, 0x006E, 0x0073, 0x0069, 0x006D, 0x0070, 0x006C, 0x0065, 0x006D, 0x0065, 0x006E, 0x0074, 0x0065, 0x0068, 0x0061, 0x0062, 0x006C, 0x0061, 0x0072, 0x0065, 0x006E, 0x0045, 0x0073, 0x0070, 0x0061, 0x00F1, 0x006F, 0x006C )); $result = $this->idn->decode(IDNA_ACE_PREFIX."PorqunopuedensimplementehablarenEspaol-fmd56a"); $this->assertSame($expected, $result); } public function testDecode10() { // Vietnamese $expected = $this->hexarray2string(array( 0x0054, 0x1EA1, 0x0069, 0x0073, 0x0061, 0x006F, 0x0068, 0x1ECD, 0x006B, 0x0068, 0x00F4, 0x006E, 0x0067, 0x0074, 0x0068, 0x1EC3, 0x0063, 0x0068, 0x1EC9, 0x006E, 0x00F3, 0x0069, 0x0074, 0x0069, 0x1EBF, 0x006E, 0x0067, 0x0056, 0x0069, 0x1EC7, 0x0074 )); $result = $this->idn->decode(IDNA_ACE_PREFIX."TisaohkhngthchnitingVit-kjcr8268qyxafd2f1b9g"); $this->assertSame($expected, $result); } public function testDecode11() { // Japanese $expected = $this->hexarray2string(array( 0x0033, 0x5E74, 0x0042, 0x7D44, 0x91D1, 0x516B, 0x5148, 0x751F )); $result = $this->idn->decode(IDNA_ACE_PREFIX."3B-ww4c5e180e575a65lsy2b"); $this->assertSame($expected, $result); } public function testDecode12() { // Japanese $expected = $this->hexarray2string(array( 0x5B89, 0x5BA4, 0x5948, 0x7F8E, 0x6075, 0x002D, 0x0077, 0x0069, 0x0074, 0x0068, 0x002D, 0x0053, 0x0055, 0x0050, 0x0045, 0x0052, 0x002D, 0x004D, 0x004F, 0x004E, 0x004B, 0x0045, 0x0059, 0x0053 )); $result = $this->idn->decode(IDNA_ACE_PREFIX."-with-SUPER-MONKEYS-pc58ag80a8qai00g7n9n"); $this->assertSame($expected, $result); } public function testDecode13() { // Japanese $expected = $this->hexarray2string(array( 0x0048, 0x0065, 0x006C, 0x006C, 0x006F, 0x002D, 0x0041, 0x006E, 0x006F, 0x0074, 0x0068, 0x0065, 0x0072, 0x002D, 0x0057, 0x0061, 0x0079, 0x002D, 0x305D, 0x308C, 0x305E, 0x308C, 0x306E, 0x5834, 0x6240 )); $result = $this->idn->decode(IDNA_ACE_PREFIX."Hello-Another-Way--fc4qua05auwb3674vfr0b"); $this->assertSame($expected, $result); } public function testDecode14() { // Japanese $expected = $this->hexarray2string(array( 0x3072, 0x3068, 0x3064, 0x5C4B, 0x6839, 0x306E, 0x4E0B, 0x0032 )); $result = $this->idn->decode(IDNA_ACE_PREFIX."2-u9tlzr9756bt3uc0v"); $this->assertSame($expected, $result); } public function testDecode15() { // Japanese $expected = $this->hexarray2string(array( 0x004D, 0x0061, 0x006A, 0x0069, 0x3067, 0x004B, 0x006F, 0x0069, 0x3059, 0x308B, 0x0035, 0x79D2, 0x524D )); $result = $this->idn->decode(IDNA_ACE_PREFIX."MajiKoi5-783gue6qz075azm5e"); $this->assertSame($expected, $result); } public function testDecode16() { // Japanese $expected = $this->hexarray2string(array( 0x30D1, 0x30D5, 0x30A3, 0x30FC, 0x0064, 0x0065, 0x30EB, 0x30F3, 0x30D0 )); $result = $this->idn->decode(IDNA_ACE_PREFIX."de-jg4avhby1noc0d"); $this->assertSame($expected, $result); } public function testDecode17() { // Japanese $expected = $this->hexarray2string(array( 0x305D, 0x306E, 0x30B9, 0x30D4, 0x30FC, 0x30C9, 0x3067 )); $result = $this->idn->decode(IDNA_ACE_PREFIX."d9juau41awczczp"); $this->assertSame($expected, $result); } public function testDecode18() { // Greek $expected = $this->hexarray2string(array( 0x03b5, 0x03bb, 0x03bb, 0x03b7, 0x03bd, 0x03b9, 0x03ba, 0x03ac )); $result = $this->idn->decode(IDNA_ACE_PREFIX."hxargifdar"); $this->assertSame($expected, $result); } public function testDecode19() { // Maltese (Malti) $expected = $this->hexarray2string(array( 0x0062, 0x006f, 0x006e, 0x0121, 0x0075, 0x0073, 0x0061, 0x0127, 0x0127, 0x0061 )); $result = $this->idn->decode(IDNA_ACE_PREFIX."bonusaa-5bb1da"); $this->assertSame($expected, $result); } public function testDecode20() { // Russian (Cyrillic) $expected = $this->hexarray2string(array( 0x043f, 0x043e, 0x0447, 0x0435, 0x043c, 0x0443, 0x0436, 0x0435, 0x043e, 0x043d, 0x0438, 0x043d, 0x0435, 0x0433, 0x043e, 0x0432, 0x043e, 0x0440, 0x044f, 0x0442, 0x043f, 0x043e, 0x0440, 0x0443, 0x0441, 0x0441, 0x043a, 0x0438 )); $result = $this->idn->decode(IDNA_ACE_PREFIX."b1abfaaepdrnnbgefbadotcwatmq2g4l"); $this->assertSame($expected, $result); } public function testEncode1() { // Arabic (Egyptian) $idna = $this->hexarray2string(array( 0x0644, 0x064A, 0x0647, 0x0645, 0x0627, 0x0628, 0x062A, 0x0643, 0x0644, 0x0645, 0x0648, 0x0634, 0x0639, 0x0631, 0x0628, 0x064A, 0x061F )); $result = $this->idn->encode($idna); $this->assertSame(IDNA_ACE_PREFIX."egbpdaj6bu4bxfgehfvwxn", $result); } public function testEncode2() { // Chinese (simplified) $idna = $this->hexarray2string(array( 0x4ED6, 0x4EEC, 0x4E3A, 0x4EC0, 0x4E48, 0x4E0D, 0x8BF4, 0x4E2D, 0x6587 )); $result = $this->idn->encode($idna); $this->assertSame(IDNA_ACE_PREFIX."ihqwcrb4cv8a8dqg056pqjye", $result); } public function testEncode3() { // Chinese (traditional) $idna = $this->hexarray2string(array( 0x4ED6, 0x5011, 0x7232, 0x4EC0, 0x9EBD, 0x4E0D, 0x8AAA, 0x4E2D, 0x6587 )); $result = $this->idn->encode($idna); $this->assertSame(IDNA_ACE_PREFIX."ihqwctvzc91f659drss3x8bo0yb", $result); } public function testEncode4() { // Czech $idna = $this->hexarray2string(array( 0x0050, 0x0072, 0x006F, 0x010D, 0x0070, 0x0072, 0x006F, 0x0073, 0x0074, 0x011B, 0x006E, 0x0065, 0x006D, 0x006C, 0x0075, 0x0076, 0x00ED, 0x010D, 0x0065, 0x0073, 0x006B, 0x0079 )); $result = $this->idn->encode($idna); $this->assertSame(IDNA_ACE_PREFIX."proprostnemluvesky-uyb24dma41a", $result); } public function testEncode5() { // Hebrew $idna = $this->hexarray2string(array( 0x05DC, 0x05DE, 0x05D4, 0x05D4, 0x05DD, 0x05E4, 0x05E9, 0x05D5, 0x05D8, 0x05DC, 0x05D0, 0x05DE, 0x05D3, 0x05D1, 0x05E8, 0x05D9, 0x05DD, 0x05E2, 0x05D1, 0x05E8, 0x05D9, 0x05EA )); $result = $this->idn->encode($idna); $this->assertSame(IDNA_ACE_PREFIX."4dbcagdahymbxekheh6e0a7fei0b", $result); } public function testEncode6() { // Hindi (Devanagari) $idna = $this->hexarray2string(array( 0x092F, 0x0939, 0x0932, 0x094B, 0x0917, 0x0939, 0x093F, 0x0928, 0x094D, 0x0926, 0x0940, 0x0915, 0x094D, 0x092F, 0x094B, 0x0902, 0x0928, 0x0939, 0x0940, 0x0902, 0x092C, 0x094B, 0x0932, 0x0938, 0x0915, 0x0924, 0x0947, 0x0939, 0x0948, 0x0902 )); $result = $this->idn->encode($idna); $this->assertSame(IDNA_ACE_PREFIX."i1baa7eci9glrd9b2ae1bj0hfcgg6iyaf8o0a1dig0cd", $result); } public function testEncode7() { // Japanese (kanji and hiragana) $idna = $this->hexarray2string(array( 0x306A, 0x305C, 0x307F, 0x3093, 0x306A, 0x65E5, 0x672C, 0x8A9E, 0x3092, 0x8A71, 0x3057, 0x3066, 0x304F, 0x308C, 0x306A, 0x3044, 0x306E, 0x304B )); $result = $this->idn->encode($idna); $this->assertSame(IDNA_ACE_PREFIX."n8jok5ay5dzabd5bym9f0cm5685rrjetr6pdxa", $result); } public function testEncode8() { // Russian (Cyrillic) $idna = $this->hexarray2string(array( 0x043F, 0x043E, 0x0447, 0x0435, 0x043C, 0x0443, 0x0436, 0x0435, 0x043E, 0x043D, 0x0438, 0x043D, 0x0435, 0x0433, 0x043E, 0x0432, 0x043E, 0x0440, 0x044F, 0x0442, 0x043F, 0x043E, 0x0440, 0x0443, 0x0441, 0x0441, 0x043A, 0x0438 )); $result = $this->idn->encode($idna); $this->assertSame(IDNA_ACE_PREFIX."b1abfaaepdrnnbgefbadotcwatmq2g4l", $result); } public function testEncode9() { // Spanish $idna = $this->hexarray2string(array( 0x0050, 0x006F, 0x0072, 0x0071, 0x0075, 0x00E9, 0x006E, 0x006F, 0x0070, 0x0075, 0x0065, 0x0064, 0x0065, 0x006E, 0x0073, 0x0069, 0x006D, 0x0070, 0x006C, 0x0065, 0x006D, 0x0065, 0x006E, 0x0074, 0x0065, 0x0068, 0x0061, 0x0062, 0x006C, 0x0061, 0x0072, 0x0065, 0x006E, 0x0045, 0x0073, 0x0070, 0x0061, 0x00F1, 0x006F, 0x006C )); $result = $this->idn->encode($idna); $this->assertSame(IDNA_ACE_PREFIX."porqunopuedensimplementehablarenespaol-fmd56a", $result); } public function testEncode10() { // Vietnamese $idna = $this->hexarray2string(array( 0x0054, 0x1EA1, 0x0069, 0x0073, 0x0061, 0x006F, 0x0068, 0x1ECD, 0x006B, 0x0068, 0x00F4, 0x006E, 0x0067, 0x0074, 0x0068, 0x1EC3, 0x0063, 0x0068, 0x1EC9, 0x006E, 0x00F3, 0x0069, 0x0074, 0x0069, 0x1EBF, 0x006E, 0x0067, 0x0056, 0x0069, 0x1EC7, 0x0074 )); $result = $this->idn->encode($idna); $this->assertSame(IDNA_ACE_PREFIX."tisaohkhngthchnitingvit-kjcr8268qyxafd2f1b9g", $result); } public function testEncode11() { // Japanese $idna = $this->hexarray2string(array( 0x0033, 0x5E74, 0x0042, 0x7D44, 0x91D1, 0x516B, 0x5148, 0x751F )); $result = $this->idn->encode($idna); $this->assertSame(IDNA_ACE_PREFIX."3b-ww4c5e180e575a65lsy2b", $result); } public function testEncode12() { // Japanese $idna = $this->hexarray2string(array( 0x5B89, 0x5BA4, 0x5948, 0x7F8E, 0x6075, 0x002D, 0x0077, 0x0069, 0x0074, 0x0068, 0x002D, 0x0053, 0x0055, 0x0050, 0x0045, 0x0052, 0x002D, 0x004D, 0x004F, 0x004E, 0x004B, 0x0045, 0x0059, 0x0053 )); $result = $this->idn->encode($idna); $this->assertSame(IDNA_ACE_PREFIX."-with-super-monkeys-pc58ag80a8qai00g7n9n", $result); } public function testEncode13() { // Japanese $idna = $this->hexarray2string(array( 0x0048, 0x0065, 0x006C, 0x006C, 0x006F, 0x002D, 0x0041, 0x006E, 0x006F, 0x0074, 0x0068, 0x0065, 0x0072, 0x002D, 0x0057, 0x0061, 0x0079, 0x002D, 0x305D, 0x308C, 0x305E, 0x308C, 0x306E, 0x5834, 0x6240 )); $result = $this->idn->encode($idna); $this->assertSame(IDNA_ACE_PREFIX."hello-another-way--fc4qua05auwb3674vfr0b", $result); } public function testEncode14() { // Japanese $idna = $this->hexarray2string(array( 0x3072, 0x3068, 0x3064, 0x5C4B, 0x6839, 0x306E, 0x4E0B, 0x0032 )); $result = $this->idn->encode($idna); $this->assertSame(IDNA_ACE_PREFIX."2-u9tlzr9756bt3uc0v", $result); } public function testEncode15() { // Japanese $idna = $this->hexarray2string(array( 0x004D, 0x0061, 0x006A, 0x0069, 0x3067, 0x004B, 0x006F, 0x0069, 0x3059, 0x308B, 0x0035, 0x79D2, 0x524D )); $result = $this->idn->encode($idna); $this->assertSame(IDNA_ACE_PREFIX."majikoi5-783gue6qz075azm5e", $result); } public function testEncode16() { // Japanese $idna = $this->hexarray2string(array( 0x30D1, 0x30D5, 0x30A3, 0x30FC, 0x0064, 0x0065, 0x30EB, 0x30F3, 0x30D0 )); $result = $this->idn->encode($idna); $this->assertSame(IDNA_ACE_PREFIX."de-jg4avhby1noc0d", $result); } public function testEncode17() { // Japanese $idna = $this->hexarray2string(array( 0x305D, 0x306E, 0x30B9, 0x30D4, 0x30FC, 0x30C9, 0x3067 )); $result = $this->idn->encode($idna); $this->assertSame(IDNA_ACE_PREFIX."d9juau41awczczp", $result); } public function testEncode18() { // Greek $idna = $this->hexarray2string(array( 0x03b5, 0x03bb, 0x03bb, 0x03b7, 0x03bd, 0x03b9, 0x03ba, 0x03ac )); $result = $this->idn->encode($idna); $this->assertSame(IDNA_ACE_PREFIX."hxargifdar", $result); } public function testEncode19() { // Maltese (Malti) $idna = $this->hexarray2string(array( 0x0062, 0x006f, 0x006e, 0x0121, 0x0075, 0x0073, 0x0061, 0x0127, 0x0127, 0x0061 )); $result = $this->idn->encode($idna); $this->assertSame(IDNA_ACE_PREFIX."bonusaa-5bb1da", $result); } public function testEncode20() { // Russian (Cyrillic) $idna = $this->hexarray2string(array( 0x043f, 0x043e, 0x0447, 0x0435, 0x043c, 0x0443, 0x0436, 0x0435, 0x043e, 0x043d, 0x0438, 0x043d, 0x0435, 0x0433, 0x043e, 0x0432, 0x043e, 0x0440, 0x044f, 0x0442, 0x043f, 0x043e, 0x0440, 0x0443, 0x0441, 0x0441, 0x043a, 0x0438 )); $result = $this->idn->encode($idna); $this->assertSame(IDNA_ACE_PREFIX."b1abfaaepdrnnbgefbadotcwatmq2g4l", $result); } } PKu]XX test/XML_RPC/tests/test_Dump.phpnu[ * @copyright 2005-2010 The PHP Group * @license http://www.php.net/license/3_01.txt PHP License * @version SVN: $Id: test_Dump.php 300962 2010-07-03 02:24:24Z danielc $ * @link http://pear.php.net/package/XML_RPC */ /* * If the package version number is found in the left hand * portion of the if() expression below, that means this file has * come from the PEAR installer. Therefore, let's test the * installed version of XML_RPC which should be in the include path. * * If the version has not been substituted in the if() expression, * this file has likely come from a SVN checkout or a .tar file. * Therefore, we'll assume the tests should use the version of * XML_RPC that has come from there as well. */ if ('1.5.5' == '@'.'package_version'.'@') { ini_set('include_path', '../' . PATH_SEPARATOR . '.' . PATH_SEPARATOR . ini_get('include_path') ); } require_once 'XML/RPC/Dump.php'; $val = new XML_RPC_Value(array( 'title' =>new XML_RPC_Value('das ist der Titel', 'string'), 'startDate'=>new XML_RPC_Value(mktime(0,0,0,13,11,2004), 'dateTime.iso8601'), 'endDate' =>new XML_RPC_Value(mktime(0,0,0,15,11,2004), 'dateTime.iso8601'), 'arkey' => new XML_RPC_Value( array( new XML_RPC_Value('simple string'), new XML_RPC_Value(12345, 'int') ), 'array') ) ,'struct'); XML_RPC_Dump($val); echo '==============' . "\r\n"; $val2 = new XML_RPC_Value(44353, 'int'); XML_RPC_Dump($val2); echo '==============' . "\r\n"; $val3 = new XML_RPC_Value('this should be a string', 'string'); XML_RPC_Dump($val3); echo '==============' . "\r\n"; $val4 = new XML_RPC_Value(true, 'boolean'); XML_RPC_Dump($val4); echo '==============' . "\r\n"; echo 'Next we will test the error handling...' . "\r\n"; $val5 = new XML_RPC_Value(array( 'foo' => 'bar' ), 'struct'); XML_RPC_Dump($val5); echo '==============' . "\r\n"; echo 'DONE' . "\r\n"; PKu]3l** test/XML_RPC/tests/protoport.phpnu[ * @copyright 2005-2010 The PHP Group * @license http://www.php.net/license/3_01.txt PHP License * @version SVN: $Id: protoport.php 300957 2010-07-02 23:55:00Z danielc $ * @link http://pear.php.net/package/XML_RPC * @since File available since Release 1.2 */ /* * If the package version number is found in the left hand * portion of the if() expression below, that means this file has * come from the PEAR installer. Therefore, let's test the * installed version of XML_RPC which should be in the include path. * * If the version has not been substituted in the if() expression, * this file has likely come from a SVN checkout or a .tar file. * Therefore, we'll assume the tests should use the version of * XML_RPC that has come from there as well. */ if ('1.5.5' == '@'.'package_version'.'@') { ini_set('include_path', '../' . PATH_SEPARATOR . '.' . PATH_SEPARATOR . ini_get('include_path') ); } require_once 'XML/RPC.php'; /** * Compare the test result to the expected result * * If the test fails, echo out the results. * * @param array $expect the array of object properties you expect * from the test * @param object $actual the object results from the test * @param string $test_name the name of the test * * @return void */ function compare($expect, $actual, $test_name) { $actual = get_object_vars($actual); if (count(array_diff($actual, $expect))) { echo "$test_name failed.\nExpect: "; print_r($expect); echo "Actual: "; print_r($actual); echo "\n"; } } if (php_sapi_name() != 'cli') { echo "
\n";
}


$x = array(
    'path' => 'thepath',
    'server' => 'theserver',
    'protocol' => 'http://',
    'port' => 80,
    'proxy' => '',
    'proxy_protocol' => 'http://',
    'proxy_port' => 8080,
    'proxy_user' => '',
    'proxy_pass' => '',
    'errno' => 0,
    'errstring' => '',
    'debug' => 0,
    'username' => '',
    'password' => '',
);
$c = new XML_RPC_Client('thepath', 'theserver');
compare($x, $c, 'defaults');

$x = array(
    'path' => 'thepath',
    'server' => 'theserver',
    'protocol' => 'http://',
    'port' => 80,
    'proxy' => '',
    'proxy_protocol' => 'http://',
    'proxy_port' => 8080,
    'proxy_user' => '',
    'proxy_pass' => '',
    'errno' => 0,
    'errstring' => '',
    'debug' => 0,
    'username' => '',
    'password' => '',
);
$c = new XML_RPC_Client('thepath', 'http://theserver');
compare($x, $c, 'defaults with http');

$x = array(
    'path' => 'thepath',
    'server' => 'theserver',
    'protocol' => 'ssl://',
    'port' => 443,
    'proxy' => '',
    'proxy_protocol' => 'http://',
    'proxy_port' => 8080,
    'proxy_user' => '',
    'proxy_pass' => '',
    'errno' => 0,
    'errstring' => '',
    'debug' => 0,
    'username' => '',
    'password' => '',
);
$c = new XML_RPC_Client('thepath', 'https://theserver');
compare($x, $c, 'defaults with https');

$x = array(
    'path' => 'thepath',
    'server' => 'theserver',
    'protocol' => 'ssl://',
    'port' => 443,
    'proxy' => '',
    'proxy_protocol' => 'http://',
    'proxy_port' => 8080,
    'proxy_user' => '',
    'proxy_pass' => '',
    'errno' => 0,
    'errstring' => '',
    'debug' => 0,
    'username' => '',
    'password' => '',
);
$c = new XML_RPC_Client('thepath', 'ssl://theserver');
compare($x, $c, 'defaults with ssl');


$x = array(
    'path' => 'thepath',
    'server' => 'theserver',
    'protocol' => 'http://',
    'port' => 65,
    'proxy' => '',
    'proxy_protocol' => 'http://',
    'proxy_port' => 8080,
    'proxy_user' => '',
    'proxy_pass' => '',
    'errno' => 0,
    'errstring' => '',
    'debug' => 0,
    'username' => '',
    'password' => '',
);
$c = new XML_RPC_Client('thepath', 'theserver', 65);
compare($x, $c, 'port 65');

$x = array(
    'path' => 'thepath',
    'server' => 'theserver',
    'protocol' => 'http://',
    'port' => 65,
    'proxy' => '',
    'proxy_protocol' => 'http://',
    'proxy_port' => 8080,
    'proxy_user' => '',
    'proxy_pass' => '',
    'errno' => 0,
    'errstring' => '',
    'debug' => 0,
    'username' => '',
    'password' => '',
);
$c = new XML_RPC_Client('thepath', 'http://theserver', 65);
compare($x, $c, 'port 65 with http');

$x = array(
    'path' => 'thepath',
    'server' => 'theserver',
    'protocol' => 'ssl://',
    'port' => 65,
    'proxy' => '',
    'proxy_protocol' => 'http://',
    'proxy_port' => 8080,
    'proxy_user' => '',
    'proxy_pass' => '',
    'errno' => 0,
    'errstring' => '',
    'debug' => 0,
    'username' => '',
    'password' => '',
);
$c = new XML_RPC_Client('thepath', 'https://theserver', 65);
compare($x, $c, 'port 65 with https');

$x = array(
    'path' => 'thepath',
    'server' => 'theserver',
    'protocol' => 'ssl://',
    'port' => 65,
    'proxy' => '',
    'proxy_protocol' => 'http://',
    'proxy_port' => 8080,
    'proxy_user' => '',
    'proxy_pass' => '',
    'errno' => 0,
    'errstring' => '',
    'debug' => 0,
    'username' => '',
    'password' => '',
);
$c = new XML_RPC_Client('thepath', 'ssl://theserver', 65);
compare($x, $c, 'port 65 with ssl');


$x = array(
    'path' => 'thepath',
    'server' => 'theserver',
    'protocol' => 'http://',
    'port' => 80,
    'proxy' => 'theproxy',
    'proxy_protocol' => 'http://',
    'proxy_port' => 8080,
    'proxy_user' => '',
    'proxy_pass' => '',
    'errno' => 0,
    'errstring' => '',
    'debug' => 0,
    'username' => '',
    'password' => '',
);
$c = new XML_RPC_Client('thepath', 'theserver', 0,
                        'theproxy');
compare($x, $c, 'defaults proxy');

$x = array(
    'path' => 'thepath',
    'server' => 'theserver',
    'protocol' => 'http://',
    'port' => 80,
    'proxy' => 'theproxy',
    'proxy_protocol' => 'http://',
    'proxy_port' => 8080,
    'proxy_user' => '',
    'proxy_pass' => '',
    'errno' => 0,
    'errstring' => '',
    'debug' => 0,
    'username' => '',
    'password' => '',
);
$c = new XML_RPC_Client('thepath', 'http://theserver', 0,
                        'http://theproxy');
compare($x, $c, 'defaults with http proxy');

$x = array(
    'path' => 'thepath',
    'server' => 'theserver',
    'protocol' => 'ssl://',
    'port' => 443,
    'proxy' => 'theproxy',
    'proxy_protocol' => 'ssl://',
    'proxy_port' => 443,
    'proxy_user' => '',
    'proxy_pass' => '',
    'errno' => 0,
    'errstring' => '',
    'debug' => 0,
    'username' => '',
    'password' => '',
);
$c = new XML_RPC_Client('thepath', 'https://theserver', 0,
                        'https://theproxy');
compare($x, $c, 'defaults with https proxy');

$x = array(
    'path' => 'thepath',
    'server' => 'theserver',
    'protocol' => 'ssl://',
    'port' => 443,
    'proxy' => 'theproxy',
    'proxy_protocol' => 'ssl://',
    'proxy_port' => 443,
    'proxy_user' => '',
    'proxy_pass' => '',
    'errno' => 0,
    'errstring' => '',
    'debug' => 0,
    'username' => '',
    'password' => '',
);
$c = new XML_RPC_Client('thepath', 'ssl://theserver', 0,
                        'ssl://theproxy');
compare($x, $c, 'defaults with ssl proxy');


$x = array(
    'path' => 'thepath',
    'server' => 'theserver',
    'protocol' => 'http://',
    'port' => 65,
    'proxy' => 'theproxy',
    'proxy_protocol' => 'http://',
    'proxy_port' => 6565,
    'proxy_user' => '',
    'proxy_pass' => '',
    'errno' => 0,
    'errstring' => '',
    'debug' => 0,
    'username' => '',
    'password' => '',
);
$c = new XML_RPC_Client('thepath', 'theserver', 65,
                        'theproxy', 6565);
compare($x, $c, 'port 65 proxy 6565');

$x = array(
    'path' => 'thepath',
    'server' => 'theserver',
    'protocol' => 'http://',
    'port' => 65,
    'proxy' => 'theproxy',
    'proxy_protocol' => 'http://',
    'proxy_port' => 6565,
    'proxy_user' => '',
    'proxy_pass' => '',
    'errno' => 0,
    'errstring' => '',
    'debug' => 0,
    'username' => '',
    'password' => '',
);
$c = new XML_RPC_Client('thepath', 'http://theserver', 65,
                        'http://theproxy', 6565);
compare($x, $c, 'port 65 with http proxy 6565');

$x = array(
    'path' => 'thepath',
    'server' => 'theserver',
    'protocol' => 'ssl://',
    'port' => 65,
    'proxy' => 'theproxy',
    'proxy_protocol' => 'ssl://',
    'proxy_port' => 6565,
    'proxy_user' => '',
    'proxy_pass' => '',
    'errno' => 0,
    'errstring' => '',
    'debug' => 0,
    'username' => '',
    'password' => '',
);
$c = new XML_RPC_Client('thepath', 'https://theserver', 65,
                        'https://theproxy', 6565);
compare($x, $c, 'port 65 with https proxy 6565');

$x = array(
    'path' => 'thepath',
    'server' => 'theserver',
    'protocol' => 'ssl://',
    'port' => 65,
    'proxy' => 'theproxy',
    'proxy_protocol' => 'ssl://',
    'proxy_port' => 6565,
    'proxy_user' => '',
    'proxy_pass' => '',
    'errno' => 0,
    'errstring' => '',
    'debug' => 0,
    'username' => '',
    'password' => '',
);
$c = new XML_RPC_Client('thepath', 'ssl://theserver', 65,
                        'ssl://theproxy', 6565);
compare($x, $c, 'port 65 with ssl proxy 6565');


$x = array(
    'path' => 'thepath',
    'server' => 'theserver',
    'protocol' => 'ssl://',
    'port' => 443,
    'proxy' => 'theproxy',
    'proxy_protocol' => 'ssl://',
    'proxy_port' => 443,
    'proxy_user' => '',
    'proxy_pass' => '',
    'errno' => 0,
    'errstring' => '',
    'debug' => 0,
    'username' => '',
    'password' => '',
);
$c = new XML_RPC_Client('thepath', 'theserver', 443,
                        'theproxy', 443);
compare($x, $c, 'port 443 no protocol and proxy port 443 no protocol');

$x = array(
    'path' => 'thepath',
    'server' => 'theserver',
    'protocol' => 'http://',
    'port' => 80,
    'proxy' => 'theproxy',
    'proxy_protocol' => 'ssl://',
    'proxy_port' => 6565,
    'proxy_user' => '',
    'proxy_pass' => '',
    'errno' => 0,
    'errstring' => '',
    'debug' => 0,
    'username' => '',
    'password' => '',
);
$c = new XML_RPC_Client('thepath', 'theserver', 0,
                        'ssl://theproxy', 6565);
compare($x, $c, 'port 443 no protocol and proxy port 443 no protocol');

echo "\nIf no other output was produced, these tests passed.\n";
PKu]|E)test/XML_RPC/tests/empty-value-struct.phpnu[
 * @copyright  2005-2010 The PHP Group
 * @license    http://www.php.net/license/3_01.txt  PHP License
 * @version    SVN: $Id: empty-value-struct.php 300957 2010-07-02 23:55:00Z danielc $
 * @link       http://pear.php.net/package/XML_RPC
 * @since      File available since Release 1.4.4
 */

/*
 * If the package version number is found in the left hand
 * portion of the if() expression below, that means this file has
 * come from the PEAR installer.  Therefore, let's test the
 * installed version of XML_RPC which should be in the include path.
 *
 * If the version has not been substituted in the if() expression,
 * this file has likely come from a SVN checkout or a .tar file.
 * Therefore, we'll assume the tests should use the version of
 * XML_RPC that has come from there as well.
 */
if ('1.5.5' == '@'.'package_version'.'@') {
    ini_set('include_path', '../'
            . PATH_SEPARATOR . '.' . PATH_SEPARATOR
            . ini_get('include_path')
    );
}
require_once 'XML/RPC/Server.php';


$GLOBALS['HTTP_RAW_POST_DATA'] = <<

 allgot
  
   
    
     
      
      fld1
   
  
 
EOPOST;

$expect = <<



param 0: array (
  'fld1' => '',
)




EOEXP;

include './allgot.inc';
PKu]̢		test/XML_RPC/tests/types.phpnu[
 * @copyright  2005-2010 The PHP Group
 * @license    http://www.php.net/license/3_01.txt  PHP License
 * @version    SVN: $Id: types.php 300957 2010-07-02 23:55:00Z danielc $
 * @link       http://pear.php.net/package/XML_RPC
 * @since      File available since Release 1.4.4
 */

/*
 * If the package version number is found in the left hand
 * portion of the if() expression below, that means this file has
 * come from the PEAR installer.  Therefore, let's test the
 * installed version of XML_RPC which should be in the include path.
 *
 * If the version has not been substituted in the if() expression,
 * this file has likely come from a SVN checkout or a .tar file.
 * Therefore, we'll assume the tests should use the version of
 * XML_RPC that has come from there as well.
 */
if ('1.5.5' == '@'.'package_version'.'@') {
    ini_set('include_path', '../'
            . PATH_SEPARATOR . '.' . PATH_SEPARATOR
            . ini_get('include_path')
    );
}
require_once 'XML/RPC/Server.php';


$GLOBALS['HTTP_RAW_POST_DATA'] = <<

 allgot
  
   default to string
   inside string
   8
   20050809T01:33:44

   
    
     
      
       
        a
       
       
        b
       
      
     
    
   

   
    
     
      
       a
       
        ay
       
      
      
       b
       
        be
       
      
     
    
   

  
 
EOPOST;

$expect = <<



param 0: 'default to string'
param 1: 'inside string'
param 2: '8'
param 3: '20050809T01:33:44'
param 4: array (
  0 => 'a',
  1 => 'b',
)
param 5: array (
  'a' => 'ay',
  'b' => 'be',
)




EOEXP;

include './allgot.inc';
PKu]Jtest/XML_RPC/tests/encode.phpnu[
 * @copyright  2005-2010 The PHP Group
 * @license    http://www.php.net/license/3_01.txt  PHP License
 * @version    SVN: $Id: extra-lines.php 293218 2010-01-07 14:20:08Z danielc $
 * @link       http://pear.php.net/package/XML_RPC
 * @since      File available since Release 1.5.3
 */

/*
 * If the package version number is found in the left hand
 * portion of the if() expression below, that means this file has
 * come from the PEAR installer.  Therefore, let's test the
 * installed version of XML_RPC which should be in the include path.
 *
 * If the version has not been substituted in the if() expression,
 * this file has likely come from a SVN checkout or a .tar file.
 * Therefore, we'll assume the tests should use the version of
 * XML_RPC that has come from there as well.
 */
if ('1.5.5' == '@'.'package_version'.'@') {
    ini_set('include_path', '../'
            . PATH_SEPARATOR . '.' . PATH_SEPARATOR
            . ini_get('include_path')
    );
}
require_once 'XML/RPC.php';


$input = array(10, 11, 12);

$expect = <<

nada




10
11
12





EOT;

$expect = trim(preg_replace("/\r\n/", "\n", $expect));

$msg = new XML_RPC_Message('nada', array(XML_RPC_encode($input)));
$msg->createPayload();
$actual = trim(preg_replace("/\r\n/", "\n", $msg->payload));
if ($actual == $expect) {
    echo "passed\n";
} else {
    echo "PROBLEM\n";
    echo $actual;
}

$msg = new XML_RPC_Message('nada',
    array(
        new XML_RPC_Value(
            array(
                new XML_RPC_Value(10, 'int'),
                new XML_RPC_Value(11, 'int'),
                new XML_RPC_Value(12, 'int'),
            ),
            'array'
        )
    )
);
$msg->createPayload();
$actual = trim(preg_replace("/\r\n/", "\n", $msg->payload));
if ($actual == $expect) {
    echo "passed\n";
} else {
    echo "PROBLEM\n";
    echo $actual;
}
PKu].
"test/XML_RPC/tests/extra-lines.phpnu[
 * @copyright  2005-2010 The PHP Group
 * @license    http://www.php.net/license/3_01.txt  PHP License
 * @version    SVN: $Id: extra-lines.php 300958 2010-07-02 23:58:51Z danielc $
 * @link       http://pear.php.net/package/XML_RPC
 * @since      File available since Release 1.4.4
 */

/*
 * If the package version number is found in the left hand
 * portion of the if() expression below, that means this file has
 * come from the PEAR installer.  Therefore, let's test the
 * installed version of XML_RPC which should be in the include path.
 *
 * If the version has not been substituted in the if() expression,
 * this file has likely come from a SVN checkout or a .tar file.
 * Therefore, we'll assume the tests should use the version of
 * XML_RPC that has come from there as well.
 */
if ('1.5.5' == '@'.'package_version'.'@') {
    ini_set('include_path', '../'
            . PATH_SEPARATOR . '.' . PATH_SEPARATOR
            . ini_get('include_path')
    );
}
require_once 'XML/RPC.php';


$input = "First lfs\n\nSecond crlfs\r\n\r\nThird crs\r\rFourth line";

$expect_removed = "\r\n\r\nnada\r\n\r\n\r\nFirst lfs\r\nSecond crlfs\r\nThird crs\r\nFourth line\r\n\r\n\r\n\r\n";

$expect_not_removed = "\r\n\r\nnada\r\n\r\n\r\nFirst lfs\r\n\r\nSecond crlfs\r\n\r\nThird crs\r\n\r\nFourth line\r\n\r\n\r\n\r\n";

$msg = new XML_RPC_Message('nada', array(XML_RPC_encode($input)));
$msg->createPayload();
if ($msg->payload == $expect_removed) {
    echo "passed\n";
} else {
    echo "PROBLEM\n";
}

$msg = new XML_RPC_Message('nada', array(XML_RPC_encode($input)));
$msg->remove_extra_lines = false;
$msg->createPayload();
if ($msg->payload == $expect_not_removed) {
    echo "passed\n";
} else {
    echo "PROBLEM\n";
}
PKu]$]"test/XML_RPC/tests/empty-value.phpnu[
 * @copyright  2005-2010 The PHP Group
 * @license    http://www.php.net/license/3_01.txt  PHP License
 * @version    SVN: $Id: empty-value.php 300957 2010-07-02 23:55:00Z danielc $
 * @link       http://pear.php.net/package/XML_RPC
 * @since      File available since Release 1.4.4
 */

/*
 * If the package version number is found in the left hand
 * portion of the if() expression below, that means this file has
 * come from the PEAR installer.  Therefore, let's test the
 * installed version of XML_RPC which should be in the include path.
 *
 * If the version has not been substituted in the if() expression,
 * this file has likely come from a SVN checkout or a .tar file.
 * Therefore, we'll assume the tests should use the version of
 * XML_RPC that has come from there as well.
 */
if ('1.5.5' == '@'.'package_version'.'@') {
    ini_set('include_path', '../'
            . PATH_SEPARATOR . '.' . PATH_SEPARATOR
            . ini_get('include_path')
    );
}
require_once 'XML/RPC/Server.php';


$GLOBALS['HTTP_RAW_POST_DATA'] = <<

 allgot
  
   
   first
     
   
  
 
EOPOST;

$expect = <<



param 0: ''
param 1: 'first'
param 2: '  '
param 3: ''




EOEXP;

include './allgot.inc';
PKu]Btest/XML_RPC/tests/allgot.incnu[
 * @copyright  2005-2010 The PHP Group
 * @license    http://www.php.net/license/3_01.txt  PHP License
 * @version    SVN: $Id: allgot.inc 293223 2010-01-07 15:32:19Z danielc $
 * @link       http://pear.php.net/package/XML_RPC
 * @since      File available since Release 1.4.4
 */

ob_start();

function returnAllGot($params) {
    $out = '';
    $count = count($params->params);
    for ($i = 0; $i < $count; $i++) {
        $param = $params->getParam($i);
        if (!XML_RPC_Value::isValue($param)) {
            $out .= "parameter $i was error: $param\n";
            continue;
        }
        $got = XML_RPC_Decode($param);
        $out .= "param $i: " . var_export($got, true) . "\n";
    }
    $val = new XML_RPC_Value($out, 'string');
    return new XML_RPC_Response($val);
}

$server = new XML_RPC_Server(
    array(
        'allgot' => array(
            'function' => 'returnAllGot',
        ),
    )
);

$got = ob_get_clean();

if ($got == $expect) {
    echo "passed\n";
} else {
    echo "FAILED\n";
    echo "Expected:\n$expect\n";
    echo "Got:\n$got\n";
}
PKu]b)))%test/XML_RPC/tests/actual-request.phpnu[
 * @copyright  2005-2010 The PHP Group
 * @license    http://www.php.net/license/3_01.txt  PHP License
 * @version    SVN: $Id: actual-request.php 300957 2010-07-02 23:55:00Z danielc $
 * @link       http://pear.php.net/package/XML_RPC
 * @since      File available since Release 1.5.3
 */

/*
 * If the package version number is found in the left hand
 * portion of the if() expression below, that means this file has
 * come from the PEAR installer.  Therefore, let's test the
 * installed version of XML_RPC which should be in the include path.
 *
 * If the version has not been substituted in the if() expression,
 * this file has likely come from a SVN checkout or a .tar file.
 * Therefore, we'll assume the tests should use the version of
 * XML_RPC that has come from there as well.
 */
if ('1.5.5' == '@'.'package_version'.'@') {
    ini_set('include_path', '../'
            . PATH_SEPARATOR . '.' . PATH_SEPARATOR
            . ini_get('include_path')
    );
}
require_once 'XML/RPC/Dump.php';


$debug = 0;

$params = array(
    new XML_RPC_Value('php.net', 'string'),
);
$msg = new XML_RPC_Message('domquery', $params);
$client = new XML_RPC_Client('/api/xmlrpc', 'www.adamsnames.com');
$client->setDebug($debug);

$resp = $client->send($msg);
if (!$resp) {
    echo 'Communication error: ' . $client->errstr;
    exit(1);
}
if ($resp->faultCode()) {
    /*
     * Display problems that have been gracefully cought and
     * reported by the xmlrpc.php script
     */
    echo 'Fault Code: ' . $resp->faultCode() . "\n";
    echo 'Fault Reason: ' . $resp->faultString() . "\n";
    exit(1);
}

$val = $resp->value();
XML_RPC_Dump($val);
PKu]$test/Net_Sieve/tests/largescript.sivnu[require ["fileinto", "reject", "vacation", "regex", "relational", "comparator-i;ascii-numeric"];
if header :is ["X-Spam-Flag", "X-Spam-Status"] ["YES","Yes"] {
fileinto "INBOX.Spam";
stop;
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["cvs-all.freebsd.org"] {
fileinto "INBOX.FreeBSD.CVS All";
}
if header :contains ["List-Id"] ["freebsd-acpi.freebsd.org"] {
fileinto "INBOX.FreeBSD.ACPI";
}
if header :contains ["List-Id"] ["freebsd-current.freebsd.org"] {
fileinto "INBOX.FreeBSD.Current";
}
if header :contains ["List-Id"] ["freebsd-hackers.freebsd.org"] {
fileinto "INBOX.FreeBSD.Hackers";
}
if header :contains ["List-Id"] ["freebsd-multimedia.freebsd.org"] {
fileinto "INBOX.FreeBSD.Multimedia";
}
if header :contains ["List-Id"] ["freebsd-questions.freebsd.org"] {
fileinto "INBOX.FreeBSD.Questions";
}
if header :contains ["List-Id"] ["freebsd-stable.freebsd.org"] {
fileinto "INBOX.FreeBSD.Stable";
}
if header :contains ["List-Id"] ["freebsd-mobile.freebsd.org"] {
fileinto "INBOX.FreeBSD.Mobile";
}
if header :contains ["List-Id"] ["wine-devel.winehq.org"] {
fileinto "INBOX.FreeBSD.Wine.Devel";
}
if header :contains ["List-Id"] ["wine-users.winehq.org"] {
fileinto "INBOX.FreeBSD.Wine.Users";
}
if header :contains ["List-Id"] ["dri-devel.lists.sourceforge.net"] {
fileinto "INBOX.FreeBSD.dri-devel";
}
if header :contains ["List-Id"] ["freebsd-threads.freebsd.org"] {
fileinto "INBOX.FreeBSD.Threads";
}
if header :contains ["List-Id"] ["freebsd-hardware.freebsd.org"] {
fileinto "INBOX.FreeBSD.Hardware";
}
if header :contains ["List-Id"] ["freebsd-usb.freebsd.org"] {
fileinto "INBOX.FreeBSD.USB";
}
if header :contains ["List-Id"] ["freebsd-ports.freebsd.org"] {
fileinto "INBOX.FreeBSD.Ports";
}
if header :contains ["To"] ["amistry@php.net"] {
fileinto "INBOX.PEAR.Account";
}
if header :contains ["list-post"] ["pear-qa@lists.php.net"] {
fileinto "INBOX.PEAR.QA";
}
if header :contains ["Delivered-To"] ["php-general@lists.php.net"] {
fileinto "INBOX.PHP.General";
}
if header :contains ["Delivered-to"] ["internals@lists.php.net"] {
fileinto "INBOX.PEAR.Internals";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["cvs-all.freebsd.org"] {
fileinto "INBOX.FreeBSD.CVS All";
}
if header :contains ["List-Id"] ["freebsd-acpi.freebsd.org"] {
fileinto "INBOX.FreeBSD.ACPI";
}
if header :contains ["List-Id"] ["freebsd-current.freebsd.org"] {
fileinto "INBOX.FreeBSD.Current";
}
if header :contains ["List-Id"] ["freebsd-hackers.freebsd.org"] {
fileinto "INBOX.FreeBSD.Hackers";
}
if header :contains ["List-Id"] ["freebsd-multimedia.freebsd.org"] {
fileinto "INBOX.FreeBSD.Multimedia";
}
if header :contains ["List-Id"] ["freebsd-questions.freebsd.org"] {
fileinto "INBOX.FreeBSD.Questions";
}
if header :contains ["List-Id"] ["freebsd-stable.freebsd.org"] {
fileinto "INBOX.FreeBSD.Stable";
}
if header :contains ["List-Id"] ["freebsd-mobile.freebsd.org"] {
fileinto "INBOX.FreeBSD.Mobile";
}
if header :contains ["List-Id"] ["wine-devel.winehq.org"] {
fileinto "INBOX.FreeBSD.Wine.Devel";
}
if header :contains ["List-Id"] ["wine-users.winehq.org"] {
fileinto "INBOX.FreeBSD.Wine.Users";
}
if header :contains ["List-Id"] ["dri-devel.lists.sourceforge.net"] {
fileinto "INBOX.FreeBSD.dri-devel";
}
if header :contains ["List-Id"] ["freebsd-threads.freebsd.org"] {
fileinto "INBOX.FreeBSD.Threads";
}
if header :contains ["List-Id"] ["freebsd-hardware.freebsd.org"] {
fileinto "INBOX.FreeBSD.Hardware";
}
if header :contains ["List-Id"] ["freebsd-usb.freebsd.org"] {
fileinto "INBOX.FreeBSD.USB";
}
if header :contains ["List-Id"] ["freebsd-ports.freebsd.org"] {
fileinto "INBOX.FreeBSD.Ports";
}
if header :contains ["To"] ["amistry@php.net"] {
fileinto "INBOX.PEAR.Account";
}
if header :contains ["list-post"] ["pear-qa@lists.php.net"] {
fileinto "INBOX.PEAR.QA";
}
if header :contains ["Delivered-To"] ["php-general@lists.php.net"] {
fileinto "INBOX.PHP.General";
}
if header :contains ["Delivered-to"] ["internals@lists.php.net"] {
fileinto "INBOX.PEAR.Internals";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["cvs-all.freebsd.org"] {
fileinto "INBOX.FreeBSD.CVS All";
}
if header :contains ["List-Id"] ["freebsd-acpi.freebsd.org"] {
fileinto "INBOX.FreeBSD.ACPI";
}
if header :contains ["List-Id"] ["freebsd-current.freebsd.org"] {
fileinto "INBOX.FreeBSD.Current";
}
if header :contains ["List-Id"] ["freebsd-hackers.freebsd.org"] {
fileinto "INBOX.FreeBSD.Hackers";
}
if header :contains ["List-Id"] ["freebsd-multimedia.freebsd.org"] {
fileinto "INBOX.FreeBSD.Multimedia";
}
if header :contains ["List-Id"] ["freebsd-questions.freebsd.org"] {
fileinto "INBOX.FreeBSD.Questions";
}
if header :contains ["List-Id"] ["freebsd-stable.freebsd.org"] {
fileinto "INBOX.FreeBSD.Stable";
}
if header :contains ["List-Id"] ["freebsd-mobile.freebsd.org"] {
fileinto "INBOX.FreeBSD.Mobile";
}
if header :contains ["List-Id"] ["wine-devel.winehq.org"] {
fileinto "INBOX.FreeBSD.Wine.Devel";
}
if header :contains ["List-Id"] ["wine-users.winehq.org"] {
fileinto "INBOX.FreeBSD.Wine.Users";
}
if header :contains ["List-Id"] ["dri-devel.lists.sourceforge.net"] {
fileinto "INBOX.FreeBSD.dri-devel";
}
if header :contains ["List-Id"] ["freebsd-threads.freebsd.org"] {
fileinto "INBOX.FreeBSD.Threads";
}
if header :contains ["List-Id"] ["freebsd-hardware.freebsd.org"] {
fileinto "INBOX.FreeBSD.Hardware";
}
if header :contains ["List-Id"] ["freebsd-usb.freebsd.org"] {
fileinto "INBOX.FreeBSD.USB";
}
if header :contains ["List-Id"] ["freebsd-ports.freebsd.org"] {
fileinto "INBOX.FreeBSD.Ports";
}
if header :contains ["To"] ["amistry@php.net"] {
fileinto "INBOX.PEAR.Account";
}
if header :contains ["list-post"] ["pear-qa@lists.php.net"] {
fileinto "INBOX.PEAR.QA";
}
if header :contains ["Delivered-To"] ["php-general@lists.php.net"] {
fileinto "INBOX.PHP.General";
}
if header :contains ["Delivered-to"] ["internals@lists.php.net"] {
fileinto "INBOX.PEAR.Internals";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["cvs-all.freebsd.org"] {
fileinto "INBOX.FreeBSD.CVS All";
}
if header :contains ["List-Id"] ["freebsd-acpi.freebsd.org"] {
fileinto "INBOX.FreeBSD.ACPI";
}
if header :contains ["List-Id"] ["freebsd-current.freebsd.org"] {
fileinto "INBOX.FreeBSD.Current";
}
if header :contains ["List-Id"] ["freebsd-hackers.freebsd.org"] {
fileinto "INBOX.FreeBSD.Hackers";
}
if header :contains ["List-Id"] ["freebsd-multimedia.freebsd.org"] {
fileinto "INBOX.FreeBSD.Multimedia";
}
if header :contains ["List-Id"] ["freebsd-questions.freebsd.org"] {
fileinto "INBOX.FreeBSD.Questions";
}
if header :contains ["List-Id"] ["freebsd-stable.freebsd.org"] {
fileinto "INBOX.FreeBSD.Stable";
}
if header :contains ["List-Id"] ["freebsd-mobile.freebsd.org"] {
fileinto "INBOX.FreeBSD.Mobile";
}
if header :contains ["List-Id"] ["wine-devel.winehq.org"] {
fileinto "INBOX.FreeBSD.Wine.Devel";
}
if header :contains ["List-Id"] ["wine-users.winehq.org"] {
fileinto "INBOX.FreeBSD.Wine.Users";
}
if header :contains ["List-Id"] ["dri-devel.lists.sourceforge.net"] {
fileinto "INBOX.FreeBSD.dri-devel";
}
if header :contains ["List-Id"] ["freebsd-threads.freebsd.org"] {
fileinto "INBOX.FreeBSD.Threads";
}
if header :contains ["List-Id"] ["freebsd-hardware.freebsd.org"] {
fileinto "INBOX.FreeBSD.Hardware";
}
if header :contains ["List-Id"] ["freebsd-usb.freebsd.org"] {
fileinto "INBOX.FreeBSD.USB";
}
if header :contains ["List-Id"] ["freebsd-ports.freebsd.org"] {
fileinto "INBOX.FreeBSD.Ports";
}
if header :contains ["To"] ["amistry@php.net"] {
fileinto "INBOX.PEAR.Account";
}
if header :contains ["list-post"] ["pear-qa@lists.php.net"] {
fileinto "INBOX.PEAR.QA";
}
if header :contains ["Delivered-To"] ["php-general@lists.php.net"] {
fileinto "INBOX.PHP.General";
}
if header :contains ["Delivered-to"] ["internals@lists.php.net"] {
fileinto "INBOX.PEAR.Internals";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["cvs-all.freebsd.org"] {
fileinto "INBOX.FreeBSD.CVS All";
}
if header :contains ["List-Id"] ["freebsd-acpi.freebsd.org"] {
fileinto "INBOX.FreeBSD.ACPI";
}
if header :contains ["List-Id"] ["freebsd-current.freebsd.org"] {
fileinto "INBOX.FreeBSD.Current";
}
if header :contains ["List-Id"] ["freebsd-hackers.freebsd.org"] {
fileinto "INBOX.FreeBSD.Hackers";
}
if header :contains ["List-Id"] ["freebsd-multimedia.freebsd.org"] {
fileinto "INBOX.FreeBSD.Multimedia";
}
if header :contains ["List-Id"] ["freebsd-questions.freebsd.org"] {
fileinto "INBOX.FreeBSD.Questions";
}
if header :contains ["List-Id"] ["freebsd-stable.freebsd.org"] {
fileinto "INBOX.FreeBSD.Stable";
}
if header :contains ["List-Id"] ["freebsd-mobile.freebsd.org"] {
fileinto "INBOX.FreeBSD.Mobile";
}
if header :contains ["List-Id"] ["wine-devel.winehq.org"] {
fileinto "INBOX.FreeBSD.Wine.Devel";
}
if header :contains ["List-Id"] ["wine-users.winehq.org"] {
fileinto "INBOX.FreeBSD.Wine.Users";
}
if header :contains ["List-Id"] ["dri-devel.lists.sourceforge.net"] {
fileinto "INBOX.FreeBSD.dri-devel";
}
if header :contains ["List-Id"] ["freebsd-threads.freebsd.org"] {
fileinto "INBOX.FreeBSD.Threads";
}
if header :contains ["List-Id"] ["freebsd-hardware.freebsd.org"] {
fileinto "INBOX.FreeBSD.Hardware";
}
if header :contains ["List-Id"] ["freebsd-usb.freebsd.org"] {
fileinto "INBOX.FreeBSD.USB";
}
if header :contains ["List-Id"] ["freebsd-ports.freebsd.org"] {
fileinto "INBOX.FreeBSD.Ports";
}
if header :contains ["To"] ["amistry@php.net"] {
fileinto "INBOX.PEAR.Account";
}
if header :contains ["list-post"] ["pear-qa@lists.php.net"] {
fileinto "INBOX.PEAR.QA";
}
if header :contains ["Delivered-To"] ["php-general@lists.php.net"] {
fileinto "INBOX.PHP.General";
}
if header :contains ["Delivered-to"] ["internals@lists.php.net"] {
fileinto "INBOX.PEAR.Internals";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["cvs-all.freebsd.org"] {
fileinto "INBOX.FreeBSD.CVS All";
}
if header :contains ["List-Id"] ["freebsd-acpi.freebsd.org"] {
fileinto "INBOX.FreeBSD.ACPI";
}
if header :contains ["List-Id"] ["freebsd-current.freebsd.org"] {
fileinto "INBOX.FreeBSD.Current";
}
if header :contains ["List-Id"] ["freebsd-hackers.freebsd.org"] {
fileinto "INBOX.FreeBSD.Hackers";
}
if header :contains ["List-Id"] ["freebsd-multimedia.freebsd.org"] {
fileinto "INBOX.FreeBSD.Multimedia";
}
if header :contains ["List-Id"] ["freebsd-questions.freebsd.org"] {
fileinto "INBOX.FreeBSD.Questions";
}
if header :contains ["List-Id"] ["freebsd-stable.freebsd.org"] {
fileinto "INBOX.FreeBSD.Stable";
}
if header :contains ["List-Id"] ["freebsd-mobile.freebsd.org"] {
fileinto "INBOX.FreeBSD.Mobile";
}
if header :contains ["List-Id"] ["wine-devel.winehq.org"] {
fileinto "INBOX.FreeBSD.Wine.Devel";
}
if header :contains ["List-Id"] ["wine-users.winehq.org"] {
fileinto "INBOX.FreeBSD.Wine.Users";
}
if header :contains ["List-Id"] ["dri-devel.lists.sourceforge.net"] {
fileinto "INBOX.FreeBSD.dri-devel";
}
if header :contains ["List-Id"] ["freebsd-threads.freebsd.org"] {
fileinto "INBOX.FreeBSD.Threads";
}
if header :contains ["List-Id"] ["freebsd-hardware.freebsd.org"] {
fileinto "INBOX.FreeBSD.Hardware";
}
if header :contains ["List-Id"] ["freebsd-usb.freebsd.org"] {
fileinto "INBOX.FreeBSD.USB";
}
if header :contains ["List-Id"] ["freebsd-ports.freebsd.org"] {
fileinto "INBOX.FreeBSD.Ports";
}
if header :contains ["To"] ["amistry@php.net"] {
fileinto "INBOX.PEAR.Account";
}
if header :contains ["list-post"] ["pear-qa@lists.php.net"] {
fileinto "INBOX.PEAR.QA";
}
if header :contains ["Delivered-To"] ["php-general@lists.php.net"] {
fileinto "INBOX.PHP.General";
}
if header :contains ["Delivered-to"] ["internals@lists.php.net"] {
fileinto "INBOX.PEAR.Internals";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["cvs-all.freebsd.org"] {
fileinto "INBOX.FreeBSD.CVS All";
}
if header :contains ["List-Id"] ["freebsd-acpi.freebsd.org"] {
fileinto "INBOX.FreeBSD.ACPI";
}
if header :contains ["List-Id"] ["freebsd-current.freebsd.org"] {
fileinto "INBOX.FreeBSD.Current";
}
if header :contains ["List-Id"] ["freebsd-hackers.freebsd.org"] {
fileinto "INBOX.FreeBSD.Hackers";
}
if header :contains ["List-Id"] ["freebsd-multimedia.freebsd.org"] {
fileinto "INBOX.FreeBSD.Multimedia";
}
if header :contains ["List-Id"] ["freebsd-questions.freebsd.org"] {
fileinto "INBOX.FreeBSD.Questions";
}
if header :contains ["List-Id"] ["freebsd-stable.freebsd.org"] {
fileinto "INBOX.FreeBSD.Stable";
}
if header :contains ["List-Id"] ["freebsd-mobile.freebsd.org"] {
fileinto "INBOX.FreeBSD.Mobile";
}
if header :contains ["List-Id"] ["wine-devel.winehq.org"] {
fileinto "INBOX.FreeBSD.Wine.Devel";
}
if header :contains ["List-Id"] ["wine-users.winehq.org"] {
fileinto "INBOX.FreeBSD.Wine.Users";
}
if header :contains ["List-Id"] ["dri-devel.lists.sourceforge.net"] {
fileinto "INBOX.FreeBSD.dri-devel";
}
if header :contains ["List-Id"] ["freebsd-threads.freebsd.org"] {
fileinto "INBOX.FreeBSD.Threads";
}
if header :contains ["List-Id"] ["freebsd-hardware.freebsd.org"] {
fileinto "INBOX.FreeBSD.Hardware";
}
if header :contains ["List-Id"] ["freebsd-usb.freebsd.org"] {
fileinto "INBOX.FreeBSD.USB";
}
if header :contains ["List-Id"] ["freebsd-ports.freebsd.org"] {
fileinto "INBOX.FreeBSD.Ports";
}
if header :contains ["To"] ["amistry@php.net"] {
fileinto "INBOX.PEAR.Account";
}
if header :contains ["list-post"] ["pear-qa@lists.php.net"] {
fileinto "INBOX.PEAR.QA";
}
if header :contains ["Delivered-To"] ["php-general@lists.php.net"] {
fileinto "INBOX.PHP.General";
}
if header :contains ["Delivered-to"] ["internals@lists.php.net"] {
fileinto "INBOX.PEAR.Internals";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["cvs-all.freebsd.org"] {
fileinto "INBOX.FreeBSD.CVS All";
}
if header :contains ["List-Id"] ["freebsd-acpi.freebsd.org"] {
fileinto "INBOX.FreeBSD.ACPI";
}
if header :contains ["List-Id"] ["freebsd-current.freebsd.org"] {
fileinto "INBOX.FreeBSD.Current";
}
if header :contains ["List-Id"] ["freebsd-hackers.freebsd.org"] {
fileinto "INBOX.FreeBSD.Hackers";
}
if header :contains ["List-Id"] ["freebsd-multimedia.freebsd.org"] {
fileinto "INBOX.FreeBSD.Multimedia";
}
if header :contains ["List-Id"] ["freebsd-questions.freebsd.org"] {
fileinto "INBOX.FreeBSD.Questions";
}
if header :contains ["List-Id"] ["freebsd-stable.freebsd.org"] {
fileinto "INBOX.FreeBSD.Stable";
}
if header :contains ["List-Id"] ["freebsd-mobile.freebsd.org"] {
fileinto "INBOX.FreeBSD.Mobile";
}
if header :contains ["List-Id"] ["wine-devel.winehq.org"] {
fileinto "INBOX.FreeBSD.Wine.Devel";
}
if header :contains ["List-Id"] ["wine-users.winehq.org"] {
fileinto "INBOX.FreeBSD.Wine.Users";
}
if header :contains ["List-Id"] ["dri-devel.lists.sourceforge.net"] {
fileinto "INBOX.FreeBSD.dri-devel";
}
if header :contains ["List-Id"] ["freebsd-threads.freebsd.org"] {
fileinto "INBOX.FreeBSD.Threads";
}
if header :contains ["List-Id"] ["freebsd-hardware.freebsd.org"] {
fileinto "INBOX.FreeBSD.Hardware";
}
if header :contains ["List-Id"] ["freebsd-usb.freebsd.org"] {
fileinto "INBOX.FreeBSD.USB";
}
if header :contains ["List-Id"] ["freebsd-ports.freebsd.org"] {
fileinto "INBOX.FreeBSD.Ports";
}
if header :contains ["To"] ["amistry@php.net"] {
fileinto "INBOX.PEAR.Account";
}
if header :contains ["list-post"] ["pear-qa@lists.php.net"] {
fileinto "INBOX.PEAR.QA";
}
if header :contains ["Delivered-To"] ["php-general@lists.php.net"] {
fileinto "INBOX.PHP.General";
}
if header :contains ["Delivered-to"] ["internals@lists.php.net"] {
fileinto "INBOX.PEAR.Internals";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["cvs-all.freebsd.org"] {
fileinto "INBOX.FreeBSD.CVS All";
}
if header :contains ["List-Id"] ["freebsd-acpi.freebsd.org"] {
fileinto "INBOX.FreeBSD.ACPI";
}
if header :contains ["List-Id"] ["freebsd-current.freebsd.org"] {
fileinto "INBOX.FreeBSD.Current";
}
if header :contains ["List-Id"] ["freebsd-hackers.freebsd.org"] {
fileinto "INBOX.FreeBSD.Hackers";
}
if header :contains ["List-Id"] ["freebsd-multimedia.freebsd.org"] {
fileinto "INBOX.FreeBSD.Multimedia";
}
if header :contains ["List-Id"] ["freebsd-questions.freebsd.org"] {
fileinto "INBOX.FreeBSD.Questions";
}
if header :contains ["List-Id"] ["freebsd-stable.freebsd.org"] {
fileinto "INBOX.FreeBSD.Stable";
}
if header :contains ["List-Id"] ["freebsd-mobile.freebsd.org"] {
fileinto "INBOX.FreeBSD.Mobile";
}
if header :contains ["List-Id"] ["wine-devel.winehq.org"] {
fileinto "INBOX.FreeBSD.Wine.Devel";
}
if header :contains ["List-Id"] ["wine-users.winehq.org"] {
fileinto "INBOX.FreeBSD.Wine.Users";
}
if header :contains ["List-Id"] ["dri-devel.lists.sourceforge.net"] {
fileinto "INBOX.FreeBSD.dri-devel";
}
if header :contains ["List-Id"] ["freebsd-threads.freebsd.org"] {
fileinto "INBOX.FreeBSD.Threads";
}
if header :contains ["List-Id"] ["freebsd-hardware.freebsd.org"] {
fileinto "INBOX.FreeBSD.Hardware";
}
if header :contains ["List-Id"] ["freebsd-usb.freebsd.org"] {
fileinto "INBOX.FreeBSD.USB";
}
if header :contains ["List-Id"] ["freebsd-ports.freebsd.org"] {
fileinto "INBOX.FreeBSD.Ports";
}
if header :contains ["To"] ["amistry@php.net"] {
fileinto "INBOX.PEAR.Account";
}
if header :contains ["list-post"] ["pear-qa@lists.php.net"] {
fileinto "INBOX.PEAR.QA";
}
if header :contains ["Delivered-To"] ["php-general@lists.php.net"] {
fileinto "INBOX.PHP.General";
}
if header :contains ["Delivered-to"] ["internals@lists.php.net"] {
fileinto "INBOX.PEAR.Internals";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["cvs-all.freebsd.org"] {
fileinto "INBOX.FreeBSD.CVS All";
}
if header :contains ["List-Id"] ["freebsd-acpi.freebsd.org"] {
fileinto "INBOX.FreeBSD.ACPI";
}
if header :contains ["List-Id"] ["freebsd-current.freebsd.org"] {
fileinto "INBOX.FreeBSD.Current";
}
if header :contains ["List-Id"] ["freebsd-hackers.freebsd.org"] {
fileinto "INBOX.FreeBSD.Hackers";
}
if header :contains ["List-Id"] ["freebsd-multimedia.freebsd.org"] {
fileinto "INBOX.FreeBSD.Multimedia";
}
if header :contains ["List-Id"] ["freebsd-questions.freebsd.org"] {
fileinto "INBOX.FreeBSD.Questions";
}
if header :contains ["List-Id"] ["freebsd-stable.freebsd.org"] {
fileinto "INBOX.FreeBSD.Stable";
}
if header :contains ["List-Id"] ["freebsd-mobile.freebsd.org"] {
fileinto "INBOX.FreeBSD.Mobile";
}
if header :contains ["List-Id"] ["wine-devel.winehq.org"] {
fileinto "INBOX.FreeBSD.Wine.Devel";
}
if header :contains ["List-Id"] ["wine-users.winehq.org"] {
fileinto "INBOX.FreeBSD.Wine.Users";
}
if header :contains ["List-Id"] ["dri-devel.lists.sourceforge.net"] {
fileinto "INBOX.FreeBSD.dri-devel";
}
if header :contains ["List-Id"] ["freebsd-threads.freebsd.org"] {
fileinto "INBOX.FreeBSD.Threads";
}
if header :contains ["List-Id"] ["freebsd-hardware.freebsd.org"] {
fileinto "INBOX.FreeBSD.Hardware";
}
if header :contains ["List-Id"] ["freebsd-usb.freebsd.org"] {
fileinto "INBOX.FreeBSD.USB";
}
if header :contains ["List-Id"] ["freebsd-ports.freebsd.org"] {
fileinto "INBOX.FreeBSD.Ports";
}
if header :contains ["To"] ["amistry@php.net"] {
fileinto "INBOX.PEAR.Account";
}
if header :contains ["list-post"] ["pear-qa@lists.php.net"] {
fileinto "INBOX.PEAR.QA";
}
if header :contains ["Delivered-To"] ["php-general@lists.php.net"] {
fileinto "INBOX.PHP.General";
}
if header :contains ["Delivered-to"] ["internals@lists.php.net"] {
fileinto "INBOX.PEAR.Internals";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["cvs-all.freebsd.org"] {
fileinto "INBOX.FreeBSD.CVS All";
}
if header :contains ["List-Id"] ["freebsd-acpi.freebsd.org"] {
fileinto "INBOX.FreeBSD.ACPI";
}
if header :contains ["List-Id"] ["freebsd-current.freebsd.org"] {
fileinto "INBOX.FreeBSD.Current";
}
if header :contains ["List-Id"] ["freebsd-hackers.freebsd.org"] {
fileinto "INBOX.FreeBSD.Hackers";
}
if header :contains ["List-Id"] ["freebsd-multimedia.freebsd.org"] {
fileinto "INBOX.FreeBSD.Multimedia";
}
if header :contains ["List-Id"] ["freebsd-questions.freebsd.org"] {
fileinto "INBOX.FreeBSD.Questions";
}
if header :contains ["List-Id"] ["freebsd-stable.freebsd.org"] {
fileinto "INBOX.FreeBSD.Stable";
}
if header :contains ["List-Id"] ["freebsd-mobile.freebsd.org"] {
fileinto "INBOX.FreeBSD.Mobile";
}
if header :contains ["List-Id"] ["wine-devel.winehq.org"] {
fileinto "INBOX.FreeBSD.Wine.Devel";
}
if header :contains ["List-Id"] ["wine-users.winehq.org"] {
fileinto "INBOX.FreeBSD.Wine.Users";
}
if header :contains ["List-Id"] ["dri-devel.lists.sourceforge.net"] {
fileinto "INBOX.FreeBSD.dri-devel";
}
if header :contains ["List-Id"] ["freebsd-threads.freebsd.org"] {
fileinto "INBOX.FreeBSD.Threads";
}
if header :contains ["List-Id"] ["freebsd-hardware.freebsd.org"] {
fileinto "INBOX.FreeBSD.Hardware";
}
if header :contains ["List-Id"] ["freebsd-usb.freebsd.org"] {
fileinto "INBOX.FreeBSD.USB";
}
if header :contains ["List-Id"] ["freebsd-ports.freebsd.org"] {
fileinto "INBOX.FreeBSD.Ports";
}
if header :contains ["To"] ["amistry@php.net"] {
fileinto "INBOX.PEAR.Account";
}
if header :contains ["list-post"] ["pear-qa@lists.php.net"] {
fileinto "INBOX.PEAR.QA";
}
if header :contains ["Delivered-To"] ["php-general@lists.php.net"] {
fileinto "INBOX.PHP.General";
}
if header :contains ["Delivered-to"] ["internals@lists.php.net"] {
fileinto "INBOX.PEAR.Internals";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["cvs-all.freebsd.org"] {
fileinto "INBOX.FreeBSD.CVS All";
}
if header :contains ["List-Id"] ["freebsd-acpi.freebsd.org"] {
fileinto "INBOX.FreeBSD.ACPI";
}
if header :contains ["List-Id"] ["freebsd-current.freebsd.org"] {
fileinto "INBOX.FreeBSD.Current";
}
if header :contains ["List-Id"] ["freebsd-hackers.freebsd.org"] {
fileinto "INBOX.FreeBSD.Hackers";
}
if header :contains ["List-Id"] ["freebsd-multimedia.freebsd.org"] {
fileinto "INBOX.FreeBSD.Multimedia";
}
if header :contains ["List-Id"] ["freebsd-questions.freebsd.org"] {
fileinto "INBOX.FreeBSD.Questions";
}
if header :contains ["List-Id"] ["freebsd-stable.freebsd.org"] {
fileinto "INBOX.FreeBSD.Stable";
}
if header :contains ["List-Id"] ["freebsd-mobile.freebsd.org"] {
fileinto "INBOX.FreeBSD.Mobile";
}
if header :contains ["List-Id"] ["wine-devel.winehq.org"] {
fileinto "INBOX.FreeBSD.Wine.Devel";
}
if header :contains ["List-Id"] ["wine-users.winehq.org"] {
fileinto "INBOX.FreeBSD.Wine.Users";
}
if header :contains ["List-Id"] ["dri-devel.lists.sourceforge.net"] {
fileinto "INBOX.FreeBSD.dri-devel";
}
if header :contains ["List-Id"] ["freebsd-threads.freebsd.org"] {
fileinto "INBOX.FreeBSD.Threads";
}
if header :contains ["List-Id"] ["freebsd-hardware.freebsd.org"] {
fileinto "INBOX.FreeBSD.Hardware";
}
if header :contains ["List-Id"] ["freebsd-usb.freebsd.org"] {
fileinto "INBOX.FreeBSD.USB";
}
if header :contains ["List-Id"] ["freebsd-ports.freebsd.org"] {
fileinto "INBOX.FreeBSD.Ports";
}
if header :contains ["To"] ["amistry@php.net"] {
fileinto "INBOX.PEAR.Account";
}
if header :contains ["list-post"] ["pear-qa@lists.php.net"] {
fileinto "INBOX.PEAR.QA";
}
if header :contains ["Delivered-To"] ["php-general@lists.php.net"] {
fileinto "INBOX.PHP.General";
}
if header :contains ["Delivered-to"] ["internals@lists.php.net"] {
fileinto "INBOX.PEAR.Internals";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["cvs-all.freebsd.org"] {
fileinto "INBOX.FreeBSD.CVS All";
}
if header :contains ["List-Id"] ["freebsd-acpi.freebsd.org"] {
fileinto "INBOX.FreeBSD.ACPI";
}
if header :contains ["List-Id"] ["freebsd-current.freebsd.org"] {
fileinto "INBOX.FreeBSD.Current";
}
if header :contains ["List-Id"] ["freebsd-hackers.freebsd.org"] {
fileinto "INBOX.FreeBSD.Hackers";
}
if header :contains ["List-Id"] ["freebsd-multimedia.freebsd.org"] {
fileinto "INBOX.FreeBSD.Multimedia";
}
if header :contains ["List-Id"] ["freebsd-questions.freebsd.org"] {
fileinto "INBOX.FreeBSD.Questions";
}
if header :contains ["List-Id"] ["freebsd-stable.freebsd.org"] {
fileinto "INBOX.FreeBSD.Stable";
}
if header :contains ["List-Id"] ["freebsd-mobile.freebsd.org"] {
fileinto "INBOX.FreeBSD.Mobile";
}
if header :contains ["List-Id"] ["wine-devel.winehq.org"] {
fileinto "INBOX.FreeBSD.Wine.Devel";
}
if header :contains ["List-Id"] ["wine-users.winehq.org"] {
fileinto "INBOX.FreeBSD.Wine.Users";
}
if header :contains ["List-Id"] ["dri-devel.lists.sourceforge.net"] {
fileinto "INBOX.FreeBSD.dri-devel";
}
if header :contains ["List-Id"] ["freebsd-threads.freebsd.org"] {
fileinto "INBOX.FreeBSD.Threads";
}
if header :contains ["List-Id"] ["freebsd-hardware.freebsd.org"] {
fileinto "INBOX.FreeBSD.Hardware";
}
if header :contains ["List-Id"] ["freebsd-usb.freebsd.org"] {
fileinto "INBOX.FreeBSD.USB";
}
if header :contains ["List-Id"] ["freebsd-ports.freebsd.org"] {
fileinto "INBOX.FreeBSD.Ports";
}
if header :contains ["To"] ["amistry@php.net"] {
fileinto "INBOX.PEAR.Account";
}
if header :contains ["list-post"] ["pear-qa@lists.php.net"] {
fileinto "INBOX.PEAR.QA";
}
if header :contains ["Delivered-To"] ["php-general@lists.php.net"] {
fileinto "INBOX.PHP.General";
}
if header :contains ["Delivered-to"] ["internals@lists.php.net"] {
fileinto "INBOX.PEAR.Internals";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["cvs-all.freebsd.org"] {
fileinto "INBOX.FreeBSD.CVS All";
}
if header :contains ["List-Id"] ["freebsd-acpi.freebsd.org"] {
fileinto "INBOX.FreeBSD.ACPI";
}
if header :contains ["List-Id"] ["freebsd-current.freebsd.org"] {
fileinto "INBOX.FreeBSD.Current";
}
if header :contains ["List-Id"] ["freebsd-hackers.freebsd.org"] {
fileinto "INBOX.FreeBSD.Hackers";
}
if header :contains ["List-Id"] ["freebsd-multimedia.freebsd.org"] {
fileinto "INBOX.FreeBSD.Multimedia";
}
if header :contains ["List-Id"] ["freebsd-questions.freebsd.org"] {
fileinto "INBOX.FreeBSD.Questions";
}
if header :contains ["List-Id"] ["freebsd-stable.freebsd.org"] {
fileinto "INBOX.FreeBSD.Stable";
}
if header :contains ["List-Id"] ["freebsd-mobile.freebsd.org"] {
fileinto "INBOX.FreeBSD.Mobile";
}
if header :contains ["List-Id"] ["wine-devel.winehq.org"] {
fileinto "INBOX.FreeBSD.Wine.Devel";
}
if header :contains ["List-Id"] ["wine-users.winehq.org"] {
fileinto "INBOX.FreeBSD.Wine.Users";
}
if header :contains ["List-Id"] ["dri-devel.lists.sourceforge.net"] {
fileinto "INBOX.FreeBSD.dri-devel";
}
if header :contains ["List-Id"] ["freebsd-threads.freebsd.org"] {
fileinto "INBOX.FreeBSD.Threads";
}
if header :contains ["List-Id"] ["freebsd-hardware.freebsd.org"] {
fileinto "INBOX.FreeBSD.Hardware";
}
if header :contains ["List-Id"] ["freebsd-usb.freebsd.org"] {
fileinto "INBOX.FreeBSD.USB";
}
if header :contains ["List-Id"] ["freebsd-ports.freebsd.org"] {
fileinto "INBOX.FreeBSD.Ports";
}
if header :contains ["To"] ["amistry@php.net"] {
fileinto "INBOX.PEAR.Account";
}
if header :contains ["list-post"] ["pear-qa@lists.php.net"] {
fileinto "INBOX.PEAR.QA";
}
if header :contains ["Delivered-To"] ["php-general@lists.php.net"] {
fileinto "INBOX.PHP.General";
}
if header :contains ["Delivered-to"] ["internals@lists.php.net"] {
fileinto "INBOX.PEAR.Internals";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["cvs-all.freebsd.org"] {
fileinto "INBOX.FreeBSD.CVS All";
}
if header :contains ["List-Id"] ["freebsd-acpi.freebsd.org"] {
fileinto "INBOX.FreeBSD.ACPI";
}
if header :contains ["List-Id"] ["freebsd-current.freebsd.org"] {
fileinto "INBOX.FreeBSD.Current";
}
if header :contains ["List-Id"] ["freebsd-hackers.freebsd.org"] {
fileinto "INBOX.FreeBSD.Hackers";
}
if header :contains ["List-Id"] ["freebsd-multimedia.freebsd.org"] {
fileinto "INBOX.FreeBSD.Multimedia";
}
if header :contains ["List-Id"] ["freebsd-questions.freebsd.org"] {
fileinto "INBOX.FreeBSD.Questions";
}
if header :contains ["List-Id"] ["freebsd-stable.freebsd.org"] {
fileinto "INBOX.FreeBSD.Stable";
}
if header :contains ["List-Id"] ["freebsd-mobile.freebsd.org"] {
fileinto "INBOX.FreeBSD.Mobile";
}
if header :contains ["List-Id"] ["wine-devel.winehq.org"] {
fileinto "INBOX.FreeBSD.Wine.Devel";
}
if header :contains ["List-Id"] ["wine-users.winehq.org"] {
fileinto "INBOX.FreeBSD.Wine.Users";
}
if header :contains ["List-Id"] ["dri-devel.lists.sourceforge.net"] {
fileinto "INBOX.FreeBSD.dri-devel";
}
if header :contains ["List-Id"] ["freebsd-threads.freebsd.org"] {
fileinto "INBOX.FreeBSD.Threads";
}
if header :contains ["List-Id"] ["freebsd-hardware.freebsd.org"] {
fileinto "INBOX.FreeBSD.Hardware";
}
if header :contains ["List-Id"] ["freebsd-usb.freebsd.org"] {
fileinto "INBOX.FreeBSD.USB";
}
if header :contains ["List-Id"] ["freebsd-ports.freebsd.org"] {
fileinto "INBOX.FreeBSD.Ports";
}
if header :contains ["To"] ["amistry@php.net"] {
fileinto "INBOX.PEAR.Account";
}
if header :contains ["list-post"] ["pear-qa@lists.php.net"] {
fileinto "INBOX.PEAR.QA";
}
if header :contains ["Delivered-To"] ["php-general@lists.php.net"] {
fileinto "INBOX.PHP.General";
}
if header :contains ["Delivered-to"] ["internals@lists.php.net"] {
fileinto "INBOX.PEAR.Internals";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["cvs-all.freebsd.org"] {
fileinto "INBOX.FreeBSD.CVS All";
}
if header :contains ["List-Id"] ["freebsd-acpi.freebsd.org"] {
fileinto "INBOX.FreeBSD.ACPI";
}
if header :contains ["List-Id"] ["freebsd-current.freebsd.org"] {
fileinto "INBOX.FreeBSD.Current";
}
if header :contains ["List-Id"] ["freebsd-hackers.freebsd.org"] {
fileinto "INBOX.FreeBSD.Hackers";
}
if header :contains ["List-Id"] ["freebsd-multimedia.freebsd.org"] {
fileinto "INBOX.FreeBSD.Multimedia";
}
if header :contains ["List-Id"] ["freebsd-questions.freebsd.org"] {
fileinto "INBOX.FreeBSD.Questions";
}
if header :contains ["List-Id"] ["freebsd-stable.freebsd.org"] {
fileinto "INBOX.FreeBSD.Stable";
}
if header :contains ["List-Id"] ["freebsd-mobile.freebsd.org"] {
fileinto "INBOX.FreeBSD.Mobile";
}
if header :contains ["List-Id"] ["wine-devel.winehq.org"] {
fileinto "INBOX.FreeBSD.Wine.Devel";
}
if header :contains ["List-Id"] ["wine-users.winehq.org"] {
fileinto "INBOX.FreeBSD.Wine.Users";
}
if header :contains ["List-Id"] ["dri-devel.lists.sourceforge.net"] {
fileinto "INBOX.FreeBSD.dri-devel";
}
if header :contains ["List-Id"] ["freebsd-threads.freebsd.org"] {
fileinto "INBOX.FreeBSD.Threads";
}
if header :contains ["List-Id"] ["freebsd-hardware.freebsd.org"] {
fileinto "INBOX.FreeBSD.Hardware";
}
if header :contains ["List-Id"] ["freebsd-usb.freebsd.org"] {
fileinto "INBOX.FreeBSD.USB";
}
if header :contains ["List-Id"] ["freebsd-ports.freebsd.org"] {
fileinto "INBOX.FreeBSD.Ports";
}
if header :contains ["To"] ["amistry@php.net"] {
fileinto "INBOX.PEAR.Account";
}
if header :contains ["list-post"] ["pear-qa@lists.php.net"] {
fileinto "INBOX.PEAR.QA";
}
if header :contains ["Delivered-To"] ["php-general@lists.php.net"] {
fileinto "INBOX.PHP.General";
}
if header :contains ["Delivered-to"] ["internals@lists.php.net"] {
fileinto "INBOX.PEAR.Internals";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["cvs-all.freebsd.org"] {
fileinto "INBOX.FreeBSD.CVS All";
}
if header :contains ["List-Id"] ["freebsd-acpi.freebsd.org"] {
fileinto "INBOX.FreeBSD.ACPI";
}
if header :contains ["List-Id"] ["freebsd-current.freebsd.org"] {
fileinto "INBOX.FreeBSD.Current";
}
if header :contains ["List-Id"] ["freebsd-hackers.freebsd.org"] {
fileinto "INBOX.FreeBSD.Hackers";
}
if header :contains ["List-Id"] ["freebsd-multimedia.freebsd.org"] {
fileinto "INBOX.FreeBSD.Multimedia";
}
if header :contains ["List-Id"] ["freebsd-questions.freebsd.org"] {
fileinto "INBOX.FreeBSD.Questions";
}
if header :contains ["List-Id"] ["freebsd-stable.freebsd.org"] {
fileinto "INBOX.FreeBSD.Stable";
}
if header :contains ["List-Id"] ["freebsd-mobile.freebsd.org"] {
fileinto "INBOX.FreeBSD.Mobile";
}
if header :contains ["List-Id"] ["wine-devel.winehq.org"] {
fileinto "INBOX.FreeBSD.Wine.Devel";
}
if header :contains ["List-Id"] ["wine-users.winehq.org"] {
fileinto "INBOX.FreeBSD.Wine.Users";
}
if header :contains ["List-Id"] ["dri-devel.lists.sourceforge.net"] {
fileinto "INBOX.FreeBSD.dri-devel";
}
if header :contains ["List-Id"] ["freebsd-threads.freebsd.org"] {
fileinto "INBOX.FreeBSD.Threads";
}
if header :contains ["List-Id"] ["freebsd-hardware.freebsd.org"] {
fileinto "INBOX.FreeBSD.Hardware";
}
if header :contains ["List-Id"] ["freebsd-usb.freebsd.org"] {
fileinto "INBOX.FreeBSD.USB";
}
if header :contains ["List-Id"] ["freebsd-ports.freebsd.org"] {
fileinto "INBOX.FreeBSD.Ports";
}
if header :contains ["To"] ["amistry@php.net"] {
fileinto "INBOX.PEAR.Account";
}
if header :contains ["list-post"] ["pear-qa@lists.php.net"] {
fileinto "INBOX.PEAR.QA";
}
if header :contains ["Delivered-To"] ["php-general@lists.php.net"] {
fileinto "INBOX.PHP.General";
}
if header :contains ["Delivered-to"] ["internals@lists.php.net"] {
fileinto "INBOX.PEAR.Internals";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["cvs-all.freebsd.org"] {
fileinto "INBOX.FreeBSD.CVS All";
}
if header :contains ["List-Id"] ["freebsd-acpi.freebsd.org"] {
fileinto "INBOX.FreeBSD.ACPI";
}
if header :contains ["List-Id"] ["freebsd-current.freebsd.org"] {
fileinto "INBOX.FreeBSD.Current";
}
if header :contains ["List-Id"] ["freebsd-hackers.freebsd.org"] {
fileinto "INBOX.FreeBSD.Hackers";
}
if header :contains ["List-Id"] ["freebsd-multimedia.freebsd.org"] {
fileinto "INBOX.FreeBSD.Multimedia";
}
if header :contains ["List-Id"] ["freebsd-questions.freebsd.org"] {
fileinto "INBOX.FreeBSD.Questions";
}
if header :contains ["List-Id"] ["freebsd-stable.freebsd.org"] {
fileinto "INBOX.FreeBSD.Stable";
}
if header :contains ["List-Id"] ["freebsd-mobile.freebsd.org"] {
fileinto "INBOX.FreeBSD.Mobile";
}
if header :contains ["List-Id"] ["wine-devel.winehq.org"] {
fileinto "INBOX.FreeBSD.Wine.Devel";
}
if header :contains ["List-Id"] ["wine-users.winehq.org"] {
fileinto "INBOX.FreeBSD.Wine.Users";
}
if header :contains ["List-Id"] ["dri-devel.lists.sourceforge.net"] {
fileinto "INBOX.FreeBSD.dri-devel";
}
if header :contains ["List-Id"] ["freebsd-threads.freebsd.org"] {
fileinto "INBOX.FreeBSD.Threads";
}
if header :contains ["List-Id"] ["freebsd-hardware.freebsd.org"] {
fileinto "INBOX.FreeBSD.Hardware";
}
if header :contains ["List-Id"] ["freebsd-usb.freebsd.org"] {
fileinto "INBOX.FreeBSD.USB";
}
if header :contains ["List-Id"] ["freebsd-ports.freebsd.org"] {
fileinto "INBOX.FreeBSD.Ports";
}
if header :contains ["To"] ["amistry@php.net"] {
fileinto "INBOX.PEAR.Account";
}
if header :contains ["list-post"] ["pear-qa@lists.php.net"] {
fileinto "INBOX.PEAR.QA";
}
if header :contains ["Delivered-To"] ["php-general@lists.php.net"] {
fileinto "INBOX.PHP.General";
}
if header :contains ["Delivered-to"] ["internals@lists.php.net"] {
fileinto "INBOX.PEAR.Internals";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["cvs-all.freebsd.org"] {
fileinto "INBOX.FreeBSD.CVS All";
}
if header :contains ["List-Id"] ["freebsd-acpi.freebsd.org"] {
fileinto "INBOX.FreeBSD.ACPI";
}
if header :contains ["List-Id"] ["freebsd-current.freebsd.org"] {
fileinto "INBOX.FreeBSD.Current";
}
if header :contains ["List-Id"] ["freebsd-hackers.freebsd.org"] {
fileinto "INBOX.FreeBSD.Hackers";
}
if header :contains ["List-Id"] ["freebsd-multimedia.freebsd.org"] {
fileinto "INBOX.FreeBSD.Multimedia";
}
if header :contains ["List-Id"] ["freebsd-questions.freebsd.org"] {
fileinto "INBOX.FreeBSD.Questions";
}
if header :contains ["List-Id"] ["freebsd-stable.freebsd.org"] {
fileinto "INBOX.FreeBSD.Stable";
}
if header :contains ["List-Id"] ["freebsd-mobile.freebsd.org"] {
fileinto "INBOX.FreeBSD.Mobile";
}
if header :contains ["List-Id"] ["wine-devel.winehq.org"] {
fileinto "INBOX.FreeBSD.Wine.Devel";
}
if header :contains ["List-Id"] ["wine-users.winehq.org"] {
fileinto "INBOX.FreeBSD.Wine.Users";
}
if header :contains ["List-Id"] ["dri-devel.lists.sourceforge.net"] {
fileinto "INBOX.FreeBSD.dri-devel";
}
if header :contains ["List-Id"] ["freebsd-threads.freebsd.org"] {
fileinto "INBOX.FreeBSD.Threads";
}
if header :contains ["List-Id"] ["freebsd-hardware.freebsd.org"] {
fileinto "INBOX.FreeBSD.Hardware";
}
if header :contains ["List-Id"] ["freebsd-usb.freebsd.org"] {
fileinto "INBOX.FreeBSD.USB";
}
if header :contains ["List-Id"] ["freebsd-ports.freebsd.org"] {
fileinto "INBOX.FreeBSD.Ports";
}
if header :contains ["To"] ["amistry@php.net"] {
fileinto "INBOX.PEAR.Account";
}
if header :contains ["list-post"] ["pear-qa@lists.php.net"] {
fileinto "INBOX.PEAR.QA";
}
if header :contains ["Delivered-To"] ["php-general@lists.php.net"] {
fileinto "INBOX.PHP.General";
}
if header :contains ["Delivered-to"] ["internals@lists.php.net"] {
fileinto "INBOX.PEAR.Internals";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["cvs-all.freebsd.org"] {
fileinto "INBOX.FreeBSD.CVS All";
}
if header :contains ["List-Id"] ["freebsd-acpi.freebsd.org"] {
fileinto "INBOX.FreeBSD.ACPI";
}
if header :contains ["List-Id"] ["freebsd-current.freebsd.org"] {
fileinto "INBOX.FreeBSD.Current";
}
if header :contains ["List-Id"] ["freebsd-hackers.freebsd.org"] {
fileinto "INBOX.FreeBSD.Hackers";
}
if header :contains ["List-Id"] ["freebsd-multimedia.freebsd.org"] {
fileinto "INBOX.FreeBSD.Multimedia";
}
if header :contains ["List-Id"] ["freebsd-questions.freebsd.org"] {
fileinto "INBOX.FreeBSD.Questions";
}
if header :contains ["List-Id"] ["freebsd-stable.freebsd.org"] {
fileinto "INBOX.FreeBSD.Stable";
}
if header :contains ["List-Id"] ["freebsd-mobile.freebsd.org"] {
fileinto "INBOX.FreeBSD.Mobile";
}
if header :contains ["List-Id"] ["wine-devel.winehq.org"] {
fileinto "INBOX.FreeBSD.Wine.Devel";
}
if header :contains ["List-Id"] ["wine-users.winehq.org"] {
fileinto "INBOX.FreeBSD.Wine.Users";
}
if header :contains ["List-Id"] ["dri-devel.lists.sourceforge.net"] {
fileinto "INBOX.FreeBSD.dri-devel";
}
if header :contains ["List-Id"] ["freebsd-threads.freebsd.org"] {
fileinto "INBOX.FreeBSD.Threads";
}
if header :contains ["List-Id"] ["freebsd-hardware.freebsd.org"] {
fileinto "INBOX.FreeBSD.Hardware";
}
if header :contains ["List-Id"] ["freebsd-usb.freebsd.org"] {
fileinto "INBOX.FreeBSD.USB";
}
if header :contains ["List-Id"] ["freebsd-ports.freebsd.org"] {
fileinto "INBOX.FreeBSD.Ports";
}
if header :contains ["To"] ["amistry@php.net"] {
fileinto "INBOX.PEAR.Account";
}
if header :contains ["list-post"] ["pear-qa@lists.php.net"] {
fileinto "INBOX.PEAR.QA";
}
if header :contains ["Delivered-To"] ["php-general@lists.php.net"] {
fileinto "INBOX.PHP.General";
}
if header :contains ["Delivered-to"] ["internals@lists.php.net"] {
fileinto "INBOX.PEAR.Internals";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
if header :contains ["List-Id"] ["suphp.lists.marsching.biz"] {
fileinto "INBOX.suPHP";
}
PKu]Ynpp$test/Net_Sieve/tests/config.php.distnu[
 * @copyright 2006 Anish Mistry
 * @license   http://www.opensource.org/licenses/bsd-license.php BSD
 * @version   SVN: $Id$
 * @link      http://pear.php.net/package/Net_Sieve
 */

require_once dirname(__FILE__) . '/../Sieve.php';

/**
 * PHPUnit test case for Net_Sieve.
 *
 * @category  Networking
 * @package   Net_Sieve
 * @author    Anish Mistry 
 * @copyright 2006 Anish Mistry
 * @license   http://www.opensource.org/licenses/bsd-license.php BSD
 * @version   Release: @package_version@
 * @link      http://pear.php.net/package/Net_Sieve
 */
class SieveTest extends PHPUnit\Framework\TestCase
{
    // contains the object handle of the string class
    protected $fixture;

    protected function setUp()
    {
        if (!file_exists(dirname(__FILE__) . '/config.php')) {
            $this->markTestSkipped('Test configuration incomplete. Copy config.php.dist to config.php.');
        }
        require_once dirname(__FILE__) . '/config.php';

        // Create a new instance of Net_Sieve.
        $this->_pear = new PEAR();
        $this->fixture = new Net_Sieve();
        $this->scripts = array(
            'test script1' => "require \"fileinto\";\r\nif header :contains \"From\" \"@cnba.uba.ar\" \r\n{fileinto \"INBOX.Test1\";}\r\nelse \r\n{fileinto \"INBOX\";}",
            'test script2' => "require \"fileinto\";\r\nif header :contains \"From\" \"@cnba.uba.ar\" \r\n{fileinto \"INBOX.Test\";}\r\nelse \r\n{fileinto \"INBOX\";}",
            'test"scriptäöü3' => "require \"vacation\";\nvacation\n:days 7\n:addresses [\"matthew@de-construct.com\"]\n:subject \"This is a test\"\n\"I'm on my holiday!\nsadfafs\";",
            'test script4' => file_get_contents(dirname(__FILE__) . '/largescript.siv'));
    }
    
    protected function tearDown()
    {
        // Delete the instance.
        unset($this->fixture);
    }
    
    protected function login()
    {
        $result = $this->fixture->connect(HOST, PORT);
        $this->assertTrue($this->check($result), 'Can not connect');
        $result = $this->fixture->login(USERNAME, PASSWORD, null, '', false);
        $this->assertTrue($this->check($result), 'Can not login');
    }

    protected function logout()
    {
        $result = $this->fixture->disconnect();
        $this->assertFalse($this->_pear->isError($result), 'Error on disconnect');
    }

    protected function clear()
    {
        // Clear all the scripts in the account.
        $this->login();
        $active = $this->fixture->getActive();
        if (isset($this->scripts[$active])) {
            $this->fixture->setActive(null);
        }
        foreach (array_keys($this->scripts) as $script) {
            $this->fixture->removeScript($script);
        }
        $this->logout();
    }

    protected function check($result)
    {
        if ($this->_pear->isError($result)) {
            throw new Exception($result->getMessage());
        }
        return $result;
    }

    public function testConnect()
    {
        $result = $this->fixture->connect(HOST, PORT);
        $this->assertTrue($this->check($result), 'Cannot connect');
    }
    
    public function testLogin()
    {
        $result = $this->fixture->connect(HOST, PORT);
        $this->assertTrue($this->check($result), 'Cannot connect');
        $result = $this->fixture->login(USERNAME, PASSWORD, null, '', false);
        $this->assertTrue($this->check($result), 'Cannot login');
    }

    public function testDisconnect()
    {
        $result = $this->fixture->connect(HOST, PORT);
        $this->assertFalse($this->_pear->isError($result), 'Cannot connect');
        $result = $this->fixture->login(USERNAME, PASSWORD, null, '', false);
        $this->assertFalse($this->_pear->isError($result), 'Cannot login');
        $result = $this->fixture->disconnect();
        $this->assertFalse($this->_pear->isError($result), 'Error on disconnect');
    }

    public function testListScripts()
    {
        $this->login();
        $scripts = $this->fixture->listScripts();
        $this->logout();
        $this->assertFalse($this->_pear->isError($scripts), 'Can not list scripts');
    }

    public function testInstallScript()
    {
        $this->clear();
        $this->login();

        // First script.
        $scriptname = 'test script1';
        $before_scripts = $this->fixture->listScripts();
        $result = $this->fixture->installScript($scriptname, $this->scripts[$scriptname]);
        $this->assertFalse($this->_pear->isError($result), 'Can not install script ' . $scriptname);
        $after_scripts = $this->fixture->listScripts();
        $diff_scripts = array_values(array_diff($after_scripts, $before_scripts));
        $this->assertTrue(count($diff_scripts) > 0, 'Script not installed');
        $this->assertEquals($scriptname, $diff_scripts[0], 'Added script has a different name');

        // Second script (install and activate)
        $scriptname = 'test script2';
        $before_scripts = $this->fixture->listScripts();
        $result = $this->fixture->installScript($scriptname, $this->scripts[$scriptname], true);
        $this->assertFalse($this->_pear->isError($result), 'Can not install script ' . $scriptname);
        $after_scripts = $this->fixture->listScripts();
        $diff_scripts = array_values(array_diff($after_scripts, $before_scripts));
        $this->assertTrue(count($diff_scripts) > 0, 'Script not installed');
        $this->assertEquals($scriptname, $diff_scripts[0], 'Added script has a different name');
        $active_script = $this->fixture->getActive();
        $this->assertEquals($scriptname, $active_script, 'Added script has a different name');
        $this->logout();
    }

    /**
     * There is a good chance that this test will fail since most servers have
     * a 32KB limit on uploaded scripts.
     */
    public function testInstallScriptLarge()
    {
        $this->clear();
        $this->login();
        $scriptname = 'test script4';
        $before_scripts = $this->fixture->listScripts();
        $result = $this->fixture->installScript($scriptname, $this->scripts[$scriptname]);
        $this->assertFalse($this->_pear->isError($result), 'Unable to upload large script (expected behavior for most servers)');
        $after_scripts = $this->fixture->listScripts();
        $diff_scripts = array_diff($after_scripts, $before_scripts);
        $this->assertEquals($scriptname, reset($diff_scripts), 'Added script has a different name');
        $this->logout();
    }

    /**
     * See bug #16691.
     */
    public function testInstallNonAsciiScript()
    {
        $this->clear();
        $this->login();

        $scriptname = 'test"scriptäöü3';
        $before_scripts = $this->fixture->listScripts();
        $result = $this->fixture->installScript($scriptname, $this->scripts[$scriptname]);
        $this->assertFalse($this->_pear->isError($result), 'Can not install script ' . $scriptname);
        $after_scripts = $this->fixture->listScripts();
        $diff_scripts = array_values(array_diff($after_scripts, $before_scripts));
        $this->assertTrue(count($diff_scripts) > 0, 'Script not installed');
        $this->assertEquals($scriptname, $diff_scripts[0], 'Added script has a different name');

        $this->logout();
    }

    public function testGetScript()
    {
        $this->clear();
        $this->login();
        $scriptname = 'test script1';
        $before_scripts = $this->fixture->listScripts();
        $result = $this->fixture->installScript($scriptname, $this->scripts[$scriptname]);
        $this->assertFalse($this->_pear->isError($result), 'Can not install script ' . $scriptname);
        $after_scripts = $this->fixture->listScripts();
        $diff_scripts = array_values(array_diff($after_scripts, $before_scripts));
        $this->assertTrue(count($diff_scripts) > 0);
        $this->assertEquals($scriptname, $diff_scripts[0], 'Added script has a different name');
        $script = $this->fixture->getScript($scriptname);
        $this->assertEquals(trim($this->scripts[$scriptname]), trim($script), 'Script installed is not the same script retrieved');
        $this->logout();
    }

    public function testGetActive()
    {
        $this->clear();
        $this->login();
        $active_script = $this->fixture->getActive();
        $this->assertFalse($this->_pear->isError($active_script), 'Error getting the active script');
        $this->logout();
    }

    public function testSetActive()
    {
        $this->clear();
        $scriptname = 'test script1';
        $this->login();
        $result = $this->fixture->installScript($scriptname, $this->scripts[$scriptname]);
        $result = $this->fixture->setActive($scriptname);
        $this->assertFalse($this->_pear->isError($result), 'Can not set active script');
        $active_script = $this->fixture->getActive();
        $this->assertEquals($scriptname, $active_script, 'Active script does not match');

        // Test for non-existant script.
        $result = $this->fixture->setActive('non existant script');
        $this->assertTrue($this->_pear->isError($result));
        $this->logout();
    }

    public function testRemoveScript()
    {
        $this->clear();
        $scriptname = 'test script1';
        $this->login();
        $result = $this->fixture->installScript($scriptname, $this->scripts[$scriptname]);
        $result = $this->fixture->removeScript($scriptname);
        $this->assertFalse($this->_pear->isError($result), 'Error removing active script');
        $this->logout();
    }
}
PKu]g+(test/Mail_Mime/tests/test_Bug_13444.phptnu[--TEST--
Bug #9725   multipart/related & alternative wrong order
--SKIPIF--
--FILE--
setTXTBody("test");
$mime->setHTMLBody("test");
$mime->addHTMLImage("test", 'application/octet-stream', '', false);
$body = $mime->get();
$head = $mime->headers();
$headCT = $head['Content-Type'];
$headCT = explode(";", $headCT);
$headCT = $headCT[0];

$ct = preg_match_all('|Content-Type: ([^;\r\n]+)|', $body, $matches);
print($headCT);
print("\n");
foreach ($matches[1] as $match){
    print($match);
    print("\n");
}
--EXPECT--
multipart/alternative
text/plain
multipart/related
text/html
application/octet-stream
PKu]UiE!E!2test/Mail_Mime/tests/headers_without_mbstring.phptnu[--TEST--
Multi-test for headers encoding using base64 and quoted-printable
--SKIPIF--

--FILE--
'),
array('From', 'adresse@adresse.de'),
array('From', 'Frank Do '),
array('To', 'Frank Do , James Clark '),
array('From', '"Frank Do" '),
array('Cc', '"Frank Do" , "James Clark" '),
array('Cc', ' , "Kuśmiderski Jan Krzysztof Janusz Długa nazwa" '),
array('From', '"adresse@adresse.de" '),
array('From', 'adresse@adresse.de '),
array('From', '"German Umlauts öäü" '),
array('Subject', 'German Umlauts öäü '),
array('Subject', 'Short ASCII subject'),
array('Subject', 'Long ASCII subject - multiline space separated words - too long for one line'),
array('Subject', 'Short Unicode ż subject'),
array('Subject', 'Long Unicode subject - zażółć gęślą jaźń - too long for one line'),
array('References', '  <4b2e87ac$1@news.home.net.pl> '),
array('To', '"Frank Do" ,, "James Clark" '),
array('To', '"Frank \\" \\\\Do" '),
array('To', 'Frank " \\Do '),
array('Subject', "A REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY /REALLY/ LONG test"),
array('Subject', "TEST Süper gröse tolle grüße von mir Süper gröse tolle grüße von mir Süper gröse tolle grüße von mir Süper gröse tolle grüße von mir Süper gröse tolle grüße von mir Süper gröse tolle grüße von mir Süper gröse tolle grüße von mir Süper gröse tolle grüße von mir Süper gröse tolle grüße von mir!!!?"),
array('Subject', "Update: Microsoft Windows-Tool zum Entfernen bösartiger Software 3.6"),
array('From', "test@nàme "),
array('From', "Test <\"test test\"@domain.com>"),
array('From', "\"test test\"@domain.com"),
array('From', "<\"test test\"@domain.com>"),
array('From', "Doe"),
array('From', "\"John Doe\""),
array('Mail-Reply-To', 'adresse@adresse.de '),
array('Mail-Reply-To', '"öäü" '),
);

$i = 1;
foreach ($headers as $header) {
    $hdr = $mime->encodeHeader($header[0], $header[1], 'UTF-8', 'base64');
    printf("[%02d] %s: %s\n", $i, $header[0], $hdr);
    $hdr = $mime->encodeHeader($header[0], $header[1], 'UTF-8', 'quoted-printable');
    printf("[%02d] %s: %s\n", $i, $header[0], $hdr);
    $i++;
}
?>
--EXPECT--
[01] From: 
[01] From: 
[02] From: adresse@adresse.de
[02] From: adresse@adresse.de
[03] From: Frank Do 
[03] From: Frank Do 
[04] To: Frank Do , James Clark 
[04] To: Frank Do , James Clark 
[05] From: "Frank Do" 
[05] From: "Frank Do" 
[06] Cc: "Frank Do" , "James Clark" 
[06] Cc: "Frank Do" , "James Clark" 
[07] Cc: , =?UTF-8?B?S3XFm21pZGVyc2tpIEphbiBLcnp5c3p0b2Yg?=
 =?UTF-8?B?SmFudXN6IETFgnVnYSBuYXp3YQ==?= 
[07] Cc: ,
 =?UTF-8?Q?Ku=C5=9Bmiderski_Jan_Krzysztof_Janusz_D?=
 =?UTF-8?Q?=C5=82uga_nazwa?= 
[08] From: "adresse@adresse.de" 
[08] From: "adresse@adresse.de" 
[09] From: "adresse@adresse.de" 
[09] From: "adresse@adresse.de" 
[10] From: =?UTF-8?B?R2VybWFuIFVtbGF1dHMgw7bDpMO8?= 
[10] From: =?UTF-8?Q?German_Umlauts_=C3=B6=C3=A4=C3=BC?= 
[11] Subject: =?UTF-8?B?R2VybWFuIFVtbGF1dHMgw7bDpMO8IDxhZHJlc3NlQGFkcmVzc2Uu?=
 =?UTF-8?B?ZGU+?=
[11] Subject: =?UTF-8?Q?German_Umlauts_=C3=B6=C3=A4=C3=BC_=3Cadresse=40adresse?=
 =?UTF-8?Q?=2Ede=3E?=
[12] Subject: Short ASCII subject
[12] Subject: Short ASCII subject
[13] Subject: Long ASCII subject - multiline space separated words - too long for
 one line
[13] Subject: Long ASCII subject - multiline space separated words - too long for
 one line
[14] Subject: =?UTF-8?B?U2hvcnQgVW5pY29kZSDFvCBzdWJqZWN0?=
[14] Subject: =?UTF-8?Q?Short_Unicode_=C5=BC_subject?=
[15] Subject: =?UTF-8?B?TG9uZyBVbmljb2RlIHN1YmplY3QgLSB6YcW8w7PFgsSHIGfEmcWb?=
 =?UTF-8?B?bMSFIGphxbrFhCAtIHRvbyBsb25nIGZvciBvbmUgbGluZQ==?=
[15] Subject: =?UTF-8?Q?Long_Unicode_subject_-_za=C5=BC=C3=B3=C5=82=C4=87_g=C4?=
 =?UTF-8?Q?=99=C5=9Bl=C4=85_ja=C5=BA=C5=84_-_too_long_for_one_line?=
[16] References: 
 <4b2e87ac$1@news.home.net.pl> 
[16] References: 
 <4b2e87ac$1@news.home.net.pl> 
[17] To: "Frank Do" , "James Clark" 
[17] To: "Frank Do" , "James Clark" 
[18] To: "Frank \" \\Do" 
[18] To: "Frank \" \\Do" 
[19] To: "Frank \" \\Do" 
[19] To: "Frank \" \\Do" 
[20] Subject: A REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY
 REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY
 REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY
 REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY /REALLY/ LONG test
[20] Subject: A REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY
 REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY
 REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY
 REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY /REALLY/ LONG test
[21] Subject: =?UTF-8?B?VEVTVCBTw7xwZXIgZ3LDtnNlIHRvbGxlIGdyw7zDn2Ugdm9uIG1p?=
 =?UTF-8?B?ciBTw7xwZXIgZ3LDtnNlIHRvbGxlIGdyw7zDn2Ugdm9uIG1pciBTw7xwZXIg?=
 =?UTF-8?B?Z3LDtnNlIHRvbGxlIGdyw7zDn2Ugdm9uIG1pciBTw7xwZXIgZ3LDtnNlIHRv?=
 =?UTF-8?B?bGxlIGdyw7zDn2Ugdm9uIG1pciBTw7xwZXIgZ3LDtnNlIHRvbGxlIGdyw7zD?=
 =?UTF-8?B?n2Ugdm9uIG1pciBTw7xwZXIgZ3LDtnNlIHRvbGxlIGdyw7zDn2Ugdm9uIG1p?=
 =?UTF-8?B?ciBTw7xwZXIgZ3LDtnNlIHRvbGxlIGdyw7zDn2Ugdm9uIG1pciBTw7xwZXIg?=
 =?UTF-8?B?Z3LDtnNlIHRvbGxlIGdyw7zDn2Ugdm9uIG1pciBTw7xwZXIgZ3LDtnNlIHRv?=
 =?UTF-8?B?bGxlIGdyw7zDn2Ugdm9uIG1pciEhIT8=?=
[21] Subject: =?UTF-8?Q?TEST_S=C3=BCper_gr=C3=B6se_tolle_gr=C3=BC=C3=9Fe_von_mir?=
 =?UTF-8?Q?_S=C3=BCper_gr=C3=B6se_tolle_gr=C3=BC=C3=9Fe_von_mir_S=C3=BCper_g?=
 =?UTF-8?Q?r=C3=B6se_tolle_gr=C3=BC=C3=9Fe_von_mir_S=C3=BCper_gr=C3=B6se_tol?=
 =?UTF-8?Q?le_gr=C3=BC=C3=9Fe_von_mir_S=C3=BCper_gr=C3=B6se_tolle_gr=C3=BC?=
 =?UTF-8?Q?=C3=9Fe_von_mir_S=C3=BCper_gr=C3=B6se_tolle_gr=C3=BC=C3=9Fe_von_m?=
 =?UTF-8?Q?ir_S=C3=BCper_gr=C3=B6se_tolle_gr=C3=BC=C3=9Fe_von_mir_S=C3=BCper?=
 =?UTF-8?Q?_gr=C3=B6se_tolle_gr=C3=BC=C3=9Fe_von_mir_S=C3=BCper_gr=C3=B6se_t?=
 =?UTF-8?Q?olle_gr=C3=BC=C3=9Fe_von_mir!!!=3F?=
[22] Subject: =?UTF-8?B?VXBkYXRlOiBNaWNyb3NvZnQgV2luZG93cy1Ub29sIHp1bSBFbnRm?=
 =?UTF-8?B?ZXJuZW4gYsO2c2FydGlnZXIgU29mdHdhcmUgMy42?=
[22] Subject: =?UTF-8?Q?Update=3A_Microsoft_Windows-Tool_zum_Entfernen_b=C3=B6sa?=
 =?UTF-8?Q?rtiger_Software_3=2E6?=
[23] From: =?UTF-8?B?dGVzdEBuw6BtZQ==?= 
[23] From: =?UTF-8?Q?test=40n=C3=A0me?= 
[24] From: Test <"test test"@domain.com>
[24] From: Test <"test test"@domain.com>
[25] From: "test test"@domain.com
[25] From: "test test"@domain.com
[26] From: <"test test"@domain.com>
[26] From: <"test test"@domain.com>
[27] From: Doe 
[27] From: Doe 
[28] From: "John Doe" 
[28] From: "John Doe" 
[29] Mail-Reply-To: "adresse@adresse.de" 
[29] Mail-Reply-To: "adresse@adresse.de" 
[30] Mail-Reply-To: =?UTF-8?B?w7bDpMO8?= 
[30] Mail-Reply-To: =?UTF-8?Q?=C3=B6=C3=A4=C3=BC?= 
PKu](test/Mail_Mime/tests/test_Bug_15320.phptnu[--TEST--
Bug #15320  Charset parameter in Content-Type of mail parts
--SKIPIF--
--FILE--
addAttachment('testfile', "text/plain", 'file.txt', FALSE, 'base64', 'attachment', 'ISO-8859-1');

$content = $Mime->get();
//$content = str_replace("\n", '', $content);

if (preg_match('/Content-type:([^\n]+)/i', $content, $matches)) {
    echo $matches[1];
}

?>
--EXPECT--
text/plain; charset=ISO-8859-1;

PKu]ܶghh)test/Mail_Mime/tests/test_Bug_9722_1.phptnu[--TEST--
Bug #9722   quotedPrintableEncode does not encode dot at start of line on Windows platform
--SKIPIF--
--FILE--

--EXPECT--
Here's=
=09
a tab
PKu](V,(test/Mail_Mime/tests/test_Bug_12411.phptnu[--TEST--
Bug #12411  RFC2047 encoded attachment filenames
--SKIPIF--
--FILE--
addAttachment('testfile', "text/plain", $filename, FALSE,
    'base64', 'attachment', 'ISO-8859-1', 'pl', '',
    'quoted-printable', 'base64');

$content = $Mime->get();
$content = str_replace("\n", '', $content);

if (preg_match_all('/(name|filename)=([^\s]+)/i', $content, $matches)) {
    echo implode("\n", $matches[2]);
}

?>
--EXPECT--
"=?ISO-8859-1?Q?=C5=9Bciema?="
"=?ISO-8859-1?B?xZtjaWVtYQ==?=";
PKu]-b2(test/Mail_Mime/tests/test_Bug_13032.phptnu[--TEST--
Bug #13032  Proper (different) boundary for nested parts
--SKIPIF--
--FILE--
setHTMLBody('html');
$mime->setTXTBody('text');
$mime->addAttachment('file.pdf', 'application/pdf', 'file.pdf', false, 'base64', 'inline');
$msg = $mime->getMessage();

if (preg_match_all('/boundary="([^"]+)"/', $msg, $matches)) {
    if (count($matches) == 2 && count($matches[1]) == 2 &&
        $matches[1][0] != $matches[1][1]) {
            print('OK');
    }
}
?>
--EXPECT--
OK
PKu]Izz(test/Mail_Mime/tests/test_Bug_20563.phptnu[--TEST--
Bug #20563  isMultipart() method tests
--SKIPIF--
--FILE--
isMultipart() ? 'TRUE' : 'FALSE') . "\n";

$mime->setTXTBody('test');

echo ($mime->isMultipart() ? 'TRUE' : 'FALSE') . "\n";

$mime->setHTMLBody('test');

echo ($mime->isMultipart() ? 'TRUE' : 'FALSE') . "\n";

--EXPECT--
FALSE
FALSE
TRUE
PKu]Cz2}}(test/Mail_Mime/tests/test_Bug_12165.phptnu[--TEST--
Bug #12165  Dot at the end of the line disappeared
--SKIPIF--
--FILE--
setHTMLBody($string);
print_r($mime->get());
    
--EXPECT--
http://aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa=
=2Ecom
PKu]%+2PP(test/Mail_Mime/tests/test_Bug_18083.phptnu[--TEST--
Bug #18083  Separate charset for attachment's content and headers
--SKIPIF--
--FILE--
addAttachment('testfile', "text/plain",
    base64_decode("xZtjaWVtYQ=="), FALSE,
    'base64', 'attachment', 'ISO-8859-1', 'pl', '',
    'quoted-printable', 'base64', '', 'UTF-8');

$content = $Mime->get();
$content = str_replace("\n", '', $content);

if (preg_match_all('/(name|filename)=([^\s]+)/i', $content, $matches)) {
    echo implode("\n", $matches[2]);
}
?>
--EXPECT--
"=?UTF-8?Q?=C5=9Bciema?="
"=?UTF-8?B?xZtjaWVtYQ==?=";
PKu]e@Q__(test/Mail_Mime/tests/test_Bug_14780.phptnu[--TEST--
Bug #14780  Invalid Content-Type when headers() is called before get()
--SKIPIF--
--FILE--
setTXTBody("test");
$mime->setHTMLBody("test");

$head1 = $mime->headers();
$body = $mime->get();
$head2 = $mime->headers();

if ($head1 === $head2) {
    echo "OK";
}

?>
--EXPECT--
OK
PKu]5(test/Mail_Mime/tests/test_Bug_21098.phptnu[--TEST--
Bug #21098  Handling of empty plain text parts
--SKIPIF--
--FILE--
setTxtBody('');
$mime->setHTMLBody('');

$headers1 = $mime->txtHeaders();
$body     = $mime->get();
$headers2 = $mime->txtHeaders();
print strpos($headers1, 'text/html') && strpos($headers2, 'text/html') ? 'OK' : 'NOT OK';
--EXPECT--
OK
PKu]
Ǟ		2test/Mail_Mime/tests/test_linebreak_larger_76.phptnu[--TEST--
Test for correct linebreaks for lines _longer_ than 76 chars.
--SKIPIF--
--FILE--
 'text/plain',
    'encoding'     => 'quoted-printable',
);

for ($i=74; $i <= strlen($text); $i++) {
    $input = substr($text, 0, $i);
    $mimePart = new Mail_mimePart($input, $params);
    $encoded  =  $mimePart->encode();
    $output = $encoded['body'];
    printf("input: %02d: %s\n", strlen($input), $input);

    $lines = explode("\r\n", $output);
    for($j=0; $j < count($lines); $j++) {
        $line = $lines[$j];
        if ($j + 1 < count($lines)) {
            $line_vis = $line.'\r\n';
        } else {
            $line_vis = $line;
        }
        printf("output:%02d: %s\n", strlen($line), $line_vis);
    }
    print("---\n");
}
--EXPECT--
input: 74: 12345678901234567890123456789012345678901234567890123456789012345678901234
output:74: 12345678901234567890123456789012345678901234567890123456789012345678901234
---
input: 75: 123456789012345678901234567890123456789012345678901234567890123456789012345
output:75: 123456789012345678901234567890123456789012345678901234567890123456789012345
---
input: 76: 1234567890123456789012345678901234567890123456789012345678901234567890123456
output:76: 1234567890123456789012345678901234567890123456789012345678901234567890123456
---
input: 77: 12345678901234567890123456789012345678901234567890123456789012345678901234567
output:76: 123456789012345678901234567890123456789012345678901234567890123456789012345=\r\n
output:02: 67
---
input: 78: 123456789012345678901234567890123456789012345678901234567890123456789012345678
output:76: 123456789012345678901234567890123456789012345678901234567890123456789012345=\r\n
output:03: 678
---
input: 79: 1234567890123456789012345678901234567890123456789012345678901234567890123456789
output:76: 123456789012345678901234567890123456789012345678901234567890123456789012345=\r\n
output:04: 6789
---
input: 80: 12345678901234567890123456789012345678901234567890123456789012345678901234567890
output:76: 123456789012345678901234567890123456789012345678901234567890123456789012345=\r\n
output:05: 67890
---
PKu]1d(test/Mail_Mime/tests/test_Bug_17025.phptnu[--TEST--
Bug #16539  Headers longer than 998 characters
--SKIPIF--
--FILE--
headers($headers);
print_r($hdrs['From']); 
?>
--EXPECT--
aaaaaaaaaabbbbbbbbbbccccccccccddddddddddeeeeeeeeeeffffffffffgggggggggghhhhhhhhhh
PKu]`~@*test/Mail_Mime/tests/test_Bug_12385_1.phptnu[--TEST--
Bug #12385  Bad regex when replacing css style attachments
--SKIPIF--
--FILE--

className {
    background-image: url('test.gif');
}

";

$mime->setHTMLBody($body);
$mime->setFrom($from);
$mime->addHTMLImage('','image/gif', 'test.gif', false);
$msg = $mime->get();

$cidtag = preg_match("|url\('cid:[^']*'\);|", $msg);
if (!$cidtag){
    print("FAIL:\n");
    print($msg);
}else{
    print("OK");
}
--EXPECT--
OK
PKu]o		(test/Mail_Mime/tests/test_Bug_14529.phptnu[--TEST--
Bug #14529  basename() workaround
--SKIPIF--
--FILE--
addAttachment('testfile', "text/plain", $filename, FALSE, 'base64', 'attachment', 'ISO-8859-1');

$content = $Mime->get();
$content = str_replace("\n", '', $content);

if (preg_match('/filename([^\s]+)/i', $content, $matches)) {
    echo $matches[1];
}
?>
--EXPECT--
*=ISO-8859-1''%C5%9Bciema;
PKu]MU..(test/Mail_Mime/tests/test_Bug_20273.phptnu[--TEST--
Bug #20273  Mail_mimePart::encodeHeader() and TAB character
--SKIPIF--
--FILE--
\t";
$mime = new Mail_mimePart();
echo $mime->encodeHeader('References', $refs);
?>
--EXPECT--
 
PKu]Xb(test/Mail_Mime/tests/test_Bug_14779.phptnu[--TEST--
Bug #14779  Proper header-body separator for empty attachment
--SKIPIF--
--FILE--
addAttachment('', "text/plain", 'file.txt', FALSE, 'base64', 'attachment');
$result = $m->get();

if (preg_match('/(Content.*)--=.*/s', $result, $matches)) {
    print_r($matches[1]."END");
}

?>
--EXPECT--
Content-Transfer-Encoding: base64
Content-Type: text/plain;
 name=file.txt
Content-Disposition: attachment;
 filename=file.txt


END
PKu]9::*test/Mail_Mime/tests/test_Bug_10816_1.phptnu[--TEST--
Bug #10816  Unwanted linebreak at the end of output
--SKIPIF--
--FILE--
$eol));
$encoder->setTXTBody('test');
$encoder->setHTMLBody('test');
$encoder->addAttachment('Just a test', 'application/octet-stream', 'test.txt', false);
$body = $encoder->get();
$taillength = -1 * strlen($eol) * 2;
if (substr($body, $taillength) == ($eol.$eol)){
    print("FAILED\n");
    print("Body:\n");
    print("..." . substr($body, -10) . "\n");
}else{
    print("OK\n");
}
--EXPECT--
OK

PKu]Eoo(test/Mail_Mime/tests/test_Bug_13962.phptnu[--TEST--
Bug #13962  Multiple header support
--SKIPIF--
--FILE--
setFrom('user@from.example.com');
$r = $mime->txtHeaders(array('Received' => array('Received 1', 'Received 2')));

print_r($r); 
?>
--EXPECT--
Received: Received 1
Received: Received 2
MIME-Version: 1.0
From: user@from.example.com
PKu]@/NN(test/Mail_Mime/tests/test_Bug_21206.phptnu[--TEST--
Bug #21206  Handling quoted strings
--SKIPIF--
--FILE--
, b ',
    '"c\\\\" , d ',
);
foreach ($tests as $test) {
    $addrs = X::explodeQuotedString('[\t,]', $test);
    foreach ($addrs as $addr) {
        print trim($addr) . PHP_EOL;
    }
}
?>
--EXPECT--
"a" 
b 
"c\\" 
d 
PKu]zŬ(test/Mail_Mime/tests/test_Bug_11731.phptnu[--TEST--
Bug #11731  Full stops after soft line breaks are not encoded
--SKIPIF--
--FILE--
 'text/plain',
    'encoding'     => 'quoted-printable',
);    
$mimePart = new Mail_mimePart($text, $params);
$encoded  =  $mimePart->encode();
echo $encoded['body'];
    
--EXPECT--
=2E123456789012345678901234567890123456789012345678901234567890123456789012=
=2E3456
PKu]X##(test/Mail_Mime/tests/test_Bug_19497.phptnu[--TEST--
Bug #19497  Attachment filenames with a slash character
--SKIPIF--
--FILE--
addAttachment('testfile', "text/plain", $filename, FALSE,
    'base64', 'attachment', 'ISO-8859-1', '', '', 'quoted-printable', 'base64');

$content = $Mime->get();
$content = str_replace("\n", '', $content);

if (preg_match_all('/(name|filename)=([^\s]+)/i', $content, $matches)) {
    echo implode("\n", $matches[2]);
}
?>
--EXPECT--
"test/file.txt"
"test/file.txt";
PKu]8)test/Mail_Mime/tests/test_Bug_3513_1.phptnu[--TEST--
Bug #3513   Support of RFC2231 in header fields. (ISO-8859-1)
--SKIPIF--
--FILE--
addAttachment('testfile',"text/plain", $test, FALSE, 'base64', 'attachment', 'ISO-8859-1');

$content = $Mime->get();
$content = str_replace("\n", '', $content);

if (preg_match('/filename([^\s]+)/i', $content, $matches)) {
    echo $matches[1];
}

--EXPECT--
*=ISO-8859-1''F%F3%F3b%E6r.txt;
PKu]2!B,test/Mail_Mime/tests/test_linebreak_dot.phptnu[--TEST--
Test for correct "." encoding when doing linebreaks
--SKIPIF--
--FILE--
 'text/plain',
    'encoding'     => 'quoted-printable',
);

for ($i=74; $i <= strlen($text); $i++) {
    $input = substr($text, 0, $i);
    $mimePart = new Mail_mimePart($input, $params);
    $encoded  =  $mimePart->encode();
    $output = $encoded['body'];
    printf("input: %02d: %s\n", strlen($input), $input);

    $lines = explode("\r\n", $output);
    for($j=0; $j < count($lines); $j++) {
        $line = $lines[$j];
        if ($j + 1 < count($lines)) {
            $line_vis = $line.'\r\n';
        } else {
            $line_vis = $line;
        }
        printf("output:%02d: %s\n", strlen($line), $line_vis);
    }

    print("---\n");

}
--EXPECT--
input: 74: 0123456789012345678901234567890123456789012345678901234567890123456789012.
output:74: 0123456789012345678901234567890123456789012345678901234567890123456789012.
---
input: 75: 0123456789012345678901234567890123456789012345678901234567890123456789012..
output:75: 0123456789012345678901234567890123456789012345678901234567890123456789012..
---
input: 76: 0123456789012345678901234567890123456789012345678901234567890123456789012...
output:76: 0123456789012345678901234567890123456789012345678901234567890123456789012...
---
input: 77: 0123456789012345678901234567890123456789012345678901234567890123456789012...6
output:76: 0123456789012345678901234567890123456789012345678901234567890123456789012..=\r\n
output:04: =2E6
---
PKu]%BB'test/Mail_Mime/tests/test_Bug_GH16.phptnu[--TEST--
Bug GH-16  Test methods that write to a file
--SKIPIF--
--FILE--
setHTMLBody('html');
$mime->setTXTBody('text');
$mime->setContentType('multipart/alternative', array('boundary' => 'something'));

$temp_filename = dirname(__FILE__) . "/output1.tmp";
touch($temp_filename);
$msg = $mime->saveMessageBody($temp_filename);
echo file_get_contents($temp_filename);

$temp_filename = dirname(__FILE__) . "/output2.tmp";
touch($temp_filename);
$msg = $mime->saveMessage($temp_filename);
echo file_get_contents($temp_filename);

$temp_filename = dirname(__FILE__) . "/output3.tmp";
$mimePart = new Mail_mimePart('abc', array(
        'content_type' => 'text/plain',
        'encoding'     => 'quoted-printable',
));
$mimePart->encodeToFile($temp_filename);
echo file_get_contents($temp_filename);

?>
--CLEAN--

--EXPECT--
--something
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=ISO-8859-1

text
--something
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=ISO-8859-1

html
--something--
MIME-Version: 1.0
Content-Type: multipart/alternative;
 boundary="something"

--something
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=ISO-8859-1

text
--something
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=ISO-8859-1

html
--something--
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain

abc
PKu])#pp(test/Mail_Mime/tests/test_Bug_18772.phptnu[--TEST--
Bug #18772  Text/calendar message
--SKIPIF--
--FILE--
setSubject('test');

// A message with text/calendar only
$mime->setCalendarBody('VCALENDAR');

echo $mime->getMessage();
echo "\n---\n";

// A message with alternative text
$mime->setTXTBody('vcalendar');
$msg = $mime->getMessage();

echo preg_replace('/=_[0-9a-z]+/', '*', $msg);
--EXPECT--
MIME-Version: 1.0
Subject: test
Content-Type: text/calendar; charset=UTF-8; method=request
Content-Transfer-Encoding: quoted-printable

VCALENDAR
---
MIME-Version: 1.0
Subject: test
Content-Type: multipart/alternative;
 boundary="*"

--*
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=ISO-8859-1

vcalendar
--*
Content-Transfer-Encoding: quoted-printable
Content-Type: text/calendar; method=request; charset=UTF-8

VCALENDAR
--*--
PKu]a[(test/Mail_Mime/tests/class-filename.phptnu[--TEST--
Test class filename (bug #24)
--SKIPIF--

--FILE--

--EXPECT--
Include OK
PKu]ZXHww)test/Mail_Mime/tests/test_Bug_3513_3.phptnu[--TEST--
Bug #3513   Support of RFC2231 in header fields. (ISO-2022-JP)
--SKIPIF--
--FILE--
addAttachment('testfile',"text/plain", $test, FALSE, 'base64', 'attachment', 'iso-2022-jp', '');

$content = $Mime->get();
$content = str_replace("\n", '', $content);

if (preg_match('/filename([^\s]+)/i', $content, $matches)) {
    echo $matches[1];
}
?>
--EXPECT--
*=iso-2022-jp''%1B$BF|K%5C8l%1B%28B.txt;

PKu]Y'test/Mail_Mime/tests/test_Bug_GH26.phptnu[--TEST--
Bug GH-26  Backward slash is getting added in headers
--SKIPIF--
--FILE--
';
$to = <<,,t@mail.com
EOT;
$subject = "Test mime";
$mailbody = "hello world";

$mail_mime->setTxtBody($mailbody);
$mail_mime->setHTMLBody($mailbody);
$mail_mime->setSubject($subject);
$mail_mime->setFrom($from);

$body = $mail_mime->get();

$extra_headers = array();
$extra_headers["To"] = $to;

$arr_hdrs = $mail_mime->headers($extra_headers);

echo $arr_hdrs['From'] . "\n" . $arr_hdrs['To'];

--EXPECT--
"George B@@Z" 
"austin test" , , t@mail.comPKu]((*test/Mail_Mime/tests/test_Bug_10596_1.phptnu[--TEST--
Bug #10596  Incorrect handling of text and html '0' bodies
--SKIPIF--
--FILE--
setTxtBody('0');
$mime->setHTMLBody('0');
$body = $mime->get();
if ($body){
    print("OK");
}else{
    print("NO BODY FOUND");
}
--EXPECT--
OK
PKu]Qi"--(test/Mail_Mime/tests/test_Bug_11381.phptnu[--TEST--
Bug #11381  Domain name is attached to content-id, trailing greater-than sign is not removed
--SKIPIF--
--FILE--
';

require_once('Mail/mime.php');

$mime=new Mail_mime();

$body='';

$mime->setHTMLBody($body);
$mime->setFrom($from);
$mime->addHTMLImage('','image/gif', 'test.gif', false);
$msg=$mime->get();

$header = preg_match('|Content-ID: <[0-9a-fA-F]+@from.example.com>|', $msg);
if (!$header){
    print("FAIL:\n");
    print($msg);
}else{
    print("OK");
}
--EXPECT--
OK
PKu]v)test/Mail_Mime/tests/test_Bug_8541_1.phptnu[--TEST--
Bug #8541   mimePart.php line delimiter is \r
--SKIPIF--
--FILE--
setSubject('test');

$headers = $mime->headers(array('Subject' => null), true);
echo array_key_exists('Subject', $headers) ? '1' : '0';
--EXPECT--
0PKu]e;I(test/Mail_Mime/tests/test_Bug_21205.phptnu[--TEST--
Bug #21205  Handling ISO-2022-JP headers
--SKIPIF--
';
$charset = 'ISO-2022-JP';
$encoding = 'base64';
foreach ($tests as $test) {
    $test = mb_convert_encoding($test, $charset, 'UTF-8');
    print Mail_mimePart::encodeHeader("subject", $test,       $charset, $encoding) . PHP_EOL;
    print Mail_mimePart::encodeHeader("to",      $test.$addr, $charset, $encoding) . PHP_EOL;
    $test = '"' . $test . '"';
    print Mail_mimePart::encodeHeader("subject", $test,       $charset, $encoding) . PHP_EOL;
    print Mail_mimePart::encodeHeader("to",      $test.$addr, $charset, $encoding) . PHP_EOL;
}
?>
--EXPECT--
=?ISO-2022-JP?B?GyRCIiI1fkVUSVwiIhsoQg==?=
=?ISO-2022-JP?B?GyRCIiI1fkVUSVwiIhsoQg==?= 
=?ISO-2022-JP?B?GyRCIiI1fkVUSVwiIhsoQg==?=
=?ISO-2022-JP?B?GyRCIiI1fkVUSVwiIhsoQg==?= 
=?ISO-2022-JP?B?GyRCIlwiXCJcIlwbKEI=?=
=?ISO-2022-JP?B?GyRCIlwiXCJcIlwbKEI=?= 
=?ISO-2022-JP?B?GyRCIlwiXCJcIlwbKEI=?=
=?ISO-2022-JP?B?GyRCIlwiXCJcIlwbKEI=?= 
PKu]M-\(test/Mail_Mime/tests/test_Bug_17175.phptnu[--TEST--
Bug #17175  Content-Description support+ecoding
--SKIPIF--
--FILE--
setTXTBody('Test message.');
$Mime->addAttachment('test file contents', "text/plain",
    'test.txt', FALSE, 'base64', NULL, 'UTF-8', NULL, NULL, NULL, NULL,
    'desc');
$Mime->addAttachment('test file contents', "text/plain",
    'test2.txt', FALSE, 'base64', NULL, 'UTF-8', NULL, NULL, NULL, NULL,
    'test unicode żąśź');

$body = $Mime->getMessage();
preg_match_all('/Content-Description: (.*)/', $body, $matches);
foreach ($matches[1] as $value)
    echo $value."\n";
?>
--EXPECT--
desc
=?UTF-8?Q?test_unicode_=C5=BC=C4=85=C5=9B=C5=BA?=
PKu]qS*test/Mail_Mime/tests/test_Bug_10999_1.phptnu[--TEST--
Bug #10999  Bad Content-ID(cid) format
--SKIPIF--
--FILE--
';

$mime->setHTMLBody($body);
$mime->setFrom($from);
$mime->addHTMLImage('','image/gif', 'test.gif', false);
$msg=$mime->get();

$header = preg_match('|Content-ID: <[0-9a-fA-F]+@from.example.com>|', $msg);
if (!$header){
    print("FAIL:\n");
    print($msg);
}else{
    print("OK");
}
--EXPECT--
OK
PKu]RoUU(test/Mail_Mime/tests/test_Bug_20226.phptnu[--TEST--
Bug #20226  Mail_mimePart::encodeHeader() and ISO-2022-JP encoding
--SKIPIF--
--FILE--
encodeHeader('subject', $subject, 'ISO-2022-JP', 'base64');
?>
--EXPECT--
=?ISO-2022-JP?B?GyRCJT8lJCVIJWsbKEI=?=
PKu]|JJ8test/Mail_Mime/tests/sleep_wakeup_EOL-bug3488-part2.phptnu[--TEST--
Bug #3488   Sleep/Wakeup EOL Consistency - Part 2
--SKIPIF--
if (!is_readable('sleep_wakeup_data')) {
    echo "skip No data. Part 1 must run first.\n";
}
--FILE--
get();
$x = $mmData['mm']->headers();

list($h1) = explode("\n", $mmData['header']);
list($h2) = explode("\n", $x['Content-Type']);

echo ($h1 == $h2) ? "Match" : "No Match";

?>
--EXPECT--
Match
PKu]Ԣ``(test/Mail_Mime/tests/test_Bug_21255.phptnu[--TEST--
Bug #21255  Boundary gets added twice
--SKIPIF--
--FILE--
setHTMLBody('html');
$mime->setTXTBody('text');
$mime->setContentType('multipart/alternative', array('boundary' => 'something'));

$msg = $mime->getMessage();

echo substr_count($msg, 'boundary=');

?>
--EXPECT--
1
PKu]-7c77)test/Mail_Mime/tests/test_Bug_3513_2.phptnu[--TEST--
Bug #3513   Support of RFC2231 in header fields. (UTF-8)
--SKIPIF--
--FILE--
addAttachment('testfile',"text/plain", $test, FALSE, 'base64', 'attachment', 'UTF-8', 'de');

$content = $Mime->get();
$content = str_replace("\n", '', $content);

if (preg_match_all('/filename([^\s]+)/i', $content, $matches)) {
    echo implode("\n", $matches[1]);
}

--EXPECT--
*0*=UTF-8'de'S%C3%BCper%20gr%C3%B6se%20tolle%20tolle%20gr%C3%BC;
*1*=%C3%9Fe.txt;
PKu]''')test/Mail_Mime/tests/test_Bug_8386_1.phptnu[--TEST--
Bug #8386   HTML body not correctly encoded if attachments present
--SKIPIF--
--FILE--
$eol));
$encoder->setTXTBody('test');
$encoder->setHTMLBody('test');
$encoder->addAttachment('Just a test', 'application/octet-stream', 'test.txt', false);
$body = $encoder->get();
if (strpos($body, '--' . $eol . '--=')){
    print("FAILED\n");
    print("Single delimiter() between 2 parts found.\n");
    print($body);
}else{
    print("OK");
}
?>
--EXPECT--
OK
PKu]i;)test/Mail_Mime/tests/test_Bug_7561_1.phptnu[--TEST--
Bug #7561   Mail_mimePart::quotedPrintableEncode() misbehavior with mbstring overload
--INI--
mbstring.language=Neutral
mbstring.func_overload=6
mbstring.internal_encoding=UTF-8
mbstring.http_output=UTF-8
--SKIPIF--
setHTMLBody('html');
$mime->setTXTBody('text');

$body = $mime->get();
$hdrs = $mime->headers(array(
        'From'    => 'test@domain.tld',
        'Subject' => 'Subject',
        'To'      => 'to@domain.tld'
));

preg_match('/boundary="([^"]+)/', $hdrs['Content-Type'], $matches);
$boundary = $matches[1];

echo substr_count($body, "--$boundary") . "\n";

// Test headers() before get()

$mime = new Mail_mime("\r\n");
$mime->setHTMLBody('html');
$mime->setTXTBody('text');

$hdrs = $mime->headers(array(
        'From'    => 'test@domain.tld',
        'Subject' => 'Subject',
        'To'      => 'to@domain.tld'
));
$body = $mime->get();

preg_match('/boundary="([^"]+)/', $hdrs['Content-Type'], $matches);
$boundary = $matches[1];

echo substr_count($body, "--$boundary");
--EXPECT--
3
3
PKu]YcLYY(test/Mail_Mime/tests/test_Bug_16539.phptnu[--TEST--
Bug #16539  Headers longer than 998 characters
--SKIPIF--
--FILE--
 'jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com',
'Subject' => 'jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com',
);

echo $mime->txtHeaders($headers, true, true);
?>
--EXPECT--
MIME-Version: 1.0
To: jskibbie@schawk.com, jskibbie@schawk.com, jskibbie@schawk.com,
 jskibbie@schawk.com, jskibbie@schawk.com, jskibbie@schawk.com,
 jskibbie@schawk.com, jskibbie@schawk.com, jskibbie@schawk.com,
 jskibbie@schawk.com, jskibbie@schawk.com, jskibbie@schawk.com,
 jskibbie@schawk.com, jskibbie@schawk.com, jskibbie@schawk.com,
 jskibbie@schawk.com, jskibbie@schawk.com, jskibbie@schawk.com,
 jskibbie@schawk.com, jskibbie@schawk.com, jskibbie@schawk.com,
 jskibbie@schawk.com, jskibbie@schawk.com, jskibbie@schawk.com,
 jskibbie@schawk.com, jskibbie@schawk.com, jskibbie@schawk.com,
 jskibbie@schawk.com, jskibbie@schawk.com, jskibbie@schawk.com,
 jskibbie@schawk.com, jskibbie@schawk.com, jskibbie@schawk.com,
 jskibbie@schawk.com, jskibbie@schawk.com, jskibbie@schawk.com,
 jskibbie@schawk.com, jskibbie@schawk.com, jskibbie@schawk.com,
 jskibbie@schawk.com, jskibbie@schawk.com, jskibbie@schawk.com,
 jskibbie@schawk.com, jskibbie@schawk.com, jskibbie@schawk.com,
 jskibbie@schawk.com, jskibbie@schawk.com, jskibbie@schawk.com,
 jskibbie@schawk.com, jskibbie@schawk.com, jskibbie@schawk.com,
 jskibbie@schawk.com, jskibbie@schawk.com, jskibbie@schawk.com,
 jskibbie@schawk.com, jskibbie@schawk.com, jskibbie@schawk.com,
 jskibbie@schawk.com, jskibbie@schawk.com, jskibbie@schawk.com,
 jskibbie@schawk.com, jskibbie@schawk.com, jskibbie@schawk.com,
 jskibbie@schawk.com, jskibbie@schawk.com, jskibbie@schawk.com,
 jskibbie@schawk.com, jskibbie@schawk.com, jskibbie@schawk.com,
 jskibbie@schawk.com, jskibbie@schawk.com, jskibbie@schawk.com,
 jskibbie@schawk.com, jskibbie@schawk.com, jskibbie@schawk.com,
 jskibbie@schawk.com, jskibbie@schawk.com, jskibbie@schawk.com,
 jskibbie@schawk.com, jskibbie@schawk.com, jskibbie@schawk.com,
 jskibbie@schawk.com, jskibbie@schawk.com, jskibbie@schawk.com,
 jskibbie@schawk.com, jskibbie@schawk.com, jskibbie@schawk.com,
 jskibbie@schawk.com, jskibbie@schawk.com
Subject: jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.co
 m,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com,jskibbie@schawk.com
PKu](test/Mail_Mime/tests/test_Bug_21027.phptnu[--TEST--
Bug #21027  Calendar support along with attachments and html images
--SKIPIF--
--FILE--
This is HTML body.';
$icsText = 'BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//icalcreator//NONSGML iCalcreator 2.22//
METHOD:REQUEST
BEGIN:VEVENT
UID:77@localhost
DTSTAMP:20160208T170811Z
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=
 TRUE;CN=Jacob Alvarez:MAILTO:fake1@mailinator.com
CREATED:20160208T170810Z
DTSTART:20160215T180000Z
DTEND:20160215T190000Z
ORGANIZER;CN=-:MAILTO:fake2@mailinator.com
SEQUENCE:1
STATUS:CONFIRMED
SUMMARY:Prueba 69
TRANSP:OPAQUE
URL:http://localhost/event/77
END:VEVENT
END:VCALENDAR';

function printPartsStartAndEnd($body) {
    $matches  = array();
    preg_match_all('/--(=_[a-z0-9]+)--|Content-Type: ([^;\r\n]+)/', $body, $matches);
    $tab = "    ";
    foreach ($matches[0] as $match){
        if (strpos($match, '--') === false) {
            printf("%s%s\n", $tab, $match);
            if (stripos($match, "multipart")) {
                $tab .= "    ";
            }
        } else {
            $tab = substr($tab, 0, -4);
            printf("%sEnd part\n", $tab);
        }
    }
}

function printHeaderContentType($headers) {
    $headerContentType = array();
    preg_match('/([^;\r\n]+)/', $headers['Content-Type'], $headerContentType);
    printf("Content-Type: %s\n", $headerContentType[0]);
}

print "TEST: text\n";
$mime = new Mail_mime();
$mime->setTXTBody($txtBody);
$headers = $mime->headers();
$body = $mime->get();
printHeaderContentType($headers);
printPartsStartAndEnd($body);
print("\n");

print "TEST: html\n";
$mime = new Mail_mime();
$mime->setHTMLBody($htmlBody);
$headers = $mime->headers();
$body = $mime->get();
printHeaderContentType($headers);
printPartsStartAndEnd($body);
print("\n");

print "TEST: attachments\n";
$mime = new Mail_mime();
$mime->addAttachment($icsText, 'application/ics', 'invite.ics', false);
$headers = $mime->headers();
$body = $mime->get();
printHeaderContentType($headers);
printPartsStartAndEnd($body);
print("\n");

print "TEST: text + attachments\n";
$mime = new Mail_mime();
$mime->setTXTBody($txtBody);
$mime->addAttachment($icsText, 'application/ics', 'invite.ics', false);
$headers = $mime->headers();
$body = $mime->get();
printHeaderContentType($headers);
printPartsStartAndEnd($body);
print("\n");

print "TEST: html + attachments\n";
$mime = new Mail_mime();
$mime->setHTMLBody($htmlBody);
$mime->addAttachment($icsText, 'application/ics', 'invite.ics', false);
$headers = $mime->headers();
$body = $mime->get();
printHeaderContentType($headers);
printPartsStartAndEnd($body);
print("\n");

print "TEST: html + inline images\n";
$mime = new Mail_mime();
$mime->setHTMLBody($htmlBody);
$mime->addHTMLImage("aaaaaaaaaa", 'image/gif', 'image.gif', false, 'contentid');
$headers = $mime->headers();
$body = $mime->get();
printHeaderContentType($headers);
printPartsStartAndEnd($body);
print("\n");

print("TEST: txt, html and attachment\n");
$mime = new Mail_mime();
$mime->setTXTBody($txtBody);
$mime->setHTMLBody($htmlBody);
$mime->addAttachment("test", 'application/octet-stream', 'attachment', false);
$headers = $mime->headers();
$body = $mime->get();
printHeaderContentType($headers);
printPartsStartAndEnd($body);
print("\n");

print "TEST: calendar\n";
$mime = new Mail_mime();
$mime->setCalendarBody($icsText);
$headers = $mime->headers();
$body = $mime->get();
printHeaderContentType($headers);
printPartsStartAndEnd($body);
print("\n");

print "TEST: txt + calendar\n";
$mime->setTXTBody($txtBody);
$headers = $mime->headers();
$body = $mime->get();
printHeaderContentType($headers);
printPartsStartAndEnd($body);
print("\n");

print "TEST: txt, html, calendar\n";
$mime = new Mail_mime();
$mime->setTXTBody($txtBody);
$mime->setHTMLBody($htmlBody);
$mime->setCalendarBody($icsText);
$headers = $mime->headers();
$body = $mime->get();
printHeaderContentType($headers);
printPartsStartAndEnd($body);
print("\n");

print "TEST: txt, html + html images, and calendar\n";
$mime = new Mail_mime();
$mime->setTXTBody($txtBody);
$mime->setHTMLBody($htmlBody);
$mime->addHTMLImage('testimage', 'image/gif', "bus.gif", false);
$mime->setCalendarBody($icsText);
$headers = $mime->headers();
$body = $mime->get();
printHeaderContentType($headers);
printPartsStartAndEnd($body);
print("\n");

print("TEST: txt, html, calendar and attachment\n");
$mime = new Mail_mime();
$mime->setTXTBody($txtBody);
$mime->setHTMLBody($htmlBody);
$mime->setCalendarBody($icsText);
$mime->addAttachment("test", 'application/octet-stream', 'attachment', false);
$headers = $mime->headers();
$body = $mime->get();
printHeaderContentType($headers);
printPartsStartAndEnd($body);
print("\n");

print "TEST: txt, html + html images, calendar, and attachment\n";
$mime = new Mail_mime();
$mime->setTXTBody($txtBody);
$mime->setHTMLBody($htmlBody);
$mime->addHTMLImage('testimage', 'image/gif', "bus.gif", false);
$mime->setCalendarBody($icsText);
$mime->addAttachment($icsText, 'application/ics', 'invite.ics', false);
$headers = $mime->headers();
$body = $mime->get();
printHeaderContentType($headers);
printPartsStartAndEnd($body);
print("\n");
?>
--EXPECT--
TEST: text
Content-Type: text/plain

TEST: html
Content-Type: text/html

TEST: attachments
Content-Type: multipart/mixed
    Content-Type: application/ics
End part

TEST: text + attachments
Content-Type: multipart/mixed
    Content-Type: text/plain
    Content-Type: application/ics
End part

TEST: html + attachments
Content-Type: multipart/mixed
    Content-Type: text/html
    Content-Type: application/ics
End part

TEST: html + inline images
Content-Type: multipart/related
    Content-Type: text/html
    Content-Type: image/gif
End part

TEST: txt, html and attachment
Content-Type: multipart/mixed
    Content-Type: multipart/alternative
        Content-Type: text/plain
        Content-Type: text/html
    End part
    Content-Type: application/octet-stream
End part

TEST: calendar
Content-Type: text/calendar

TEST: txt + calendar
Content-Type: multipart/alternative
    Content-Type: text/plain
    Content-Type: text/calendar
End part

TEST: txt, html, calendar
Content-Type: multipart/alternative
    Content-Type: text/plain
    Content-Type: text/html
    Content-Type: text/calendar
End part

TEST: txt, html + html images, and calendar
Content-Type: multipart/alternative
    Content-Type: text/plain
    Content-Type: multipart/related
        Content-Type: text/html
        Content-Type: image/gif
    End part
    Content-Type: text/calendar
End part

TEST: txt, html, calendar and attachment
Content-Type: multipart/mixed
    Content-Type: multipart/alternative
        Content-Type: text/plain
        Content-Type: text/html
        Content-Type: text/calendar
    End part
    Content-Type: application/octet-stream
End part

TEST: txt, html + html images, calendar, and attachment
Content-Type: multipart/mixed
    Content-Type: multipart/alternative
        Content-Type: text/plain
        Content-Type: multipart/related
            Content-Type: text/html
            Content-Type: image/gif
        End part
        Content-Type: text/calendar
    End part
    Content-Type: application/ics
End part
PKu]Yak!!8test/Mail_Mime/tests/sleep_wakeup_EOL-bug3488-part1.phptnu[--TEST--
Bug #3488   Sleep/Wakeup EOL Consistency - Part 1
--SKIPIF--
--FILE--
setHTMLBody('');
$mm->setTxtBody('Blah blah');

if (version_compare(phpversion(), "5.0.0", '<')) {
    $mmCopy = $mm;
} else {
    $mmCopy = clone($mm);
}

$mm->get();
$x = $mm->headers();

$smm = serialize(array('mm' => $mmCopy, 'header' => $x['Content-Type']));
$fp = fopen('sleep_wakeup_data', 'w');
fwrite($fp, $smm);
fclose($fp);

echo "Data written";
?>
--EXPECT--
Data written
PKu]ّB

*test/Mail_Mime/tests/qp_encoding_test.phptnu[--TEST--
qp comprehensive test
--SKIPIF--
--FILE--
 '7bit',
    'html_encoding' => '7bit',
);
$mime = new Mail_mime($params);
$mime->setTXTBody("ż");
$mime->setHTMLBody("z");
$body = $mime->getMessage();

preg_match_all('/Content-Transfer-Encoding: (.*)/', $body, $m);
echo trim($m[1][0])."\n".trim($m[1][1]);

?>
--EXPECT--
quoted-printable
7bit
PKu][b3test/Mail_Mime/tests/content_transfer_encoding.phptnu[--TEST--
Test empty Content-Transfer-Encoding on multipart messages
--SKIPIF--
--FILE--
setParam('text_encoding', 'quoted-printable');
$mime->setParam('html_encoding', 'quoted-printable');
$mime->setParam('head_encoding', 'quoted-printable');

// This specific order used to set Content-Transfer-Encoding: quoted-printable
// which is invalid according to RFC 2045 on multipart messages
$mime->setTXTBody('text');
$mime->headers(array('From' => 'from@domain.tld'));
$mime->addAttachment('file.pdf', 'application/pdf', 'file.pdf', false, 'base64', 'inline');
echo $mime->txtHeaders();
list ($header, $body) = explode("\r\n\r\n", $mime->getMessage());
echo $header;
?>
--EXPECTF--
MIME-Version: 1.0
From: from@domain.tld
Content-Type: multipart/mixed;
 boundary="=_%x"
MIME-Version: 1.0
From: from@domain.tld
Content-Type: multipart/mixed;
 boundary="=_%x"
PKu]᠗""/test/Mail_Mime/tests/headers_with_mbstring.phptnu[--TEST--
Multi-test for headers encoding using base64 and quoted-printable
--SKIPIF--

--FILE--
'),
array('From', 'adresse@adresse.de'),
array('From', 'Frank Do '),
array('To', 'Frank Do , James Clark '),
array('From', '"Frank Do" '),
array('Cc', '"Frank Do" , "James Clark" '),
array('Cc', ' , "Kuśmiderski Jan Krzysztof Janusz Długa nazwa" '),
array('From', '"adresse@adresse.de" '),
array('From', 'adresse@adresse.de '),
array('From', '"German Umlauts öäü" '),
array('Subject', 'German Umlauts öäü '),
array('Subject', 'Short ASCII subject'),
array('Subject', 'Long ASCII subject - multiline space separated words - too long for one line'),
array('Subject', 'Short Unicode ż subject'),
array('Subject', 'Long Unicode subject - zażółć gęślą jaźń - too long for one line'),
array('References', '  <4b2e87ac$1@news.home.net.pl> '),
array('To', '"Frank Do" ,, "James Clark" '),
array('To', '"Frank \\" \\\\Do" '),
array('To', 'Frank " \\Do '),
array('Subject', "A REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY /REALLY/ LONG test"),
array('Subject', "TEST Süper gröse tolle grüße von mir Süper gröse tolle grüße von mir Süper gröse tolle grüße von mir Süper gröse tolle grüße von mir Süper gröse tolle grüße von mir Süper gröse tolle grüße von mir Süper gröse tolle grüße von mir Süper gröse tolle grüße von mir Süper gröse tolle grüße von mir!!!?"),
array('Subject', "Update: Microsoft Windows-Tool zum Entfernen bösartiger Software 3.6"),
array('From', "test@nàme "),
array('From', "Test <\"test test\"@domain.com>"),
array('From', "\"test test\"@domain.com"),
array('From', "<\"test test\"@domain.com>"),
array('From', "Doe"),
array('From', "\"John Doe\""),
array('Mail-Reply-To', 'adresse@adresse.de '),
array('Mail-Reply-To', '"öäü" '),
array('Subject', mb_convert_encoding('㈱山﨑工業', 'ISO-2022-JP-MS', 'UTF-8'), 'ISO-2022-JP'),
);

$i = 1;
foreach ($headers as $header) {
    $charset = isset($header[2]) ? $header[2] : 'UTF-8';
    $hdr = $mime->encodeHeader($header[0], $header[1], $charset, 'base64');
    printf("[%02d] %s: %s\n", $i, $header[0], $hdr);
    $hdr = $mime->encodeHeader($header[0], $header[1], $charset, 'quoted-printable');
    printf("[%02d] %s: %s\n", $i, $header[0], $hdr);
    $i++;
}
?>
--EXPECT--
[01] From: 
[01] From: 
[02] From: adresse@adresse.de
[02] From: adresse@adresse.de
[03] From: Frank Do 
[03] From: Frank Do 
[04] To: Frank Do , James Clark 
[04] To: Frank Do , James Clark 
[05] From: "Frank Do" 
[05] From: "Frank Do" 
[06] Cc: "Frank Do" , "James Clark" 
[06] Cc: "Frank Do" , "James Clark" 
[07] Cc: , =?UTF-8?B?S3XFm21pZGVyc2tpIEphbiBLcnp5c3p0b2Yg?=
 =?UTF-8?B?SmFudXN6IETFgnVnYSBuYXp3YQ==?= 
[07] Cc: , =?UTF-8?Q?Ku=C5=9Bmiderski_Jan_Krzysztof_Janusz?=
 =?UTF-8?Q?_D=C5=82uga_nazwa?= 
[08] From: "adresse@adresse.de" 
[08] From: "adresse@adresse.de" 
[09] From: "adresse@adresse.de" 
[09] From: "adresse@adresse.de" 
[10] From: =?UTF-8?B?R2VybWFuIFVtbGF1dHMgw7bDpMO8?= 
[10] From: =?UTF-8?Q?German_Umlauts_=C3=B6=C3=A4=C3=BC?= 
[11] Subject: =?UTF-8?B?R2VybWFuIFVtbGF1dHMgw7bDpMO8IDxhZHJlc3NlQGFkcmVzc2Uu?=
 =?UTF-8?B?ZGU+?=
[11] Subject: =?UTF-8?Q?German_Umlauts_=C3=B6=C3=A4=C3=BC_=3Cadresse=40adresse?=
 =?UTF-8?Q?=2Ede=3E?=
[12] Subject: Short ASCII subject
[12] Subject: Short ASCII subject
[13] Subject: Long ASCII subject - multiline space separated words - too long for
 one line
[13] Subject: Long ASCII subject - multiline space separated words - too long for
 one line
[14] Subject: =?UTF-8?B?U2hvcnQgVW5pY29kZSDFvCBzdWJqZWN0?=
[14] Subject: =?UTF-8?Q?Short_Unicode_=C5=BC_subject?=
[15] Subject: =?UTF-8?B?TG9uZyBVbmljb2RlIHN1YmplY3QgLSB6YcW8w7PFgsSHIGfEmcWb?=
 =?UTF-8?B?bMSFIGphxbrFhCAtIHRvbyBsb25nIGZvciBvbmUgbGluZQ==?=
[15] Subject: =?UTF-8?Q?Long_Unicode_subject_-_za=C5=BC=C3=B3=C5=82=C4=87_g?=
 =?UTF-8?Q?=C4=99=C5=9Bl=C4=85_ja=C5=BA=C5=84_-_too_long_for_one_line?=
[16] References: 
 <4b2e87ac$1@news.home.net.pl> 
[16] References: 
 <4b2e87ac$1@news.home.net.pl> 
[17] To: "Frank Do" , "James Clark" 
[17] To: "Frank Do" , "James Clark" 
[18] To: "Frank \" \\Do" 
[18] To: "Frank \" \\Do" 
[19] To: "Frank \" \\Do" 
[19] To: "Frank \" \\Do" 
[20] Subject: A REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY
 REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY
 REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY
 REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY /REALLY/ LONG test
[20] Subject: A REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY
 REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY
 REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY
 REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALLY /REALLY/ LONG test
[21] Subject: =?UTF-8?B?VEVTVCBTw7xwZXIgZ3LDtnNlIHRvbGxlIGdyw7zDn2Ugdm9uIG1p?=
 =?UTF-8?B?ciBTw7xwZXIgZ3LDtnNlIHRvbGxlIGdyw7zDn2Ugdm9uIG1pciBTw7xwZXIg?=
 =?UTF-8?B?Z3LDtnNlIHRvbGxlIGdyw7zDn2Ugdm9uIG1pciBTw7xwZXIgZ3LDtnNlIHRv?=
 =?UTF-8?B?bGxlIGdyw7zDn2Ugdm9uIG1pciBTw7xwZXIgZ3LDtnNlIHRvbGxlIGdyw7w=?=
 =?UTF-8?B?w59lIHZvbiBtaXIgU8O8cGVyIGdyw7ZzZSB0b2xsZSBncsO8w59lIHZvbiBt?=
 =?UTF-8?B?aXIgU8O8cGVyIGdyw7ZzZSB0b2xsZSBncsO8w59lIHZvbiBtaXIgU8O8cGVy?=
 =?UTF-8?B?IGdyw7ZzZSB0b2xsZSBncsO8w59lIHZvbiBtaXIgU8O8cGVyIGdyw7ZzZSB0?=
 =?UTF-8?B?b2xsZSBncsO8w59lIHZvbiBtaXIhISE/?=
[21] Subject: =?UTF-8?Q?TEST_S=C3=BCper_gr=C3=B6se_tolle_gr=C3=BC=C3=9Fe_von_m?=
 =?UTF-8?Q?ir_S=C3=BCper_gr=C3=B6se_tolle_gr=C3=BC=C3=9Fe_von_mir_S=C3=BCp?=
 =?UTF-8?Q?er_gr=C3=B6se_tolle_gr=C3=BC=C3=9Fe_von_mir_S=C3=BCper_gr=C3=B6?=
 =?UTF-8?Q?se_tolle_gr=C3=BC=C3=9Fe_von_mir_S=C3=BCper_gr=C3=B6se_tolle_gr?=
 =?UTF-8?Q?=C3=BC=C3=9Fe_von_mir_S=C3=BCper_gr=C3=B6se_tolle_gr=C3=BC?=
 =?UTF-8?Q?=C3=9Fe_von_mir_S=C3=BCper_gr=C3=B6se_tolle_gr=C3=BC=C3=9Fe_von?=
 =?UTF-8?Q?_mir_S=C3=BCper_gr=C3=B6se_tolle_gr=C3=BC=C3=9Fe_von_mir_S?=
 =?UTF-8?Q?=C3=BCper_gr=C3=B6se_tolle_gr=C3=BC=C3=9Fe_von_mir!!!=3F?=
[22] Subject: =?UTF-8?B?VXBkYXRlOiBNaWNyb3NvZnQgV2luZG93cy1Ub29sIHp1bSBFbnRm?=
 =?UTF-8?B?ZXJuZW4gYsO2c2FydGlnZXIgU29mdHdhcmUgMy42?=
[22] Subject: =?UTF-8?Q?Update=3A_Microsoft_Windows-Tool_zum_Entfernen_b=C3=B6?=
 =?UTF-8?Q?sartiger_Software_3=2E6?=
[23] From: =?UTF-8?B?dGVzdEBuw6BtZQ==?= 
[23] From: =?UTF-8?Q?test=40n=C3=A0me?= 
[24] From: Test <"test test"@domain.com>
[24] From: Test <"test test"@domain.com>
[25] From: "test test"@domain.com
[25] From: "test test"@domain.com
[26] From: <"test test"@domain.com>
[26] From: <"test test"@domain.com>
[27] From: Doe 
[27] From: Doe 
[28] From: "John Doe" 
[28] From: "John Doe" 
[29] Mail-Reply-To: "adresse@adresse.de" 
[29] Mail-Reply-To: "adresse@adresse.de" 
[30] Mail-Reply-To: =?UTF-8?B?w7bDpMO8?= 
[30] Mail-Reply-To: =?UTF-8?Q?=C3=B6=C3=A4=C3=BC?= 
[31] Subject: =?ISO-2022-JP?B?GyRCLWo7M3l1OSk2SBsoQg==?=
[31] Subject: =?ISO-2022-JP?Q?=24B-j=28B=24B=3B3=28B=24Byu=28B?=
 =?ISO-2022-JP?Q?=24B9=29=28B=24B6H=28B?=
PKu])test/Console_Getopt/tests/001-getopt.phptnu[--TEST--
Console_Getopt
--FILE--
 $d) {
        if ($i++ > 0) {
            print ", ";
        }
        print $d[0] . '=' . $d[1];
    }
    print "\n";
    print "params: " . implode(", ", $non_opts) . "\n";
    print "\n";
}

test("-abc", "abc");
test("-abc foo", "abc");
test("-abc foo", "abc:");
test("-abc foo bar gazonk", "abc");
test("-abc foo bar gazonk", "abc:");
test("-a -b -c", "abc");
test("-a -b -c", "abc:");
test("-abc", "ab:c");
test("-abc foo -bar gazonk", "abc");
?>
--EXPECT--
options: a=, b=, c=
params: 

options: a=, b=, c=
params: foo

options: a=, b=, c=foo
params: 

options: a=, b=, c=
params: foo, bar, gazonk

options: a=, b=, c=foo
params: bar, gazonk

options: a=, b=, c=
params: 

Console_Getopt: option requires an argument --c

options: a=, b=c
params: 

options: a=, b=, c=
params: foo, -bar, gazonk
PKu]|EE'test/Console_Getopt/tests/bug13140.phptnu[--TEST--
Console_Getopt [bug 13140]
--SKIPIF--
--FILE--
getopt2($cg->readPHPArgv(), 't', array('test'), true));
print_r($cg->getopt2($cg->readPHPArgv(), 'bar', array('foo'), true));
?>
--EXPECT--
Array
(
    [0] => Array
        (
            [0] => Array
                (
                    [0] => --test
                    [1] => 
                )

        )

    [1] => Array
        (
            [0] => thisshouldbehere
        )

)
Array
(
    [0] => Array
        (
            [0] => Array
                (
                    [0] => --foo
                    [1] => 
                )

            [1] => Array
                (
                    [0] => b
                    [1] => 
                )

            [2] => Array
                (
                    [0] => a
                    [1] => 
                )

            [3] => Array
                (
                    [0] => r
                    [1] => 
                )

            [4] => Array
                (
                    [0] => r
                    [1] => 
                )

        )

    [1] => Array
        (
            [0] => thisshouldbehere
        )

)
PKu]'test/Console_Getopt/tests/bug11068.phptnu[--TEST--
Console_Getopt [bug 11068]
--SKIPIF--
--FILE--
getMessage()."\n";
	echo 'FATAL';
	exit;
}

print_r($ret);
?>
--EXPECT--
Array
(
    [0] => Array
        (
            [0] => Array
                (
                    [0] => f
                    [1] => jjohnston@mail.com
                )

            [1] => Array
                (
                    [0] => --to
                    [1] => hi
                )

        )

    [1] => Array
        (
            [0] => -
        )

)PKu]'test/Console_Getopt/tests/bug10557.phptnu[--TEST--
Console_Getopt [bug 10557]
--SKIPIF--
--FILE--
getMessage()."\n";
	echo 'FATAL';
	exit;
}

print_r($ret);
?>
--EXPECT--
Console_Getopt: option requires an argument --to
FATALPKu]*Wtest/Net_SMTP/tests/basic.phptnu[--TEST--
Net_SMTP: Basic Functionality
--SKIPIF--
connect())) {
    die($e->getMessage() . "\n");
}

if (PEAR::isError($e = $smtp->auth(TEST_AUTH_USER, TEST_AUTH_PASS))) {
    die("Authentication failure\n");
}

if (PEAR::isError($smtp->mailFrom(TEST_FROM))) {
    die('Unable to set sender to <' . TEST_FROM . ">\n");
}

if (PEAR::isError($res = $smtp->rcptTo(TEST_TO))) {
    die('Unable to add recipient <' . TEST_TO . '>: ' .
        $res->getMessage() . "\n");
}

$headers = 'Subject: ' . TEST_SUBJECT;
if (PEAR::isError($smtp->data(TEST_BODY, $headers))) {
    die("Unable to send data\n");
}

$smtp->disconnect();

echo 'Success!';

--EXPECT--
Success!
PKu]6#test/Net_SMTP/tests/config.php.distnu[ "\r\n",
    "\r\n"             => "\r\n",
    "\nxx"             => "\r\nxx",
    "xx\n"             => "xx\r\n",
    "xx\nxx"           => "xx\r\nxx",
    "\n\nxx"           => "\r\n\r\nxx",
    "xx\n\nxx"         => "xx\r\n\r\nxx",
    "xx\n\n"           => "xx\r\n\r\n",
    "\r\nxx"           => "\r\nxx",
    "xx\r\n"           => "xx\r\n",
    "xx\r\nxx"         => "xx\r\nxx",
    "\r\n\r\nxx"       => "\r\n\r\nxx",
    "xx\r\n\r\nxx"     => "xx\r\n\r\nxx",
    "xx\r\n\r\n"       => "xx\r\n\r\n",
    "\r\n\nxx"         => "\r\n\r\nxx",
    "\n\r\nxx"         => "\r\n\r\nxx",
    "xx\r\n\nxx"       => "xx\r\n\r\nxx",
    "xx\n\r\nxx"       => "xx\r\n\r\nxx",
    "xx\r\n\n"         => "xx\r\n\r\n",
    "xx\n\r\n"         => "xx\r\n\r\n",
    "\r"               => "\r\n",
    "\rxx"             => "\r\nxx",
    "xx\rxx"           => "xx\r\nxx",
    "xx\r"             => "xx\r\n",
    "\r\r"             => "\r\n\r\n",
    "\r\rxx"           => "\r\n\r\nxx",
    "xx\r\rxx"         => "xx\r\n\r\nxx",
    "xx\r\r"           => "xx\r\n\r\n",
    "xx\rxx\nxx\r\nxx" => "xx\r\nxx\r\nxx\r\nxx",
    "\r\r\n\n"         => "\r\n\r\n\r\n",

    /* Dots */
    "."                 => "..",
    "xxx\n."            => "xxx\r\n..",
    "xxx\n.\nxxx"       => "xxx\r\n..\r\nxxx",
    "xxx.\n.xxx"        => "xxx.\r\n..xxx",
);

function literal($x)
{
    return str_replace(array("\r", "\n"), array('\r', '\n'), $x);
}

$smtp = new Net_SMTP();
$error = false;
foreach ($tests as $input => $expected) {
    $output = $input;
    $smtp->quotedata($output);
    if ($output != $expected) {
        printf("Error: '%s' => '%s' (expected: '%s')",
            literal($input), literal($output), literal($expected));
        $error = true;
    }
}

if (!$error) {
    echo "success\n";
}

--EXPECT--
success
PKu]<ȸB!!test/Net_SMTP/tests/auth.phptnu[--TEST--
Net_SMTP: SMTP Authentication
--SKIPIF--
connect())) {
	die($e->getMessage() . "\n");
}

if (PEAR::isError($e = $smtp->auth(TEST_AUTH_USER, TEST_AUTH_PASS))) {
	die("Authentication failure\n");
}

$smtp->disconnect();

echo 'Success!';

--EXPECT--
Success!
PKu]TT*test/XML_Util/tests/CreateCommentTests.phpnu[";
        $this->assertEquals($expected, XML_Util::createComment($original));
    }
}
PKu]>M$test/XML_Util/tests/Bug4950Tests.phpnu[ here!";
        $namespaceUrl = null;
        $expected = " here!]]>";
        $result = XML_Util::createTag($qname, $attributes, $content, $namespaceUrl, XML_UTIL_CDATA_SECTION);
        $this->assertEquals($expected, $result, "Failed bugcheck.");
    }
}
PKu]zt,test/XML_Util/tests/ReverseEntitiesTests.phpnu[.";
        $this->assertEquals($expected, XML_Util::reverseEntities($this->getSimpleData()));
    }

    /**
     * @covers XML_Util::reverseEntities()
     */
    public function testReverseEntitiesForSimpleDataWithInvalidOptionReturnsOriginalData()
    {
        $expected = "This string contains < & >.";
        $this->assertEquals($expected, XML_Util::reverseEntities($this->getSimpleData(), 'INVALID_OPTION'));
    }

    /**
     * @covers XML_Util::reverseEntities()
     */
    public function testReverseEntitiesForSimpleDataWithEntitiesXml()
    {
        $expected = "This string contains < & >.";
        $this->assertEquals($expected, XML_Util::reverseEntities($this->getSimpleData(), XML_UTIL_ENTITIES_XML));
    }

    /**
     * @covers XML_Util::reverseEntities()
     */
    public function testReverseEntitiesForSimpleDataWithEntitiesXmlAndEncoding()
    {
        $encoding = "UTF-8";
        $expected = "This string contains < & >.";
        $this->assertEquals($expected, XML_Util::reverseEntities($this->getSimpleData(), XML_UTIL_ENTITIES_XML), $encoding);
    }

    /**
     * @covers XML_Util::reverseEntities()
     */
    public function testReverseEntitiesForUtf8DataWithEntitiesXmlAndEncoding()
    {
        $encoding = "UTF-8";
        $expected = "This data contains special chars like <, >, & and \" as well as ä, ö, ß, à and ê";
        $this->assertEquals($expected, XML_Util::reverseEntities($this->getUtf8Data(), XML_UTIL_ENTITIES_XML), $encoding);
    }

    /**
     * @covers XML_Util::reverseEntities()
     */
    public function testReverseEntitiesForSimpleDataWithEntitiesXmlRequired()
    {
        $expected = "This string contains < & >.";
        $this->assertEquals($expected, XML_Util::reverseEntities($this->getSimpleData(), XML_UTIL_ENTITIES_XML_REQUIRED));
    }

    /**
     * @covers XML_Util::reverseEntities()
     */
    public function testReverseEntitiesForSimpleDataWithEntitiesXmlRequiredAndEncoding()
    {
        $encoding = "UTF-8";
        $expected = "This string contains < & >.";
        $this->assertEquals($expected, XML_Util::reverseEntities($this->getSimpleData(), XML_UTIL_ENTITIES_XML_REQUIRED, $encoding));
    }

    /**
     * @covers XML_Util::reverseEntities()
     */
    public function testReverseEntitiesForUtf8DataWithEntitiesXmlRequiredAndEncoding()
    {
        $encoding = "UTF-8";
        $expected = "This data contains special chars like <, >, & and \" as well as ä, ö, ß, à and ê";
        $this->assertEquals($expected, XML_Util::reverseEntities($this->getUtf8Data(), XML_UTIL_ENTITIES_XML_REQUIRED, $encoding));
    }

    /**
     * @covers XML_Util::reverseEntities()
     */
    public function testReverseEntitiesForSimpleDataWithEntitiesHtml()
    {
        $expected = "This string contains < & >.";
        $this->assertEquals($expected, XML_Util::reverseEntities($this->getSimpleData(), XML_UTIL_ENTITIES_HTML));
    }

    /**
     * @covers XML_Util::reverseEntities()
     */
    public function testReverseEntitiesForSimpleDataWithEntitiesHtmlAndEncoding()
    {
        $encoding = "UTF-8";
        $expected = "This string contains < & >.";
        $this->assertEquals($expected, XML_Util::reverseEntities($this->getSimpleData(), XML_UTIL_ENTITIES_HTML, $encoding));
    }

    /**
     * @covers XML_Util::reverseEntities()
     */
    public function testReverseEntitiesForUtf8DataWithEntitiesHtmlAndEncoding()
    {
        $encoding = "UTF-8";
        $expected = "This data contains special chars like <, >, & and \" as well as ä, ö, ß, à and ê";
        $this->assertEquals($expected, XML_Util::reverseEntities($this->getUtf8Data(), XML_UTIL_ENTITIES_HTML, $encoding));
    }
}
PKu]C,test/XML_Util/tests/ReplaceEntitiesTests.phpnu[.';
    }

    protected function getUtf8Data()
    {
        return 'This data contains special chars like <, >, & and " as well as ä, ö, ß, à and ê';
    }

    /**
     * @covers XML_Util::replaceEntities()
     */
    public function testReplaceEntitiesForSimpleData()
    {
        $expected = "This string contains < & >.";
        $this->assertEquals($expected, XML_Util::replaceEntities($this->getSimpleData()));
    }

    /**
     * @covers XML_Util::replaceEntities()
     */
    public function testReplaceEntitiesForSimpleDataWithInvalidOptionReturnsOriginalData()
    {
        $expected = "This string contains < & >.";
        $this->assertEquals($expected, XML_Util::replaceEntities($this->getSimpleData(), 'INVALID_OPTION'));
    }

    /**
     * @covers XML_Util::replaceEntities()
     */
    public function testReplaceEntitiesForSimpleDataWithEntitiesXml()
    {
        $expected = "This string contains < & >.";
        $this->assertEquals($expected, XML_Util::replaceEntities($this->getSimpleData(), XML_UTIL_ENTITIES_XML));
    }

    /**
     * @covers XML_Util::replaceEntities()
     */
    public function testReplaceEntitiesForSimpleDataWithEntitiesXmlAndEncoding()
    {
        $encoding = "UTF-8";
        $expected = "This string contains < & >.";
        $this->assertEquals($expected, XML_Util::replaceEntities($this->getSimpleData(), XML_UTIL_ENTITIES_XML, $encoding));
    }

    /**
     * @covers XML_Util::replaceEntities()
     */
    public function testReplaceEntitiesForUtf8DataWithEntitiesXmlAndEncoding()
    {
        $encoding = "UTF-8";
        $expected = "This data contains special chars like <, >, & and " as well as ä, ö, ß, à and ê";
        $this->assertEquals($expected, XML_Util::replaceEntities($this->getUtf8Data(), XML_UTIL_ENTITIES_XML, $encoding));
    }

    /**
     * @covers XML_Util::replaceEntities()
     */
    public function testReplaceEntitiesForSimpleDataWithEntitiesXmlRequired()
    {
        $expected = "This string contains < & >.";
        $this->assertEquals($expected, XML_Util::replaceEntities($this->getSimpleData(), XML_UTIL_ENTITIES_XML_REQUIRED));
    }

    /**
     * @covers XML_Util::replaceEntities()
     */
    public function testReplaceEntitiesForSimpleDataWithEntitiesXmlRequiredAndEncoding()
    {
        $encoding = "UTF-8";
        $expected = "This string contains < & >.";
        $this->assertEquals($expected, XML_Util::replaceEntities($this->getSimpleData(), XML_UTIL_ENTITIES_XML_REQUIRED, $encoding));
    }

    /**
     * @covers XML_Util::replaceEntities()
     */
    public function testReplaceEntitiesForUtf8DataWithEntitiesXmlRequiredAndEncoding()
    {
        $encoding = "UTF-8";
        $expected = "This data contains special chars like <, >, & and " as well as ä, ö, ß, à and ê";
        $this->assertEquals($expected, XML_Util::replaceEntities($this->getUtf8Data(), XML_UTIL_ENTITIES_XML_REQUIRED, $encoding));
    }

    /**
     * @covers XML_Util::replaceEntities()
     */
    public function testReplaceEntitiesForSimpleDataWithEntitiesHtml()
    {
        $expected = "This string contains < & >.";
        $this->assertEquals($expected, XML_Util::replaceEntities($this->getSimpleData(), XML_UTIL_ENTITIES_HTML));
    }

    /**
     * @covers XML_Util::replaceEntities()
     */
    public function testReplaceEntitiesForSimpleDataWithEntitiesHtmlAndEncoding()
    {
        $encoding = "UTF-8";
        $expected = "This string contains < & >.";
        $this->assertEquals($expected, XML_Util::replaceEntities($this->getSimpleData(), XML_UTIL_ENTITIES_HTML, $encoding));
    }

    /**
     * @covers XML_Util::replaceEntities()
     */
    public function testReplaceEntitiesForUtf8DataWithEntitiesHtmlAndEncoding()
    {
        $encoding = "UTF-8";
        $expected = "This data contains special chars like <, >, & and " as well as ä, ö, ß, à and ê";
        $this->assertEquals($expected, XML_Util::replaceEntities($this->getUtf8Data(), XML_UTIL_ENTITIES_HTML, $encoding));
    }
}
PKu]Yq%test/XML_Util/tests/Bug21184Tests.phpnu[one';
        $this->assertEquals($xml, XML_Util::collapseEmptyTags($xml, XML_UTIL_COLLAPSE_ALL));
    }
}
PKu]یu'test/XML_Util/tests/ApiVersionTests.phpnu[assertEquals('1.4', XML_Util::apiVersion());
    }
}PKu]e>44/test/XML_Util/tests/CreateTagFromArrayTests.phpnu[ "foo:bar",
        );
        $expected = "";
        $this->assertEquals($expected, XML_Util::createTagFromArray($original));
    }

    /**
     * @covers XML_Util::createTagFromArray()
     */
    public function testCreateTagFromArrayWithQnameAndNamespace()
    {
        $original = array(
            "qname" => "foo:bar",
            "namespaceUri" => "http://foo.com",
        );
        $expected = "";
        $this->assertEquals($expected, XML_Util::createTagFromArray($original));
    }

    /**
     * @covers XML_Util::createTagFromArray()
     */
    public function testCreateTagFromArrayWithQnameAndNamespaceAndAttributes()
    {
        $original = array(
            "qname" => "foo:bar",
            "namespaceUri" => "http://foo.com",
            "attributes"   => array( "key" => "value", "argh" => "fruit&vegetable" ),
        );
        $expected = "";
        $this->assertEquals($expected, XML_Util::createTagFromArray($original));
    }

    /**
     * @covers XML_Util::createTagFromArray()
     */
    public function testCreateTagFromArrayWithQnameAndNamespaceAndAttributesAndContent()
    {
        $original = array(
            "qname" => "foo:bar",
            "namespaceUri" => "http://foo.com",
            "attributes"   => array( "key" => "value", "argh" => "fruit&vegetable" ),
            "content"      => "I'm inside the tag",
        );
        $expected = "I'm inside the tag";
        $this->assertEquals($expected, XML_Util::createTagFromArray($original));
    }

    /**
     * @covers XML_Util::createTagFromArray()
     */
    public function testCreateTagFromArrayWithQnameAndAttributesAndContent()
    {
        $original = array(
            "qname" => "foo:bar",
            "attributes"   => array( "key" => "value", "argh" => "fruit&vegetable" ),
            "content"      => "I'm inside the tag",
        );
        $expected = "I'm inside the tag";
        $this->assertEquals($expected, XML_Util::createTagFromArray($original));
    }

    /**
     * @covers XML_Util::createTagFromArray()
     */
    public function testCreateTagFromArrayWithQnameAndNamespaceAndContent()
    {
        $original = array(
            "qname" => "foo:bar",
            "namespaceUri" => "http://foo.com",
            "content"      => "I'm inside the tag",
        );
        $expected = "I'm inside the tag";
        $this->assertEquals($expected, XML_Util::createTagFromArray($original));
    }

    /**
     * @covers XML_Util::createTagFromArray()
     */
    public function testCreateTagFromArrayWithQnameAndNamespaceAndAttributesAndContentWithEntitiesNone()
    {
        $original = array(
            "qname" => "foo:bar",
            "namespaceUri" => "http://foo.com",
            "attributes"   => array( "key" => "value", "argh" => "fruit&vegetable" ),
            "content"      => "I'm inside the tag",
        );
        $expected = "I'm inside the tag";
        $this->assertEquals($expected, XML_Util::createTagFromArray($original, XML_UTIL_ENTITIES_NONE));
    }

    /**
     * @covers XML_Util::createTagFromArray()
     */
    public function testCreateTagFromArrayWithQnameAndNamespaceAndAttributesAndContentWithReplaceEntities()
    {
        $original = array(
            "qname" => "foo:bar",
            "namespaceUri" => "http://foo.com",
            "attributes"   => array( "key" => "value", "argh" => "fruit&vegetable" ),
            "content"      => "I'm inside the tag",
        );
        $expected = "I'm inside the tag";
        $this->assertEquals($expected, XML_Util::createTagFromArray($original, XML_UTIL_REPLACE_ENTITIES));
    }

    /**
     * @covers XML_Util::createTagFromArray()
     */
    public function testCreateTagFromArrayWithQnameAndNamespaceAndAttributesAndContentWithReplaceEntitiesAndMultilineFalse()
    {
        $original = array(
            "qname" => "foo:bar",
            "namespaceUri" => "http://foo.com",
            "attributes"   => array( "key" => "value", "argh" => "fruit&vegetable" ),
            "content"      => "I'm inside the tag",
        );
        $multiline = false;
        $expected = "I'm inside the tag";
        $this->assertEquals($expected, XML_Util::createTagFromArray($original, XML_UTIL_REPLACE_ENTITIES, $multiline));
    }

    /**
     * @covers XML_Util::createTagFromArray()
     */
    public function testCreateTagFromArrayWithQnameAndNamespaceAndAttributesAndContentWithReplaceEntitiesAndMultilineTrue()
    {
        $original = array(
            "qname" => "foo:bar",
            "namespaceUri" => "http://foo.com",
            "attributes"   => array( "key" => "value", "argh" => "fruit&vegetable" ),
            "content"      => "I'm inside the tag",
        );
        $multiline = true;
        $expected =
<<< EOF
I'm inside the tag
EOF;
        $this->assertEquals($expected, XML_Util::createTagFromArray($original, XML_UTIL_REPLACE_ENTITIES, $multiline));
    }

    /**
     * @covers XML_Util::createTagFromArray()
     */
    public function testCreateTagFromArrayWithQnameAndNamespaceAndAttributesAndContentWithReplaceEntitiesAndMultilineTrueAndIndent()
    {
        $original = array(
            "qname" => "foo:bar",
            "namespaceUri" => "http://foo.com",
            "attributes"   => array( "key" => "value", "argh" => "fruit&vegetable" ),
            "content"      => "I'm inside the tag",
        );
        $multiline = true;
        $indent = "  ";
        $expected =
<<< EOF
I'm inside the tag
EOF;
        $this->assertEquals($expected, XML_Util::createTagFromArray($original, XML_UTIL_REPLACE_ENTITIES, $multiline, $indent));
    }

    /**
     * @covers XML_Util::createTagFromArray()
     */
    public function testCreateTagFromArrayWithQnameAndNamespaceAndAttributesAndContentWithReplaceEntitiesAndMultilineTrueAndIndentAndLinebreak()
    {
        $original = array(
            "qname" => "foo:bar",
            "namespaceUri" => "http://foo.com",
            "attributes"   => array( "key" => "value", "argh" => "fruit&vegetable" ),
            "content"      => "I'm inside the tag",
        );
        $multiline = true;
        $indent = "  ";
        $linebreak = "^";
        $expected = "I'm inside the tag";
        $this->assertEquals($expected, XML_Util::createTagFromArray($original, XML_UTIL_REPLACE_ENTITIES, $multiline, $indent, $linebreak));
    }

    /**
     * @covers XML_Util::createTagFromArray()
     */
    public function testCreateTagFromArrayWithQnameAndNamespaceAndAttributesAndContentWithReplaceEntitiesAndMultilineTrueAndIndentAndLinebreakAndSortAttributesTrue()
    {
        $original = array(
            "qname" => "foo:bar",
            "namespaceUri" => "http://foo.com",
            "attributes"   => array( "key" => "value", "argh" => "fruit&vegetable" ),
            "content"      => "I'm inside the tag",
        );
        $multiline = true;
        $indent = "  ";
        $linebreak = "^";
        $sortAttributes = true;
        $expected = "I'm inside the tag";
        $this->assertEquals($expected, XML_Util::createTagFromArray($original, XML_UTIL_REPLACE_ENTITIES, $multiline, $indent, $linebreak, $sortAttributes));
    }

    /**
     * @covers XML_Util::createTagFromArray()
     */
    public function testCreateTagFromArrayWithQnameAndNamespaceAndAttributesAndContentWithReplaceEntitiesAndMultilineTrueAndIndentAndLinebreakAndSortAttributesFalse()
    {
        $original = array(
            "qname" => "foo:bar",
            "namespaceUri" => "http://foo.com",
            "attributes"   => array( "key" => "value", "argh" => "fruit&vegetable" ),
            "content"      => "I'm inside the tag",
        );
        $multiline = true;
        $indent = "  ";
        $linebreak = "^";
        $sortAttributes = false;
        $expected = "I'm inside the tag";
        $this->assertEquals($expected, XML_Util::createTagFromArray($original, XML_UTIL_REPLACE_ENTITIES, $multiline, $indent, $linebreak, $sortAttributes));
    }

    /**
     * @covers XML_Util::createTagFromArray()
     */
    public function testCreateTagFromArrayWithInvalidArray()
    {
        $badArray = array(
            "foo" => "bar",
        );
        $expectedError = "You must either supply a qualified name (qname) or local tag name (localPart).";
        $this->assertEquals($expectedError, XML_Util::createTagFromArray($badArray));
    }

    /**
     * @covers XML_Util::createTagFromArray()
     */
    public function testCreateTagFromArrayWithNamespaceAndAttributesAndContentButWithoutQname()
    {
        $original = array(
            "namespaceUri" => "http://foo.com",
            "attributes"   => array( "key" => "value", "argh" => "fruit&vegetable" ),
            "content"      => "I'm inside the tag",
        );
        $expectedError = "You must either supply a qualified name (qname) or local tag name (localPart).";
        $this->assertEquals($expectedError, XML_Util::createTagFromArray($original));
    }

    /**
     * @covers XML_Util::createTagFromArray()
     */
    public function testCreateTagFromArrayWithNonScalarContent()
    {
        $badArray = array(
            'content' => array('foo', 'bar'),
        );
        $expectedError = "Supplied non-scalar value as tag content";
        $this->assertEquals($expectedError, XML_Util::createTagFromArray($badArray));
    }

    /**
     * @covers XML_Util::createTagFromArray()
     */
    public function testCreateTagFromArrayWithArrayOfNamespaces()
    {
        $original = array(
            'qname'        => 'foo:bar',
            'namespaces'   => array('ns1' => 'uri1', 'ns2' => 'uri2'),
        );
        $expected = "";
        $this->assertEquals($expected, XML_Util::createTagFromArray($original));
    }

    /**
     * @covers XML_Util::createTagFromArray()
     */
    public function testCreateTagFromArrayWithQnameDerivedFromNamespaceUriAndLocalPart()
    {
        $original = array(
            'namespaceUri' => 'http://bar.org',
            'localPart'    => 'foo'
        );
        $expected = "";
        $this->assertEquals($expected, XML_Util::createTagFromArray($original));
    }

    /**
     * @covers XML_Util::createTagFromArray()
     */
    public function testCreateTagFromArrayWithQnameDerivedFromNamespaceAndLocalPart()
    {
        $original = array(
            'namespace'    => 'http://foo.org',
            'localPart'    => 'bar'
        );
        $expected = "";
        $this->assertEquals($expected, XML_Util::createTagFromArray($original));
    }

    /**
     * @covers XML_Util::createTagFromArray()
     */
    public function testCreateTagFromArrayWithQnameDerivedFromLocalPart()
    {
        $original = array(
            'namespace'    => '',
            'localPart'    => 'bar'
        );
        $expected = "";
        $this->assertEquals($expected, XML_Util::createTagFromArray($original));
    }

    /**
     * @covers XML_Util::createTagFromArray()
     */
    public function testCreateTagFromArrayWithImplicitlyEmptyContentAndCollapseNoneDoesNotCollapseTag()
    {
        $original = array('qname' => 'tag1');
        $expected = "";
        $actual = XML_Util::createTagFromArray(
            $original,
            XML_UTIL_REPLACE_ENTITIES,  // default $replaceEntities
            false,                      // default $multiline
            '_auto',                    // default $indent
            "\n",                       // default $linebreak
            true,                       // default $sortAttributes
            XML_UTIL_COLLAPSE_NONE
        );
        $this->assertEquals($expected, $actual);
    }

    /**
     * @covers XML_Util::createTagFromArray()
     */
    public function testCreateTagFromArrayForCdataWithExplicitlyEmptyContentDoesNotCollapseTag()
    {
        $original = array('qname' => 'tag1', 'content' => '');
        $expected = "";
        $this->assertEquals($expected, XML_Util::createTagFromArray($original, XML_UTIL_CDATA_SECTION));
    }
}
PKu]rv'test/XML_Util/tests/RaiseErrorTests.phpnu[assertInstanceOf('PEAR_Error', $error);
        $this->assertEquals($message, $error->getMessage());
        $this->assertEquals($code, $error->getCode());
    }
}
PKu]|\5.test/XML_Util/tests/CollapseEmptyTagsTests.phpnu[";
        $expected = "";
        $this->assertEquals($expected, XML_Util::collapseEmptyTags($emptyTag));
    }

    /**
     * @covers XML_Util::collapseEmptyTags()
     */
    public function testCollapseEmptyTagsBasicUsageAlongsideNonemptyTag()
    {
        $emptyTag = "";
        $otherTag = "baz";
        $expected = "baz";
        $this->assertEquals($expected, XML_Util::collapseEmptyTags($emptyTag . $otherTag));
    }

    /**
     * @covers XML_Util::collapseEmptyTags()
     */
    public function testCollapseEmptyTagsOnOneEmptyTagWithCollapseAll()
    {
        $emptyTag = "";
        $expected = "";
        $this->assertEquals($expected, XML_Util::collapseEmptyTags($emptyTag, XML_UTIL_COLLAPSE_ALL));
    }

    /**
     * @covers XML_Util::collapseEmptyTags()
     */
    public function testCollapseEmptyTagsOnOneEmptyTagAlongsideNonemptyTagWithCollapseAll()
    {
        $emptyTag = "";
        $otherTag = "baz";
        $expected = "baz";
        $this->assertEquals($expected, XML_Util::collapseEmptyTags($emptyTag . $otherTag, XML_UTIL_COLLAPSE_ALL));
    }

    /**
     * @covers XML_Util::collapseEmptyTags()
     */
    public function testCollapseEmptyTagsOnOneEmptyTagAlongsideNonemptyTagAlongsideEmptyTagWithCollapseAll()
    {
        $emptyTag = "";
        $otherTag = "baz";
        $expected = "baz";
        $this->assertEquals($expected, XML_Util::collapseEmptyTags($emptyTag . $otherTag . $emptyTag, XML_UTIL_COLLAPSE_ALL));
    }

    /**
     * @covers XML_Util::collapseEmptyTags()
     */
    public function testCollapseEmptyTagsOnOneEmptyPrefixedTagAlongsideNonemptyTagAlongsideEmptyPrefixedTagWithCollapseAll()
    {
        $emptyTag = "";
        $otherTag = "baz";
        $expected = "baz";
        $this->assertEquals($expected, XML_Util::collapseEmptyTags($emptyTag . $otherTag . $emptyTag, XML_UTIL_COLLAPSE_ALL));
    }

    /**
     * @covers XML_Util::collapseEmptyTags()
     */
    public function testCollapseEmptyTagsOnOneEmptyNsPrefixedTagAlongsideNonemptyTagAlongsideEmptyNsPrefixedTagWithCollapseAll()
    {
        $emptyTag = "";
        $otherTag = "baz";
        $expected = "baz";
        $this->assertEquals($expected, XML_Util::collapseEmptyTags($emptyTag . $otherTag . $emptyTag, XML_UTIL_COLLAPSE_ALL));
    }

    /**
     * @covers XML_Util::collapseEmptyTags()
     */
    public function testCollapseEmptyTagsOnOneEmptyTagWithCollapseXhtml()
    {
        $emptyTag = "";
        $expected = "";
        $this->assertEquals($expected, XML_Util::collapseEmptyTags($emptyTag, XML_UTIL_COLLAPSE_XHTML_ONLY));
    }

    /**
     * @covers XML_Util::collapseEmptyTags()
     */
    public function testCollapseEmptyTagsOnOneEmptyTagAlongsideNonemptyTagWithCollapseXhtml()
    {
        $emptyTag = "";
        $otherTag = "baz";
        $xhtmlTag = "

"; $expected = "
baz"; $this->assertEquals($expected, XML_Util::collapseEmptyTags($emptyTag . $xhtmlTag . $otherTag, XML_UTIL_COLLAPSE_XHTML_ONLY)); } /** * @covers XML_Util::collapseEmptyTags() */ public function testCollapseEmptyTagsOnOneEmptyTagWithCollapseNone() { $emptyTag = ""; $expected = ""; $this->assertEquals($expected, XML_Util::collapseEmptyTags($emptyTag, XML_UTIL_COLLAPSE_NONE)); } /** * @covers XML_Util::collapseEmptyTags() */ public function testCollapseEmptyTagsOnOneEmptyTagAlongsideNonemptyTagWithCollapseNone() { $emptyTag = ""; $otherTag = "baz"; $expected = "baz"; $this->assertEquals($expected, XML_Util::collapseEmptyTags($emptyTag . $otherTag, XML_UTIL_COLLAPSE_NONE)); } } PKu]ܬ$2test/XML_Util/tests/GetDocTypeDeclarationTests.phpnu["; $this->assertEquals($expected, XML_Util::getDocTypeDeclaration("rootTag")); } /** * @covers XML_Util::getDocTypeDeclaration() */ public function testGetDocTypeDeclarationUsingRootAndStringUri() { $expected = ""; $this->assertEquals($expected, XML_Util::getDocTypeDeclaration("rootTag", "myDocType.dtd")); } /** * @covers XML_Util::getDocTypeDeclaration() */ public function testGetDocTypeDeclarationUsingRootAndArrayUri() { $uri = array( 'uri' => 'http://pear.php.net/dtd/package-1.0', 'id' => '-//PHP//PEAR/DTD PACKAGE 0.1' ); $expected = ""; $this->assertEquals($expected, XML_Util::getDocTypeDeclaration("rootTag", $uri)); } /** * @covers XML_Util::getDocTypeDeclaration() */ public function testGetDocTypeDeclarationUsingRootAndArrayUriAndInternalDtd() { $uri = array( 'uri' => 'http://pear.php.net/dtd/package-1.0', 'id' => '-//PHP//PEAR/DTD PACKAGE 0.1' ); $dtdEntry = ''; $expected = <<< EOF ]> EOF; $this->assertEquals($expected, XML_Util::getDocTypeDeclaration("rootTag", $uri, $dtdEntry)); } } PKu]GG/test/XML_Util/tests/SplitQualifiedNameTests.phpnu[ 'xslt', 'localPart' => 'stylesheet', ); $this->assertEquals($expected, XML_Util::splitQualifiedName($original)); } /** * @covers XML_Util::splitQualifiedName() */ public function testSplitQualifiedNameWithNamespace() { $original = "stylesheet"; $namespace = "myNs"; $expected = array( 'namespace' => 'myNs', 'localPart' => 'stylesheet', ); $this->assertEquals($expected, XML_Util::splitQualifiedName($original, $namespace)); } } PKu]~$[ee-test/XML_Util/tests/CreateEndElementTests.phpnu["; $this->assertEquals($expected, XML_Util::createEndElement($original)); } /** * @covers XML_Util::createEndElement() */ public function testCreateEndElementWithNamespacedTag() { $original = "myNs:myTag"; $expected = ""; $this->assertEquals($expected, XML_Util::createEndElement($original)); } } PKu]Gs$test/XML_Util/tests/Bug5392Tests.phpnu[, & and " as well as ä, ö, ß, à and ê'; $replacedResult = XML_Util::replaceEntities($original, XML_UTIL_ENTITIES_HTML, "UTF-8"); $reversedResult = XML_Util::reverseEntities($replacedResult, XML_UTIL_ENTITIES_HTML, "UTF-8"); $this->assertEquals($original, $reversedResult, "Failed bugcheck."); } } PKu]G%test/XML_Util/tests/Bug21177Tests.phpnu['; return array( array('', ''), array('', ''), array('', ''), array('', ''), ); } /** * @dataProvider getTestCandidate() */ public function testCollapseEmptyTagsForBug21177($original, $expected) { $this->assertEquals($expected, XML_Util::collapseEmptyTags($original, XML_UTIL_COLLAPSE_ALL), "Failed bugcheck."); } } PKu]4ejj/test/XML_Util/tests/CreateCDataSectionTests.phpnu["; $this->assertEquals($expected, XML_Util::createCDataSection($original)); } } PKu]ݑh(test/XML_Util/tests/IsValidNameTests.phpnu[assertTrue($result); } /** * @covers XML_Util::isValidName() */ public function testIsValidNameForTagNameWithInvalidCharacter() { $tagName = "invalidTag?"; $result = XML_Util::isValidName($tagName); $this->assertInstanceOf('PEAR_Error', $result); $expectedError = "XML names may only contain alphanumeric chars, period, hyphen, colon and underscores"; $this->assertEquals($expectedError, $result->getMessage()); } /** * @covers XML_Util::isValidName() */ public function testIsValidNameForTagNameWithInvalidStartingCharacter() { $tagName = "1234five"; $result = XML_Util::isValidName($tagName); $this->assertInstanceOf('PEAR_Error', $result); $expectedError = "XML names may only start with letter or underscore"; $this->assertEquals($expectedError, $result->getMessage()); } /** * @covers XML_Util::isValidName() */ public function testIsValidNameForInt() { $tagName = 1; $result = XML_Util::isValidName($tagName); $this->assertInstanceOf('PEAR_Error', $result); $expectedError = "XML names may only start with letter or underscore"; $this->assertEquals($expectedError, $result->getMessage()); } /** * @covers XML_Util::isValidName() */ public function testIsValidNameForEmptyString() { $tagName = ''; $result = XML_Util::isValidName($tagName); $this->assertInstanceOf('PEAR_Error', $result); $expectedError = "XML names may only start with letter or underscore"; $this->assertEquals($expectedError, $result->getMessage()); } } PKu]!)test/XML_Util/tests/AbstractUnitTests.phpnu["; $this->assertEquals($expected, XML_Util::createStartElement($original)); } /** * @covers XML_Util::createStartElement() */ public function testCreateStartElementForTagWithAttributes() { $originalTag = "myNs:myTag"; $originalAttributes = array("foo" => "bar"); $expected = ""; $this->assertEquals($expected, XML_Util::createStartElement($originalTag, $originalAttributes)); } /** * @covers XML_Util::createStartElement() */ public function testCreateStartElementForTagWithEmptyAttributes() { $originalTag = "myNs:myTag"; $originalAttributes = ""; $expected = ""; $this->assertEquals($expected, XML_Util::createStartElement($originalTag, $originalAttributes)); } /** * @covers XML_Util::createStartElement() */ public function testCreateStartElementForTagWithAttributesAndNamespace() { $originalTag = "myNs:myTag"; $originalAttributes = array("foo" => "bar"); $originalNamespace = "http://www.w3c.org/myNs#"; $expected = ""; $this->assertEquals($expected, XML_Util::createStartElement($originalTag, $originalAttributes, $originalNamespace)); } /** * @covers XML_Util::createStartElement() */ public function testCreateStartElementForTagWithEmptyAttributesAndNonUriNamespace() { $originalTag = "myTag"; $originalAttributes = ""; $originalNamespace = "foo"; $expected = ""; $this->assertEquals($expected, XML_Util::createStartElement($originalTag, $originalAttributes, $originalNamespace)); } /** * @covers XML_Util::createStartElement() */ public function testCreateStartElementForTagWithAttributesAndNamespaceWithMultiline() { $originalTag = "myNs:myTag"; $originalAttributes = array("foo" => "bar"); $originalNamespace = "http://www.w3c.org/myNs#"; $expected = <<< EOF EOF; $multiline = true; $this->assertEquals($expected, XML_Util::createStartElement($originalTag, $originalAttributes, $originalNamespace, $multiline)); } /** * @covers XML_Util::createStartElement() */ public function testCreateStartElementForTagWithAttributesAndNamespaceWithMultilineAndIndent() { $originalTag = "myNs:myTag"; $originalAttributes = array("foo" => "bar"); $originalNamespace = "http://www.w3c.org/myNs#"; $expected = <<< EOF EOF; $multiline = true; $indent = " "; $this->assertEquals($expected, XML_Util::createStartElement($originalTag, $originalAttributes, $originalNamespace, $multiline, $indent)); } /** * @covers XML_Util::createStartElement() */ public function testCreateStartElementForTagWithAttributesAndNamespaceWithMultilineAndIndentAndLinebreak() { $originalTag = "myNs:myTag"; $originalAttributes = array("foo" => "bar"); $originalNamespace = "http://www.w3c.org/myNs#"; $expected = ""; $multiline = true; $indent = " "; $linebreak = "^"; $this->assertEquals($expected, XML_Util::createStartElement($originalTag, $originalAttributes, $originalNamespace, $multiline, $indent, $linebreak)); } /** * @covers XML_Util::createStartElement() */ public function testCreateStartElementForTagWithAttributesAndNamespaceWithMultilineAndIndentAndLinebreakAndSortAttributesIsTrue() { $originalTag = "myNs:myTag"; $originalAttributes = array("foo" => "bar", "boo" => "baz"); $originalNamespace = "http://www.w3c.org/myNs#"; $expected = ""; $multiline = true; $indent = " "; $linebreak = "^"; $sortAttributes = true; $this->assertEquals($expected, XML_Util::createStartElement($originalTag, $originalAttributes, $originalNamespace, $multiline, $indent, $linebreak, $sortAttributes)); } /** * @covers XML_Util::createStartElement() */ public function testCreateStartElementForTagWithAttributesAndNamespaceWithMultilineAndIndentAndLinebreakAndSortAttributesIsFalse() { $originalTag = "myNs:myTag"; $originalAttributes = array("foo" => "bar", "boo" => "baz"); $originalNamespace = "http://www.w3c.org/myNs#"; $expected = ""; $multiline = true; $indent = " "; $linebreak = "^"; $sortAttributes = false; $this->assertEquals($expected, XML_Util::createStartElement($originalTag, $originalAttributes, $originalNamespace, $multiline, $indent, $linebreak, $sortAttributes)); } } PKu]m4**&test/XML_Util/tests/CreateTagTests.phpnu[ "bar"); $expected = ""; $this->assertEquals($expected, XML_Util::createTag($originalTag, $originalAttributes)); } /** * @covers XML_Util::createTag() */ public function testCreateTagForTagWithAttributesAndContent() { $originalTag = "myNs:myTag"; $originalAttributes = array("foo" => "bar"); $originalContent = "This is inside the tag"; $expected = "This is inside the tag"; $this->assertEquals($expected, XML_Util::createTag($originalTag, $originalAttributes, $originalContent)); } /** * @covers XML_Util::createTag() */ public function testCreateTagForTagWithAttributesAndContentAndNamespace() { $originalTag = "myNs:myTag"; $originalAttributes = array("foo" => "bar"); $originalContent = "This is inside the tag"; $originalNamespace = "http://www.w3c.org/myNs#"; $expected = "This is inside the tag"; $this->assertEquals($expected, XML_Util::createTag($originalTag, $originalAttributes, $originalContent, $originalNamespace)); } /** * @covers XML_Util::createTag() */ public function testCreateTagForTagWithAttributesAndContentAndNamespaceWithCDataSection() { $originalTag = "myNs:myTag"; $originalAttributes = array("foo" => "bar"); $originalContent = "This is inside the tag and has < & @ > in it"; $originalNamespace = "http://www.w3c.org/myNs#"; $expected = " in it]]>"; $this->assertEquals($expected, XML_Util::createTag($originalTag, $originalAttributes, $originalContent, $originalNamespace, XML_UTIL_CDATA_SECTION)); } /** * @covers XML_Util::createTag() */ public function testCreateTagForTagWithAttributesAndContentAndNamespaceWithReplaceEntities() { $originalTag = "myNs:myTag"; $originalAttributes = array("foo" => "bar"); $originalContent = "This is inside the tag and has < & @ > in it"; $originalNamespace = "http://www.w3c.org/myNs#"; $expected = "This is inside the tag and has < & @ > in it"; $this->assertEquals($expected, XML_Util::createTag($originalTag, $originalAttributes, $originalContent, $originalNamespace, XML_UTIL_REPLACE_ENTITIES)); } /** * @covers XML_Util::createTag() */ public function testCreateTagForTagWithAttributesAndContentAndNamespaceWithReplaceEntitiesAndMultilineFalse() { $originalTag = "myNs:myTag"; $originalAttributes = array("foo" => "bar"); $originalContent = "This is inside the tag and has < & @ > in it"; $originalNamespace = "http://www.w3c.org/myNs#"; $multiline = false; $expected = "This is inside the tag and has < & @ > in it"; $this->assertEquals($expected, XML_Util::createTag($originalTag, $originalAttributes, $originalContent, $originalNamespace, XML_UTIL_REPLACE_ENTITIES, $multiline)); } /** * @covers XML_Util::createTag() */ public function testCreateTagForTagWithAttributesAndContentAndNamespaceWithReplaceEntitiesAndMultilineTrue() { $originalTag = "myNs:myTag"; $originalAttributes = array("foo" => "bar"); $originalContent = "This is inside the tag and has < & @ > in it"; $originalNamespace = "http://www.w3c.org/myNs#"; $multiline = true; $expected = <<< EOF This is inside the tag and has < & @ > in it EOF; $this->assertEquals($expected, XML_Util::createTag($originalTag, $originalAttributes, $originalContent, $originalNamespace, XML_UTIL_REPLACE_ENTITIES, $multiline)); } /** * @covers XML_Util::createTag() */ public function testCreateTagForTagWithAttributesAndContentAndNamespaceWithReplaceEntitiesAndMultilineTrueAndIndent() { $originalTag = "myNs:myTag"; $originalAttributes = array("foo" => "bar"); $originalContent = "This is inside the tag and has < & @ > in it"; $originalNamespace = "http://www.w3c.org/myNs#"; $multiline = true; $indent = " "; $expected = <<< EOF This is inside the tag and has < & @ > in it EOF; $this->assertEquals($expected, XML_Util::createTag($originalTag, $originalAttributes, $originalContent, $originalNamespace, XML_UTIL_REPLACE_ENTITIES, $multiline, $indent)); } /** * @covers XML_Util::createTag() */ public function testCreateTagForTagWithAttributesAndContentAndNamespaceWithReplaceEntitiesAndMultilineTrueAndIndentAndLinebreak() { $originalTag = "myNs:myTag"; $originalAttributes = array("foo" => "bar"); $originalContent = "This is inside the tag and has < & @ > in it"; $originalNamespace = "http://www.w3c.org/myNs#"; $multiline = true; $indent = " "; $linebreak = "^"; $expected = "This is inside the tag and has < & @ > in it"; $this->assertEquals($expected, XML_Util::createTag($originalTag, $originalAttributes, $originalContent, $originalNamespace, XML_UTIL_REPLACE_ENTITIES, $multiline, $indent, $linebreak)); } /** * @covers XML_Util::createTag() */ public function testCreateTagForTagWithAttributesAndContentAndNamespaceWithReplaceEntitiesAndMultilineTrueAndIndentAndLinebreakAndSortAttributesTrue() { $originalTag = "myNs:myTag"; $originalAttributes = array("foo" => "bar", "boo" => "baz"); $originalContent = "This is inside the tag and has < & @ > in it"; $originalNamespace = "http://www.w3c.org/myNs#"; $multiline = true; $indent = " "; $linebreak = "^"; $sortAttributes = true; $expected = "This is inside the tag and has < & @ > in it"; $this->assertEquals($expected, XML_Util::createTag($originalTag, $originalAttributes, $originalContent, $originalNamespace, XML_UTIL_REPLACE_ENTITIES, $multiline, $indent, $linebreak, $sortAttributes)); } /** * @covers XML_Util::createTag() */ public function testCreateTagForTagWithAttributesAndContentAndNamespaceWithReplaceEntitiesAndMultilineTrueAndIndentAndLinebreakAndSortAttributesFalse() { $originalTag = "myNs:myTag"; $originalAttributes = array("foo" => "bar", "boo" => "baz"); $originalContent = "This is inside the tag and has < & @ > in it"; $originalNamespace = "http://www.w3c.org/myNs#"; $multiline = true; $indent = " "; $linebreak = "^"; $sortAttributes = false; $expected = "This is inside the tag and has < & @ > in it"; $this->assertEquals($expected, XML_Util::createTag($originalTag, $originalAttributes, $originalContent, $originalNamespace, XML_UTIL_REPLACE_ENTITIES, $multiline, $indent, $linebreak, $sortAttributes)); } } PKu]Df:.test/XML_Util/tests/GetXmlDeclarationTests.phpnu["; $this->assertEquals($expected, XML_Util::getXMLDeclaration($version)); } /** * @covers XML_Util::getXMLDeclaration() */ public function testGetXMLDeclarationUsingVersionAndEncodingAndStandalone() { $version = "1.0"; $encoding = "UTF-8"; $standalone = true; $expected = ""; $this->assertEquals($expected, XML_Util::getXMLDeclaration($version, $encoding, $standalone)); } /** * @covers XML_Util::getXMLDeclaration() */ public function testGetXMLDeclarationUsingVersionAndStandalone() { $version = "1.0"; $encoding = null; $standalone = true; $expected = ""; $this->assertEquals($expected, XML_Util::getXMLDeclaration($version, $encoding, $standalone)); } } PKu]۩%test/XML_Util/tests/Bug18343Tests.phpnu[ "install", "attributes" => array( "as" => "Horde/Feed/fixtures/lexicon/http-p.moreover.com-cgi-local-page%2Fo=rss&s=Newsweek", "name" => "test/Horde/Feed/fixtures/lexicon/http-p.moreover.com-cgi-local-page%2Fo=rss&s=Newsweek", ) ); public function getFlagsToTest() { new XML_Util(); // for constants to be declared return array( array('no flag', null), array('false', false), array('ENTITIES_NONE', XML_UTIL_ENTITIES_NONE), array('ENTITIES_XML', XML_UTIL_ENTITIES_XML), array('ENTITIES_XML_REQUIRED', XML_UTIL_ENTITIES_XML_REQUIRED), array('ENTITIES_HTML', XML_UTIL_ENTITIES_HTML), array('REPLACE_ENTITIES', XML_UTIL_REPLACE_ENTITIES), ); } /** * @dataProvider getFlagsToTest() */ public function testCreateTagFromArrayForBug18343($key, $flag) { // all flags for the candidate input should return the same result $expected = <<< EOF EOF; $this->assertEquals($expected, XML_Util::createTagFromArray($this->tagArray, $flag), "Failed bugcheck for $key."); } } PKu]Zt/test/XML_Util/tests/AttributesToStringTests.phpnu[ 'bar','boo' => 'baz',); $expected = " boo=\"baz\" foo=\"bar\""; $this->assertEquals($expected, XML_Util::attributesToString($original)); } /** * @covers XML_Util::attributesToString() */ public function testAttributesToStringWithExplicitSortTrue() { $original = array('foo' => 'bar','boo' => 'baz',); $expected = " boo=\"baz\" foo=\"bar\""; $sort = true; $this->assertEquals($expected, XML_Util::attributesToString($original, $sort)); } /** * @covers XML_Util::attributesToString() */ public function testAttributesToStringWithExplicitSortFalse() { $original = array('foo' => 'bar','boo' => 'baz',); $expected = " foo=\"bar\" boo=\"baz\""; $sort = false; $this->assertEquals($expected, XML_Util::attributesToString($original, $sort)); } /** * @covers XML_Util::attributesToString() */ public function testAttributesToStringWithMultilineFalse() { $original = array('foo' => 'bar','boo' => 'baz',); $expected = " boo=\"baz\" foo=\"bar\""; $sort = true; $multiline = false; $this->assertEquals($expected, XML_Util::attributesToString($original, $sort, $multiline)); } /** * @covers XML_Util::attributesToString() */ public function testAttributesToStringWithMultilineTrue() { $original = array('foo' => 'bar','boo' => 'baz',); $expected = <<< EOF boo="baz" foo="bar" EOF; $sort = true; $multiline = true; $this->assertEquals($expected, XML_Util::attributesToString($original, $sort, $multiline)); } /** * @covers XML_Util::attributesToString() */ public function testAttributesToStringWithExplicitIndent() { $original = array('foo' => 'bar','boo' => 'baz',); $expected = " boo=\"baz\"\n foo=\"bar\""; $sort = true; $multiline = true; $indent = ' '; // 8 spaces $this->assertEquals($expected, XML_Util::attributesToString($original, $sort, $multiline, $indent)); } /** * @covers XML_Util::attributesToString() */ public function testAttributesToStringWithExplicitLinebreak() { $original = array('foo' => 'bar','boo' => 'baz',); $expected = " boo=\"baz\"\n^foo=\"bar\""; $sort = true; $multiline = true; $linebreak = '^'; // some dummy character $this->assertEquals($expected, XML_Util::attributesToString($original, $sort, $multiline, $linebreak)); } /** * @covers XML_Util::attributesToString() */ public function testAttributesToStringWithOptionsThatIncludesSort() { $original = array('foo' => 'bar','boo' => 'baz',); $options = array( 'multiline' => true, 'indent' => '----', 'linebreak' => "^", 'entities' => XML_UTIL_ENTITIES_XML, 'sort' => true, ); $expected = " boo=\"baz\"\n----foo=\"bar\""; $this->assertEquals($expected, XML_Util::attributesToString($original, $options)); } /** * @covers XML_Util::attributesToString() */ public function testAttributesToStringWithOptionsThatExcludesSort() { $original = array('foo' => 'bar','boo' => 'baz',); $options = array( 'multiline' => true, 'indent' => '----', 'linebreak' => "^", 'entities' => XML_UTIL_ENTITIES_XML, ); $expected = " boo=\"baz\"\n----foo=\"bar\""; $this->assertEquals($expected, XML_Util::attributesToString($original, $options)); } /** * @covers XML_Util::attributesToString() */ public function testAttributesToStringWithEntitiesNone() { $original = array("foo" => "b@&r", "boo" => "b>assertEquals($expected, XML_Util::attributesToString($original, $sort, $multiline, $linebreak, PHP_EOL, XML_UTIL_ENTITIES_NONE)); } /** * @covers XML_Util::attributesToString() */ public function testAttributesToStringWithEntitiesXml() { $original = array("foo" => "b@&r", "boo" => "b>assertEquals($expected, XML_Util::attributesToString($original, $sort, $multiline, $linebreak, PHP_EOL, XML_UTIL_ENTITIES_XML)); } /** * @covers XML_Util::attributesToString() */ public function testAttributesToStringWithEntitiesXmlRequired() { $original = array("foo" => "b@&r", "boo" => "b><z\" foo=\"b@&r\""; $sort = true; $multiline = false; $linebreak = ' '; $this->assertEquals($expected, XML_Util::attributesToString($original, $sort, $multiline, $linebreak, PHP_EOL, XML_UTIL_ENTITIES_XML_REQUIRED)); } /** * @covers XML_Util::attributesToString() */ public function testAttributesToStringWithEntitiesHtml() { $original = array("foo" => "b@&r", "boo" => "b>assertEquals($expected, XML_Util::attributesToString($original, $sort, $multiline, $linebreak, PHP_EOL, XML_UTIL_ENTITIES_HTML)); } /** * Tag attributes should not be treated as CDATA, * so the operation will instead quietly use XML_UTIL_ENTITIES_XML. * * @covers XML_Util::attributesToString() */ public function testAttributesToStringWithCDataSectionForSingleAttribute() { $original = array('foo' => 'bar'); // need exactly one attribute here $options = array( 'sort' => true, // doesn't matter for this testcase 'multiline' => false, // doesn't matter for this testcase 'indent' => null, // doesn't matter for this testcase 'linebreak' => null, // doesn't matter for this testcase 'entities' => XML_UTIL_CDATA_SECTION, // DOES matter for this testcase ); $expected = " foo=\"bar\""; $this->assertEquals($expected, XML_Util::attributesToString($original, $options)); } /** * Tag attributes should not be treated as CDATA, * so the operation will instead quietly use XML_UTIL_ENTITIES_XML. * * @covers XML_Util::attributesToString() */ public function testAttributesToStringWithCDataSectionForMultipleAttributesAndMultilineFalse() { $original = array('foo' => 'bar', 'boo' => 'baz'); // need more than one attribute here $options = array( 'sort' => true, // doesn't matter for this testcase 'multiline' => false, // DOES matter for this testcase, must be false 'indent' => null, // doesn't matter for this testcase 'linebreak' => null, // doesn't matter for this testcase 'entities' => XML_UTIL_CDATA_SECTION, // DOES matter for this testcase ); $expected = " boo=\"baz\" foo=\"bar\""; $this->assertEquals($expected, XML_Util::attributesToString($original, $options)); } } PKu]&test/File_MARC/tests/marc_xml_005.phptnu[--TEST-- marc_xml_005: Round-trip a MARCXML record with a root element of "record" to MARC21 --SKIPIF-- --FILE-- next()) { print $marc_record->toRaw(); } ?> --EXPECT-- 01142cam 2200301 a 4500001001300000003000400013005001700017008004100034010001700075020002500092040001800117042000900135050002600144082001600170100003200186245008600218250001200304260005200316300004900368500004000417520022800457650003300685650003300718650002400751650002100775650002300796700002100819 92005291 DLC19930521155141.9920219s1993 caua j 000 0 eng  a 92005291  a0152038655 :c$15.95 aDLCcDLCdDLC alcac00aPS3537.A618bA88 199300a811/.522201 aSandburg, Carl,d1878-1967.10aArithmetic /cCarl Sandburg ; illustrated as an anamorphic adventure by Ted Rand. a1st ed. aSan Diego :bHarcourt Brace Jovanovich,cc1993. a1 v. (unpaged) :bill. (some col.) ;c26 cm. aOne Mylar sheet included in pocket. aA poem about numbers and their characteristics. Features anamorphic, or distorted, drawings which can be restored to normal by viewing from a particular angle or by viewing the image's reflection in the provided Mylar cone. 0aArithmeticxJuvenile poetry. 0aChildren's poetry, American. 1aArithmeticxPoetry. 1aAmerican poetry. 1aVisual perception.1 aRand, Ted,eill. PKu]#" ) )"test/File_MARC/tests/marc_022.phptnu[--TEST-- marc_022: Insert fields --SKIPIF-- --FILE-- next()) { print "\nNext record:\n"; // Create the new field $subfields = null; $subfields[] = new File_MARC_Subfield('a', 'Scott, Daniel.'); $new_field = new File_MARC_Data_Field('100', $subfields, 0, null); // Retrieve the target field for our insertion point $subject = $record->getFields('650'); // Insert the new field if (is_array($subject)) { $record->insertField($new_field, $subject[0], true); } elseif ($subject) { $record->insertField($new_field, $subject, true); } print $record; } $record = null; $marc_file = new File_MARC($dir . '/' . 'music.mrc'); print "\nInsert a new 100 field after the first 650\n"; while ($record = $marc_file->next()) { print "\nNext record:\n"; // Create the new field $subfields = null; $subfields[] = new File_MARC_Subfield('a', 'Scott, Daniel.'); $new_field = new File_MARC_Data_Field('100', $subfields, 0, null); // Retrieve the target field for our insertion point $subject = $record->getFields('650'); // Insert the new field if (is_array($subject)) { $record->insertField($new_field, $subject[0]); } elseif ($subject) { $record->insertField($new_field, $subject); } print $record; } ?> --EXPECT-- Insert a new 100 field before the first 650 Next record: LDR 01145ncm 2200277 i 4500 001 000073594 004 AAJ5802 005 20030415102100.0 008 801107s1977 nyujza 010 _a 77771106 035 _a(CaOTUIC)15460184 035 9 _aAAJ5802 040 _aLC 050 00 _aM1366 _b.M62 _dM1527.2 245 04 _aThe Modern Jazz Quartet : _bThe legendary profile. -- 260 _aNew York : _bM.J.Q. Music, _cc1977. 300 _ascore (72 p.) ; _c31 cm. 500 _aFor piano, vibraphone, drums, and double bass. 505 0 _aLewis, J. Django.--Lewis, J. Plastic dreams (music from the film Kemek).--Lewis, J. Dancing (music from the film Kemek).--Lewis, J. Blues in A minor.--Lewis, J. Blues in B♭.--Lewis, J. Precious joy.--Jackson, M. The martyr.--Jackson, M. The legendary profile. 100 _aScott, Daniel. 650 0 _aJazz. 650 0 _aMotion picture music _vExcerpts _vScores. 700 12 _aLewis, John, _d1920- _tSelections. _f1977. 700 12 _aJackson, Milt. _tMartyrs. _f1977. 700 12 _aJackson, Milt. _tLegendary profile. _f1977. 740 4 _aThe legendary profile. 852 00 _bMUSIC _cMAIN _kfolio _hM1366 _iM62 _91 _4Marvin Duchow Music _5 Next record: LDR 01293cjm 2200289 a 4500 001 001878039 005 20050110174900.0 007 sd fungnn|||e| 008 940202r19931981nyujzn i d 024 1 _a7464573372 028 02 _aJK 57337 _bRed Baron 035 _a(OCoLC)29737267 040 _aSVP _cSVP _dLGG 100 1 _aDesmond, Paul, _d1924- 245 10 _aPaul Desmond & the Modern Jazz Quartet _h[sound recording] 260 _aNew York, N.Y. : _bRed Baron : _bManufactured by Sony Music Entertainment, _cp1993. 300 _a1 sound disc (39 min.) : _bdigital ; _c4 3/4 in. 511 0 _aPaul Desmond, alto saxophone; Modern Jazz Quartet: John Lewis, piano; Milt Jackson, vibraphone; Percy Heath, bass; Connie Kay, drums. 500 _aAll arrangements by John Lewis. 518 _aRecorded live on December 25, 1971 at Town Hall, NYC. 500 _aOriginally released in 1981 by Finesse as LP FW 27487. 500 _aProgram notes by Irving Townsend, June 1981, on container insert. 505 0 _aGreensleeves -- You go to my head -- Blue dove -- Jesus Christ Superstar -- Here's that rainy day -- East of the sun -- Bags' new groove. 100 _aScott, Daniel. 650 0 _aJazz _y1971-1980. 700 1 _aLewis, John, _d1920- 710 2 _aModern Jazz Quartet. 740 0 _aPaul Desmond and the Modern Jazz Quartet. Next record: LDR 01829cjm 2200385 a 4500 001 001964482 005 20060626132700.0 007 sd fzngnn|m|e| 008 871211p19871957nyujzn d 024 1 _a4228332902 028 01 _a833 290-2 _bVerve 033 0 _a19571027 _b6299 _cD56 033 0 _a196112-- _b3804 _cN4 033 0 _a19571019 _b4104 _cC6 033 0 _a197107-- _b6299 _cV7 035 _a(OCoLC)17222092 040 _aCPL _cCPL _dOCL _dLGG 048 _apz01 _aka01 _asd01 _apd01 110 2 _aModern Jazz Quartet. _4prf 245 14 _aThe Modern Jazz Quartet plus _h[sound recording]. 260 _a[New York] : _bVerve, _cp1987. 300 _a1 sound disc : _bdigital ; _c4 3/4 in. 440 0 _aCompact jazz 511 0 _aModern Jazz Quartet (principally) ; Milt Jackson, vibraphone (2nd and 8th works) ; Oscar Peterson, piano (2nd and 8th works) ; Ray Brown, bass (2nd and 8th works) ; Ed Thigpen (2nd work), Louis Hayes (8th work), drums. 518 _aRecorded live, Oct. 27, 1957, at the Donaueschingen Jazz Festival (1st, 5th, 7th, and 10th works); Dec. 1961, in New York (2nd work); live, Oct. 19, 1957, at the Opera House, Chicago (3rd, 4th, 6th, and 9th works); July 1971, in Villingen, Germany (8th work). 500 _aCompact disc. 500 _aAnalog recording. 505 0 _aThe golden striker (4:08) -- On Green Dolphin Street (7:28) -- D & E (4:55) -- I'll remember April (4:51) -- Cortège (7:15) -- Now's the time (4:43) -- J.B. blues (5:09) -- Reunion blues (6:35) -- 'Round midnight (3:56) -- Three windows (7:20). 100 _aScott, Daniel. 650 0 _aJazz. 700 1 _aJackson, Milt. _4prf 700 1 _aPeterson, Oscar, _d1925- _4prf 700 1 _aBrown, Ray, _d1926-2002. _4prf 700 1 _aThigpen, Ed. _4prf 700 1 _aHayes, Louis, _d1937- _4prf 852 80 _bMUSIC _cAV _hCD 1131 _4Marvin Duchow Music _5Audio-Visual Insert a new 100 field after the first 650 Next record: LDR 01145ncm 2200277 i 4500 001 000073594 004 AAJ5802 005 20030415102100.0 008 801107s1977 nyujza 010 _a 77771106 035 _a(CaOTUIC)15460184 035 9 _aAAJ5802 040 _aLC 050 00 _aM1366 _b.M62 _dM1527.2 245 04 _aThe Modern Jazz Quartet : _bThe legendary profile. -- 260 _aNew York : _bM.J.Q. Music, _cc1977. 300 _ascore (72 p.) ; _c31 cm. 500 _aFor piano, vibraphone, drums, and double bass. 505 0 _aLewis, J. Django.--Lewis, J. Plastic dreams (music from the film Kemek).--Lewis, J. Dancing (music from the film Kemek).--Lewis, J. Blues in A minor.--Lewis, J. Blues in B♭.--Lewis, J. Precious joy.--Jackson, M. The martyr.--Jackson, M. The legendary profile. 650 0 _aJazz. 100 _aScott, Daniel. 650 0 _aMotion picture music _vExcerpts _vScores. 700 12 _aLewis, John, _d1920- _tSelections. _f1977. 700 12 _aJackson, Milt. _tMartyrs. _f1977. 700 12 _aJackson, Milt. _tLegendary profile. _f1977. 740 4 _aThe legendary profile. 852 00 _bMUSIC _cMAIN _kfolio _hM1366 _iM62 _91 _4Marvin Duchow Music _5 Next record: LDR 01293cjm 2200289 a 4500 001 001878039 005 20050110174900.0 007 sd fungnn|||e| 008 940202r19931981nyujzn i d 024 1 _a7464573372 028 02 _aJK 57337 _bRed Baron 035 _a(OCoLC)29737267 040 _aSVP _cSVP _dLGG 100 1 _aDesmond, Paul, _d1924- 245 10 _aPaul Desmond & the Modern Jazz Quartet _h[sound recording] 260 _aNew York, N.Y. : _bRed Baron : _bManufactured by Sony Music Entertainment, _cp1993. 300 _a1 sound disc (39 min.) : _bdigital ; _c4 3/4 in. 511 0 _aPaul Desmond, alto saxophone; Modern Jazz Quartet: John Lewis, piano; Milt Jackson, vibraphone; Percy Heath, bass; Connie Kay, drums. 500 _aAll arrangements by John Lewis. 518 _aRecorded live on December 25, 1971 at Town Hall, NYC. 500 _aOriginally released in 1981 by Finesse as LP FW 27487. 500 _aProgram notes by Irving Townsend, June 1981, on container insert. 505 0 _aGreensleeves -- You go to my head -- Blue dove -- Jesus Christ Superstar -- Here's that rainy day -- East of the sun -- Bags' new groove. 650 0 _aJazz _y1971-1980. 100 _aScott, Daniel. 700 1 _aLewis, John, _d1920- 710 2 _aModern Jazz Quartet. 740 0 _aPaul Desmond and the Modern Jazz Quartet. Next record: LDR 01829cjm 2200385 a 4500 001 001964482 005 20060626132700.0 007 sd fzngnn|m|e| 008 871211p19871957nyujzn d 024 1 _a4228332902 028 01 _a833 290-2 _bVerve 033 0 _a19571027 _b6299 _cD56 033 0 _a196112-- _b3804 _cN4 033 0 _a19571019 _b4104 _cC6 033 0 _a197107-- _b6299 _cV7 035 _a(OCoLC)17222092 040 _aCPL _cCPL _dOCL _dLGG 048 _apz01 _aka01 _asd01 _apd01 110 2 _aModern Jazz Quartet. _4prf 245 14 _aThe Modern Jazz Quartet plus _h[sound recording]. 260 _a[New York] : _bVerve, _cp1987. 300 _a1 sound disc : _bdigital ; _c4 3/4 in. 440 0 _aCompact jazz 511 0 _aModern Jazz Quartet (principally) ; Milt Jackson, vibraphone (2nd and 8th works) ; Oscar Peterson, piano (2nd and 8th works) ; Ray Brown, bass (2nd and 8th works) ; Ed Thigpen (2nd work), Louis Hayes (8th work), drums. 518 _aRecorded live, Oct. 27, 1957, at the Donaueschingen Jazz Festival (1st, 5th, 7th, and 10th works); Dec. 1961, in New York (2nd work); live, Oct. 19, 1957, at the Opera House, Chicago (3rd, 4th, 6th, and 9th works); July 1971, in Villingen, Germany (8th work). 500 _aCompact disc. 500 _aAnalog recording. 505 0 _aThe golden striker (4:08) -- On Green Dolphin Street (7:28) -- D & E (4:55) -- I'll remember April (4:51) -- Cortège (7:15) -- Now's the time (4:43) -- J.B. blues (5:09) -- Reunion blues (6:35) -- 'Round midnight (3:56) -- Three windows (7:20). 650 0 _aJazz. 100 _aScott, Daniel. 700 1 _aJackson, Milt. _4prf 700 1 _aPeterson, Oscar, _d1925- _4prf 700 1 _aBrown, Ray, _d1926-2002. _4prf 700 1 _aThigpen, Ed. _4prf 700 1 _aHayes, Louis, _d1937- _4prf 852 80 _bMUSIC _cAV _hCD 1131 _4Marvin Duchow Music _5Audio-Visual PKu]\.ivv!test/File_MARC/tests/sandburg.mrcnu[01142cam 2200301 a 4500001001300000003000400013005001700017008004100034010001700075020002500092040001800117042000900135050002600144082001600170100003200186245008600218250001200304260005200316300004900368500004000417520022800457650003300685650003300718650002400751650002100775650002300796700002100819 92005291 DLC19930521155141.9920219s1993 caua j 000 0 eng  a 92005291  a0152038655 :c$15.95 aDLCcDLCdDLC alcac00aPS3537.A618bA88 199300a811/.522201 aSandburg, Carl,d1878-1967.10aArithmetic /cCarl Sandburg ; illustrated as an anamorphic adventure by Ted Rand. a1st ed. aSan Diego :bHarcourt Brace Jovanovich,cc1993. a1 v. (unpaged) :bill. (some col.) ;c26 cm. aOne Mylar sheet included in pocket. aA poem about numbers and their characteristics. Features anamorphic, or distorted, drawings which can be restored to normal by viewing from a particular angle or by viewing the image's reflection in the provided Mylar cone. 0aArithmeticxJuvenile poetry. 0aChildren's poetry, American. 1aArithmeticxPoetry. 1aAmerican poetry. 1aVisual perception.1 aRand, Ted,eill.PKu]E4kL "test/File_MARC/tests/marc_001.phptnu[--TEST-- marc_001: iterate and pretty print a MARC record --SKIPIF-- --FILE-- next()) { print $marc_record; print "\n"; } ?> --EXPECT-- LDR 01850 2200517 4500 001 0000000044 003 EMILDA 008 980120s1998 fi j 000 0 swe 020 _a9515008808 _cFIM 72:00 035 _99515008808 040 _aNB 042 _9NB _9SEE 084 _aHcd,u _2kssb/6 084 _5NB _auHc _2kssb 084 _5SEE _aHcf _2kssb/6 084 _5Q _aHcd,uf _2kssb/6 100 1 _aJansson, Tove, _d1914-2001 245 04 _aDet osynliga barnet och andra berttelser / _cTove Jansson 250 _a7. uppl. 260 _aHelsingfors : _bSchildt, _c1998 ; _e(Falun : _fScandbook) 300 _a166, [4] s. : _bill. ; _c21 cm 440 0 _aMumin-biblioteket, _x99-0698931-9 500 _aOriginaluppl. 1962 599 _aLi: S 740 4 _aDet osynliga barnet 775 1 _z951-50-0385-7 _w9515003857 _907 841 _5Li _axa _b0201080u 0 4000uu |000000 _e1 841 _5SEE _axa _b0201080u 0 4000uu |000000 _e1 841 _5L _axa _b0201080u 0 4000uu |000000 _e1 841 _5NB _axa _b0201080u 0 4000uu |000000 _e1 841 _5Q _axa _b0201080u 0 4000uu |000000 _e1 841 _5S _axa _b0201080u 0 4000uu |000000 _e1 852 _5NB _bNB _cNB98:12 _hplikt _jR, 980520 852 _5Li _bLi _cCNB _hh,u 852 _5SEE _bSEE 852 _5Q _bQ _j98947 852 _5L _bL _c0100 _h98/ _j3043 H 852 _5S _bS _hSv97 _j7235 900 1s _aYanson, Tobe, _d1914-2001 _uJansson, Tove, _d1914-2001 900 1s _aJanssonov, Tove, _d1914-2001 _uJansson, Tove, _d1914-2001 900 1s _aJansone, Tuve, _d1914-2001 _uJansson, Tove, _d1914-2001 900 1s _aJanson, Tuve, _d1914-2001 _uJansson, Tove, _d1914-2001 900 1s _aJansson, Tuve, _d1914-2001 _uJansson, Tove, _d1914-2001 900 1s _aJanssonova, Tove, _d1914-2001 _uJansson, Tove, _d1914-2001 976 2 _aHcd,u _bSknlitteratur 005 20050204111518.0 PKu]#c "test/File_MARC/tests/onerecord.xmlnu[ 01142cam 2200301 a 4500 92005291 DLC 19930521155141.9 920219s1993 caua j 000 0 eng 92005291 0152038655 : $15.95 DLC DLC DLC lcac PS3537.A618 A88 1993 811/.52 20 Sandburg, Carl, 1878-1967. Arithmetic / Carl Sandburg ; illustrated as an anamorphic adventure by Ted Rand. 1st ed. San Diego : Harcourt Brace Jovanovich, c1993. 1 v. (unpaged) : ill. (some col.) ; 26 cm. One Mylar sheet included in pocket. A poem about numbers and their characteristics. Features anamorphic, or distorted, drawings which can be restored to normal by viewing from a particular angle or by viewing the image's reflection in the provided Mylar cone. Arithmetic Juvenile poetry. Children's poetry, American. Arithmetic Poetry. American poetry. Visual perception. Rand, Ted, ill. PKu]F-//(test/File_MARC/tests/marc_field_002.phptnu[--TEST-- marc_field_002: Create fields with invalid indicators --SKIPIF-- --FILE-- getMessage()}\n"; } --EXPECT-- Error: Illegal indicator "$@" in field "100" forced to blank PKu]rP  &test/File_MARC/tests/marc_xml_004.phptnu[--TEST-- marc_xml_004: test conversion to XML of subfields that need to be escaped --SKIPIF-- --FILE-- next()) { print $marc_record->toXML(); print "\n"; } ?> --EXPECT-- 00727nam 2200205 a 4500 03-0016458 19971103184734.0 970701s1997 oru u000 0 eng u (Sirsi) a351664 ML270.2 .A6 1997 Anthony, James R. French baroque music from Beaujoyeulx to Rameau Rev. and expanded ed. Portland, OR : Amadeus Press, 1997. 586 p. : music Music France 16th century History and criticism. Music France 17th century History and criticism. Music France 18th century History and criticism. ML 270.2 A6 1997 LC 30007006841505 Y BOOKS HUNT-CIRC HUNTINGTON 1 PKu]0S+test/File_MARC/tests/marc_subfield_001.phptnu[--TEST-- marc_subfield_001: Exercise basic methods for File_MARC_Subfield class --SKIPIF-- --FILE-- getCode() . "\n"; print "Data: " . $subfield->getData() . "\n"; // test __toString implementation print $subfield; print "\n"; // test raw output implementation print $subfield->toRaw() . "\n"; // test isEmpty() if ($subfield->isEmpty()) { print "Subfield is empty\n"; } else { print "Subfield is not empty\n"; } ?> --EXPECT-- Code: a Data: wasssup [a]: wasssup awasssup Subfield is not empty PKu].%``"test/File_MARC/tests/marc_010.phptnu[--TEST-- marc_010: iterate and pretty print MARC records from a stream --SKIPIF-- --FILE-- next()) { print $marc_record; print "\n"; } ?> --EXPECT-- LDR 01145ncm 2200277 i 4500 001 000073594 004 AAJ5802 005 20030415102100.0 008 801107s1977 nyujza 010 _a 77771106 035 _a(CaOTUIC)15460184 035 9 _aAAJ5802 040 _aLC 050 00 _aM1366 _b.M62 _dM1527.2 245 04 _aThe Modern Jazz Quartet : _bThe legendary profile. -- 260 _aNew York : _bM.J.Q. Music, _cc1977. 300 _ascore (72 p.) ; _c31 cm. 500 _aFor piano, vibraphone, drums, and double bass. 505 0 _aLewis, J. Django.--Lewis, J. Plastic dreams (music from the film Kemek).--Lewis, J. Dancing (music from the film Kemek).--Lewis, J. Blues in A minor.--Lewis, J. Blues in B♭.--Lewis, J. Precious joy.--Jackson, M. The martyr.--Jackson, M. The legendary profile. 650 0 _aJazz. 650 0 _aMotion picture music _vExcerpts _vScores. 700 12 _aLewis, John, _d1920- _tSelections. _f1977. 700 12 _aJackson, Milt. _tMartyrs. _f1977. 700 12 _aJackson, Milt. _tLegendary profile. _f1977. 740 4 _aThe legendary profile. 852 00 _bMUSIC _cMAIN _kfolio _hM1366 _iM62 _91 _4Marvin Duchow Music _5 LDR 01293cjm 2200289 a 4500 001 001878039 005 20050110174900.0 007 sd fungnn|||e| 008 940202r19931981nyujzn i d 024 1 _a7464573372 028 02 _aJK 57337 _bRed Baron 035 _a(OCoLC)29737267 040 _aSVP _cSVP _dLGG 100 1 _aDesmond, Paul, _d1924- 245 10 _aPaul Desmond & the Modern Jazz Quartet _h[sound recording] 260 _aNew York, N.Y. : _bRed Baron : _bManufactured by Sony Music Entertainment, _cp1993. 300 _a1 sound disc (39 min.) : _bdigital ; _c4 3/4 in. 511 0 _aPaul Desmond, alto saxophone; Modern Jazz Quartet: John Lewis, piano; Milt Jackson, vibraphone; Percy Heath, bass; Connie Kay, drums. 500 _aAll arrangements by John Lewis. 518 _aRecorded live on December 25, 1971 at Town Hall, NYC. 500 _aOriginally released in 1981 by Finesse as LP FW 27487. 500 _aProgram notes by Irving Townsend, June 1981, on container insert. 505 0 _aGreensleeves -- You go to my head -- Blue dove -- Jesus Christ Superstar -- Here's that rainy day -- East of the sun -- Bags' new groove. 650 0 _aJazz _y1971-1980. 700 1 _aLewis, John, _d1920- 710 2 _aModern Jazz Quartet. 740 0 _aPaul Desmond and the Modern Jazz Quartet. LDR 01829cjm 2200385 a 4500 001 001964482 005 20060626132700.0 007 sd fzngnn|m|e| 008 871211p19871957nyujzn d 024 1 _a4228332902 028 01 _a833 290-2 _bVerve 033 0 _a19571027 _b6299 _cD56 033 0 _a196112-- _b3804 _cN4 033 0 _a19571019 _b4104 _cC6 033 0 _a197107-- _b6299 _cV7 035 _a(OCoLC)17222092 040 _aCPL _cCPL _dOCL _dLGG 048 _apz01 _aka01 _asd01 _apd01 110 2 _aModern Jazz Quartet. _4prf 245 14 _aThe Modern Jazz Quartet plus _h[sound recording]. 260 _a[New York] : _bVerve, _cp1987. 300 _a1 sound disc : _bdigital ; _c4 3/4 in. 440 0 _aCompact jazz 511 0 _aModern Jazz Quartet (principally) ; Milt Jackson, vibraphone (2nd and 8th works) ; Oscar Peterson, piano (2nd and 8th works) ; Ray Brown, bass (2nd and 8th works) ; Ed Thigpen (2nd work), Louis Hayes (8th work), drums. 518 _aRecorded live, Oct. 27, 1957, at the Donaueschingen Jazz Festival (1st, 5th, 7th, and 10th works); Dec. 1961, in New York (2nd work); live, Oct. 19, 1957, at the Opera House, Chicago (3rd, 4th, 6th, and 9th works); July 1971, in Villingen, Germany (8th work). 500 _aCompact disc. 500 _aAnalog recording. 505 0 _aThe golden striker (4:08) -- On Green Dolphin Street (7:28) -- D & E (4:55) -- I'll remember April (4:51) -- Cortège (7:15) -- Now's the time (4:43) -- J.B. blues (5:09) -- Reunion blues (6:35) -- 'Round midnight (3:56) -- Three windows (7:20). 650 0 _aJazz. 700 1 _aJackson, Milt. _4prf 700 1 _aPeterson, Oscar, _d1925- _4prf 700 1 _aBrown, Ray, _d1926-2002. _4prf 700 1 _aThigpen, Ed. _4prf 700 1 _aHayes, Louis, _d1937- _4prf 852 80 _bMUSIC _cAV _hCD 1131 _4Marvin Duchow Music _5Audio-Visual PKu]_X(test/File_MARC/tests/marc_field_004.phptnu[--TEST-- marc_field_004: Add subfields to an existing field (corner case) --SKIPIF-- --FILE-- getSubfields('a'); // we might get an array back; in this case, we want the first subfield if (is_array($sf)) { $field->insertSubfield($subfield1, $sf[0], true); } else { $field->insertSubfield($subfield1, $sf, true); } // let's see the results print $field; print "\n"; ?> --EXPECT-- 100 0 _ga little _anothing _zeverything PKu]2.i i "test/File_MARC/tests/marc_018.phptnu[--TEST-- marc_018: iterate and print a MARC record to JSON MARC-HASH format --SKIPIF-- --FILE-- next()) { print $marc_record->toJSONHash(); print "\n"; } ?> --EXPECT-- {"type":"marc-hash","version":[1,0],"leader":"01850 2200517 4500","fields":[["001","0000000044"],["003","EMILDA"],["008","980120s1998 fi j 000 0 swe"],["020"," "," ",[["a","9515008808"],["c","FIM 72:00"]]],["035"," "," ",[["9","9515008808"]]],["040"," "," ",[["a","NB"]]],["042"," "," ",[["9","NB"],["9","SEE"]]],["084"," "," ",[["a","Hcd,u"],["2","kssb\/6"]]],["084"," "," ",[["5","NB"],["a","uHc"],["2","kssb"]]],["084"," "," ",[["5","SEE"],["a","Hcf"],["2","kssb\/6"]]],["084"," "," ",[["5","Q"],["a","Hcd,uf"],["2","kssb\/6"]]],["100","1"," ",[["a","Jansson, Tove,"],["d","1914-2001"]]],["245","0","4",[["a","Det osynliga barnet och andra ber\u00e4ttelser \/"],["c","Tove Jansson"]]],["250"," "," ",[["a","7. uppl."]]],["260"," "," ",[["a","Helsingfors :"],["b","Schildt,"],["c","1998 ;"],["e","(Falun :"],["f","Scandbook)"]]],["300"," "," ",[["a","166, [4] s. :"],["b","ill. ;"],["c","21 cm"]]],["440"," ","0",[["a","Mumin-biblioteket,"],["x","99-0698931-9"]]],["500"," "," ",[["a","Originaluppl. 1962"]]],["599"," "," ",[["a","Li: S"]]],["740","4"," ",[["a","Det osynliga barnet"]]],["775","1"," ",[["z","951-50-0385-7"],["w","9515003857"],["9","07"]]],["841"," "," ",[["5","Li"],["a","xa"],["b","0201080u 0 4000uu |000000"],["e","1"]]],["841"," "," ",[["5","SEE"],["a","xa"],["b","0201080u 0 4000uu |000000"],["e","1"]]],["841"," "," ",[["5","L"],["a","xa"],["b","0201080u 0 4000uu |000000"],["e","1"]]],["841"," "," ",[["5","NB"],["a","xa"],["b","0201080u 0 4000uu |000000"],["e","1"]]],["841"," "," ",[["5","Q"],["a","xa"],["b","0201080u 0 4000uu |000000"],["e","1"]]],["841"," "," ",[["5","S"],["a","xa"],["b","0201080u 0 4000uu |000000"],["e","1"]]],["852"," "," ",[["5","NB"],["b","NB"],["c","NB98:12"],["h","plikt"],["j","R, 980520"]]],["852"," "," ",[["5","Li"],["b","Li"],["c","CNB"],["h","h,u"]]],["852"," "," ",[["5","SEE"],["b","SEE"]]],["852"," "," ",[["5","Q"],["b","Q"],["j","98947"]]],["852"," "," ",[["5","L"],["b","L"],["c","0100"],["h","98\/"],["j","3043 H"]]],["852"," "," ",[["5","S"],["b","S"],["h","Sv97"],["j","7235"]]],["900","1","s",[["a","Yanson, Tobe,"],["d","1914-2001"],["u","Jansson, Tove,"],["d","1914-2001"]]],["900","1","s",[["a","Janssonov\u00e1, Tove,"],["d","1914-2001"],["u","Jansson, Tove,"],["d","1914-2001"]]],["900","1","s",[["a","Jansone, Tuve,"],["d","1914-2001"],["u","Jansson, Tove,"],["d","1914-2001"]]],["900","1","s",[["a","Janson, Tuve,"],["d","1914-2001"],["u","Jansson, Tove,"],["d","1914-2001"]]],["900","1","s",[["a","Jansson, Tuve,"],["d","1914-2001"],["u","Jansson, Tove,"],["d","1914-2001"]]],["900","1","s",[["a","Janssonova, Tove,"],["d","1914-2001"],["u","Jansson, Tove,"],["d","1914-2001"]]],["976"," ","2",[["a","Hcd,u"],["b","Sk\u00f6nlitteratur"]]],["005","20050204111518.0"]]} PKu]!Ņ\&test/File_MARC/tests/marc_xml_001.phptnu[--TEST-- marc_xml_001: iterate and pretty print a MARC record --SKIPIF-- --FILE-- next()) { /* Note that this adds characters to the leader to satisfy MARCXML schema */ print $marc_record->toXML(); print "\n"; } ?> --EXPECT-- 01850na 2200517 4500 0000000044 EMILDA 980120s1998 fi j 000 0 swe 9515008808 FIM 72:00 9515008808 NB NB SEE Hcd,u kssb/6 NB uHc kssb SEE Hcf kssb/6 Q Hcd,uf kssb/6 Jansson, Tove, 1914-2001 Det osynliga barnet och andra berttelser / Tove Jansson 7. uppl. Helsingfors : Schildt, 1998 ; (Falun : Scandbook) 166, [4] s. : ill. ; 21 cm Mumin-biblioteket, 99-0698931-9 Originaluppl. 1962 Li: S Det osynliga barnet 951-50-0385-7 9515003857 07 Li xa 0201080u 0 4000uu |000000 1 SEE xa 0201080u 0 4000uu |000000 1 L xa 0201080u 0 4000uu |000000 1 NB xa 0201080u 0 4000uu |000000 1 Q xa 0201080u 0 4000uu |000000 1 S xa 0201080u 0 4000uu |000000 1 NB NB NB98:12 plikt R, 980520 Li Li CNB h,u SEE SEE Q Q 98947 L L 0100 98/ 3043 H S S Sv97 7235 Yanson, Tobe, 1914-2001 Jansson, Tove, 1914-2001 Janssonov, Tove, 1914-2001 Jansson, Tove, 1914-2001 Jansone, Tuve, 1914-2001 Jansson, Tove, 1914-2001 Janson, Tuve, 1914-2001 Jansson, Tove, 1914-2001 Jansson, Tuve, 1914-2001 Jansson, Tove, 1914-2001 Janssonova, Tove, 1914-2001 Jansson, Tove, 1914-2001 Hcd,u Sknlitteratur 20050204111518.0 PKu]<--+test/File_MARC/tests/marc_subfield_002.phptnu[--TEST-- marc_subfield_002: Exercise setter and isEmpty() methods for File_MARC_Subfield class --SKIPIF-- --FILE-- isEmpty()) { print "empty.\n"; } else { print "not empty.\n"; } } $subfield = new File_MARC_Subfield('a', 'wasssup'); // test isEmpty() scenarios testEmpty($subfield); $subfield->setData(null); testEmpty($subfield); $subfield->setData('just hangin'); testEmpty($subfield); // test setCode() scenarios print "\nSet code to 'z'..."; if ($subfield->setCode('z')) { print "\n"; print $subfield; } print "\nSet code to ''..."; if ($subfield->setCode('')) { print "\n"; print $subfield; } print "\nSet code to null..."; if ($subfield->setCode(null)) { print "\n"; print $subfield; } ?> --EXPECT-- Subfield is not empty. Subfield is empty. Subfield is not empty. Set code to 'z'... [z]: just hangin Set code to ''... Set code to null... PKu]_|6 6 'test/File_MARC/tests/marc_lint_002.phptnu[--TEST-- marc_lint_002: Tests check041() and check043() called separately --SKIPIF-- --FILE-- check041($field); $field = new File_MARC_Data_Field( '041', array( new File_MARC_Subfield('a', 'endorviwo'), // invalid new File_MARC_Subfield('a', 'spanowpalasba') // too long and invalid ), "1", "" ); $marc_lint->check041($field); $field = new File_MARC_Data_Field( '043', array( new File_MARC_Subfield('a', 'n-----'), // 6 chars vs. 7 new File_MARC_Subfield('a', 'n-us----'), // 8 chars vs. 7 new File_MARC_Subfield('a', 'n-ma-us'), // invalid code new File_MARC_Subfield('a', 'e-ur-ai') // obsolete code ), "", "" ); $marc_lint->check043($field); ?> --EXPECT-- 041: Subfield _a, end (end), is not valid. 041: Subfield _a must be evenly divisible by 3 or exactly three characters if ind2 is not 7, (span). 041: Subfield _h, far, may be obsolete. 041: Subfield _a, endorviwo (end), is not valid. 041: Subfield _a, endorviwo (orv), is not valid. 041: Subfield _a, endorviwo (iwo), is not valid. 041: Subfield _a must be evenly divisible by 3 or exactly three characters if ind2 is not 7, (spanowpalasba). 043: Subfield _a must be exactly 7 characters, n----- 043: Subfield _a must be exactly 7 characters, n-us---- 043: Subfield _a, n-ma-us, is not valid. 043: Subfield _a, e-ur-ai, may be obsolete. PKu]y 'test/File_MARC/tests/marc_lint_003.phptnu[--TEST-- marc_lint_003: Tests for field 880 and for subfield 6 --SKIPIF-- --FILE-- setLeader("00000nam 22002538a 4500"); $rec->appendField( new File_MARC_Control_Field( '001', 'ttt07000001 ' ) ); $rec->appendField( new File_MARC_Control_Field( '003', 'TEST ' ) ); $rec->appendField( new File_MARC_Control_Field( '008', '070520s2007 ilu 000 0 eng d' ) ); $rec->appendField( new File_MARC_Data_Field( '040', array( new File_MARC_Subfield('a', 'TEST'), new File_MARC_Subfield('c', 'TEST') ), "", "" ) ); $rec->appendField( new File_MARC_Data_Field( '050', array( new File_MARC_Subfield('a', 'RZ999'), new File_MARC_Subfield('b', '.J66 2007') ), "", "4" ) ); $rec->appendField( new File_MARC_Data_Field( '082', array( new File_MARC_Subfield('a', '615.8/9'), new File_MARC_Subfield('2', '22') ), "0", "4" ) ); $rec->appendField( new File_MARC_Data_Field( '100', array( new File_MARC_Subfield('a', 'Jones, John') ), "1", "" ) ); $rec->appendField( new File_MARC_Data_Field( '245', array( new File_MARC_Subfield('6', '880-02'), new File_MARC_Subfield('a', 'Test 880.') ), "1", "0" ) ); $rec->appendField( new File_MARC_Data_Field( '260', array( new File_MARC_Subfield('a', 'Mount Morris, Ill. :'), new File_MARC_Subfield('b', "B. Baldus,"), new File_MARC_Subfield('c', '2007.') ), "", "" ) ); $rec->appendField( new File_MARC_Data_Field( '300', array( new File_MARC_Subfield('a', '1 v. ;'), new File_MARC_Subfield('c', '23 cm.') ), "", "" ) ); $rec->appendField( new File_MARC_Data_Field( '880', array( new File_MARC_Subfield('6', '245-02/$1'), new File_MARC_Subfield('a', '.') ), "1", "0" ) ); $rec->appendField( new File_MARC_Data_Field( '880', array( new File_MARC_Subfield('6', '245-02/$1'), new File_MARC_Subfield('a', 'Illegal duplicate field.') ), "1", "0" ) ); $warnings = $marc_lint->checkRecord($rec); foreach ($warnings as $warning) { print $warning . "\n"; } ?> --EXPECT-- 245: Field is not repeatable. PK�����u](Y����"��test/File_MARC/tests/xmlescape.mrcnu�[��������00727nam 2200205 a 450000100110000000500170001100800410002803500200006905000220008910000220011124500520013325000260018526000420021130000200025365000560027365000560032965000560038594900740044159600060051503-001645819971103184734.0970701s1997 oru u000 0 eng u a(Sirsi) a35166400aML270.2b.A6 19971 aAnthony, James R.00aFrench baroque music from Beaujoyeulx to Rameau aRev. and expanded ed. aPortland, OR :bAmadeus Press,c1997. a586 p. :bmusic 0aMusic<Francey16th centuryxHistory and criticism. 0aMusiczFrancey17th centuryxHistory and criticism. 0aMusiczFrancey18th centuryxHistory and criticism. aML 270.2 A6 1997wLCi30007006841505rYtBOOKSlHUNT-CIRCmHUNTINGTON a1 PK�����u]~N0:��:�� ��test/File_MARC/tests/example.mrcnu�[��������01850 2200517 45000010011000000030007000110080039000180200026000570350015000830400007000980420012001050840018001170840018001350840021001530840022001741000030001962450062002262500013002882600058003013000033003594400037003925000023004295990010004527400024004627750034004868410048005208410049005688410047006178410048006648410047007128410047007598520038008068520021008448520013008658520016008788520028008948520021009229000056009439000060009999000057010599000056011169000057011729000060012299760026012890050017013150000000044EMILDA980120s1998 fi j 000 0 swe a9515008808cFIM 72:00 99515008808 aNB 9NB9SEE aHcd,u2kssb/6 5NBauHc2kssb 5SEEaHcf2kssb/6 5QaHcd,uf2kssb/61 aJansson, Tove,d1914-200104aDet osynliga barnet och andra berttelser /cTove Jansson a7. uppl. aHelsingfors :bSchildt,c1998 ;e(Falun :fScandbook) a166, [4] s. :bill. ;c21 cm 0aMumin-biblioteket,x99-0698931-9 aOriginaluppl. 1962 aLi: S4 aDet osynliga barnet1 z951-50-0385-7w9515003857907 5Liaxab0201080u 0 4000uu |000000e1 5SEEaxab0201080u 0 4000uu |000000e1 5Laxab0201080u 0 4000uu |000000e1 5NBaxab0201080u 0 4000uu |000000e1 5Qaxab0201080u 0 4000uu |000000e1 5Saxab0201080u 0 4000uu |000000e1 5NBbNBcNB98:12hpliktjR, 980520 5LibLicCNBhh,u 5SEEbSEE 5QbQj98947 5LbLc0100h98/j3043 H 5SbShSv97j72351saYanson, Tobe,d1914-2001uJansson, Tove,d1914-20011saJanssonov, Tove,d1914-2001uJansson, Tove,d1914-20011saJansone, Tuve,d1914-2001uJansson, Tove,d1914-20011saJanson, Tuve,d1914-2001uJansson, Tove,d1914-20011saJansson, Tuve,d1914-2001uJansson, Tove,d1914-20011saJanssonova, Tove,d1914-2001uJansson, Tove,d1914-2001 2aHcd,ubSknlitteratur20050204111518.0PK�����u]泮������test/File_MARC/tests/music.mrcnu�[��������01145ncm 2200277 i 4500001001000000004000800010005001700018008004100035010001700076035002200093035001200115040000700127050002500134245005700159260003800216300002800254500005100282505026600333650001000599650004400609700004400653700003600697700004600733740002700779852006100806000073594AAJ580220030415102100.0801107s1977 nyujza  a 77771106  a(CaOTUIC)154601849 aAAJ5802 aLC00aM1366b.M62dM1527.204aThe Modern Jazz Quartet :bThe legendary profile. -- aNew York :bM.J.Q. Music,cc1977. ascore (72 p.) ;c31 cm. aFor piano, vibraphone, drums, and double bass.0 aLewis, J. Django.--Lewis, J. Plastic dreams (music from the film Kemek).--Lewis, J. Dancing (music from the film Kemek).--Lewis, J. Blues in A minor.--Lewis, J. Blues in B♭.--Lewis, J. Precious joy.--Jackson, M. The martyr.--Jackson, M. The legendary profile. 0aJazz. 0aMotion picture musicvExcerptsvScores.12aLewis, John,d1920-tSelections.f1977.12aJackson, Milt.tMartyrs.f1977.12aJackson, Milt.tLegendary profile.f1977.4 aThe legendary profile.00bMUSICcMAINkfoliohM1366iM62914Marvin Duchow Music5 01293cjm 2200289 a 450000100100000000500170001000700150002700800410004202400150008302800240009803500200012204000180014210000260016024500620018626000850024830000510033351101380038450000360052251800580055850000590061650000700067550501420074565000210088770000240090871000250093274000460095700187803920050110174900.0sd fungnn|||e|940202r19931981nyujzn i d1 a746457337202aJK 57337bRed Baron a(OCoLC)29737267 aSVPcSVPdLGG1 aDesmond, Paul,d1924-10aPaul Desmond & the Modern Jazz Quarteth[sound recording] aNew York, N.Y. :bRed Baron :bManufactured by Sony Music Entertainment,cp1993. a1 sound disc (39 min.) :bdigital ;c4 3/4 in.0 aPaul Desmond, alto saxophone; Modern Jazz Quartet: John Lewis, piano; Milt Jackson, vibraphone; Percy Heath, bass; Connie Kay, drums. aAll arrangements by John Lewis. aRecorded live on December 25, 1971 at Town Hall, NYC. aOriginally released in 1981 by Finesse as LP FW 27487. aProgram notes by Irving Townsend, June 1981, on container insert.0 aGreensleeves -- You go to my head -- Blue dove -- Jesus Christ Superstar -- Here's that rainy day -- East of the sun -- Bags' new groove. 0aJazzy1971-1980.1 aLewis, John,d1920-2 aModern Jazz Quartet.0 aPaul Desmond and the Modern Jazz Quartet. 01829cjm 2200385 a 450000100100000000500170001000700150002700800410004202400150008302800210009803300240011903300230014303300230016603300230018903500200021204000230023204800270025511000300028224500530031226000330036530000410039844000170043951102230045651802640067950000180094350000220096150502500098365000100123370000240124370000330126770000330130070000220133370000300135585200580138500196448220060626132700.0sd fzngnn|m|e|871211p19871957nyujzn d1 a422833290201a833 290-2bVerve0 a19571027b6299cD560 a196112--b3804cN40 a19571019b4104cC60 a197107--b6299cV7 a(OCoLC)17222092 aCPLcCPLdOCLdLGG apz01aka01asd01apd012 aModern Jazz Quartet.4prf14aThe Modern Jazz Quartet plush[sound recording]. a[New York] :bVerve,cp1987. a1 sound disc :bdigital ;c4 3/4 in. 0aCompact jazz0 aModern Jazz Quartet (principally) ; Milt Jackson, vibraphone (2nd and 8th works) ; Oscar Peterson, piano (2nd and 8th works) ; Ray Brown, bass (2nd and 8th works) ; Ed Thigpen (2nd work), Louis Hayes (8th work), drums. aRecorded live, Oct. 27, 1957, at the Donaueschingen Jazz Festival (1st, 5th, 7th, and 10th works); Dec. 1961, in New York (2nd work); live, Oct. 19, 1957, at the Opera House, Chicago (3rd, 4th, 6th, and 9th works); July 1971, in Villingen, Germany (8th work). aCompact disc. aAnalog recording.0 aThe golden striker (4:08) -- On Green Dolphin Street (7:28) -- D & E (4:55) -- I'll remember April (4:51) -- Cortège (7:15) -- Now's the time (4:43) -- J.B. blues (5:09) -- Reunion blues (6:35) -- 'Round midnight (3:56) -- Three windows (7:20). 0aJazz.1 aJackson, Milt.4prf1 aPeterson, Oscar,d1925-4prf1 aBrown, Ray,d1926-2002.4prf1 aThigpen, Ed.4prf1 aHayes, Louis,d1937-4prf80bMUSICcAVhCD 11314Marvin Duchow Music5Audio-Visual PK�����u]jS �� ��"��test/File_MARC/tests/marc_015.phptnu�[��������--TEST-- marc_015: ensure that pandemonium does not occur if a record doesn't have a given field --SKIPIF-- <?php include('tests/skipif.inc'); ?> --FILE-- <?php $dir = dirname(__FILE__); require __DIR__ . '/bootstrap.php'; $marc_file = new File_MARC($dir . '/' . 'music.mrc'); while ($marc_record = $marc_file->next()) { // Record #2 doesn't contain an 852; getField() returns false $mfhd = $marc_record->getField('852'); if ($mfhd) { $mfhd = $mfhd->getSubfield('b'); } print $marc_record; print "\n"; } ?> --EXPECT-- LDR 01145ncm 2200277 i 4500 001 000073594 004 AAJ5802 005 20030415102100.0 008 801107s1977 nyujza 010 _a 77771106 035 _a(CaOTUIC)15460184 035 9 _aAAJ5802 040 _aLC 050 00 _aM1366 _b.M62 _dM1527.2 245 04 _aThe Modern Jazz Quartet : _bThe legendary profile. -- 260 _aNew York : _bM.J.Q. Music, _cc1977. 300 _ascore (72 p.) ; _c31 cm. 500 _aFor piano, vibraphone, drums, and double bass. 505 0 _aLewis, J. Django.--Lewis, J. Plastic dreams (music from the film Kemek).--Lewis, J. Dancing (music from the film Kemek).--Lewis, J. Blues in A minor.--Lewis, J. Blues in B♭.--Lewis, J. Precious joy.--Jackson, M. The martyr.--Jackson, M. The legendary profile. 650 0 _aJazz. 650 0 _aMotion picture music _vExcerpts _vScores. 700 12 _aLewis, John, _d1920- _tSelections. _f1977. 700 12 _aJackson, Milt. _tMartyrs. _f1977. 700 12 _aJackson, Milt. _tLegendary profile. _f1977. 740 4 _aThe legendary profile. 852 00 _bMUSIC _cMAIN _kfolio _hM1366 _iM62 _91 _4Marvin Duchow Music _5 LDR 01293cjm 2200289 a 4500 001 001878039 005 20050110174900.0 007 sd fungnn|||e| 008 940202r19931981nyujzn i d 024 1 _a7464573372 028 02 _aJK 57337 _bRed Baron 035 _a(OCoLC)29737267 040 _aSVP _cSVP _dLGG 100 1 _aDesmond, Paul, _d1924- 245 10 _aPaul Desmond & the Modern Jazz Quartet _h[sound recording] 260 _aNew York, N.Y. : _bRed Baron : _bManufactured by Sony Music Entertainment, _cp1993. 300 _a1 sound disc (39 min.) : _bdigital ; _c4 3/4 in. 511 0 _aPaul Desmond, alto saxophone; Modern Jazz Quartet: John Lewis, piano; Milt Jackson, vibraphone; Percy Heath, bass; Connie Kay, drums. 500 _aAll arrangements by John Lewis. 518 _aRecorded live on December 25, 1971 at Town Hall, NYC. 500 _aOriginally released in 1981 by Finesse as LP FW 27487. 500 _aProgram notes by Irving Townsend, June 1981, on container insert. 505 0 _aGreensleeves -- You go to my head -- Blue dove -- Jesus Christ Superstar -- Here's that rainy day -- East of the sun -- Bags' new groove. 650 0 _aJazz _y1971-1980. 700 1 _aLewis, John, _d1920- 710 2 _aModern Jazz Quartet. 740 0 _aPaul Desmond and the Modern Jazz Quartet. LDR 01829cjm 2200385 a 4500 001 001964482 005 20060626132700.0 007 sd fzngnn|m|e| 008 871211p19871957nyujzn d 024 1 _a4228332902 028 01 _a833 290-2 _bVerve 033 0 _a19571027 _b6299 _cD56 033 0 _a196112-- _b3804 _cN4 033 0 _a19571019 _b4104 _cC6 033 0 _a197107-- _b6299 _cV7 035 _a(OCoLC)17222092 040 _aCPL _cCPL _dOCL _dLGG 048 _apz01 _aka01 _asd01 _apd01 110 2 _aModern Jazz Quartet. _4prf 245 14 _aThe Modern Jazz Quartet plus _h[sound recording]. 260 _a[New York] : _bVerve, _cp1987. 300 _a1 sound disc : _bdigital ; _c4 3/4 in. 440 0 _aCompact jazz 511 0 _aModern Jazz Quartet (principally) ; Milt Jackson, vibraphone (2nd and 8th works) ; Oscar Peterson, piano (2nd and 8th works) ; Ray Brown, bass (2nd and 8th works) ; Ed Thigpen (2nd work), Louis Hayes (8th work), drums. 518 _aRecorded live, Oct. 27, 1957, at the Donaueschingen Jazz Festival (1st, 5th, 7th, and 10th works); Dec. 1961, in New York (2nd work); live, Oct. 19, 1957, at the Opera House, Chicago (3rd, 4th, 6th, and 9th works); July 1971, in Villingen, Germany (8th work). 500 _aCompact disc. 500 _aAnalog recording. 505 0 _aThe golden striker (4:08) -- On Green Dolphin Street (7:28) -- D & E (4:55) -- I'll remember April (4:51) -- Cortège (7:15) -- Now's the time (4:43) -- J.B. blues (5:09) -- Reunion blues (6:35) -- 'Round midnight (3:56) -- Three windows (7:20). 650 0 _aJazz. 700 1 _aJackson, Milt. _4prf 700 1 _aPeterson, Oscar, _d1925- _4prf 700 1 _aBrown, Ray, _d1926-2002. _4prf 700 1 _aThigpen, Ed. _4prf 700 1 _aHayes, Louis, _d1937- _4prf 852 80 _bMUSIC _cAV _hCD 1131 _4Marvin Duchow Music _5Audio-Visual PK�����u]a!����"��test/File_MARC/tests/namespace.xmlnu�[��������<?xml version="1.0" encoding="UTF-8"?> <!-- edited with XML Spy v4.3 U (http://www.xmlspy.com) by Morgan Cundiff (Library of Congress) --> <marc:collection xmlns:marc="http://www.loc.gov/MARC21/slim" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.loc.gov/MARC21/slim http://www.loc.gov/standards/marcxml/schema/MARC21slim.xsd"> <marc:record> <marc:leader>00925njm 22002777a 4500</marc:leader> <marc:controlfield tag="001">5637241</marc:controlfield> <marc:controlfield tag="003">DLC</marc:controlfield> <marc:controlfield tag="005">19920826084036.0</marc:controlfield> <marc:controlfield tag="007">sdubumennmplu</marc:controlfield> <marc:controlfield tag="008">910926s1957 nyuuun eng </marc:controlfield> <marc:datafield tag="010" ind1=" " ind2=" "> <marc:subfield code="a"> 91758335 </marc:subfield> </marc:datafield> <marc:datafield tag="028" ind1="0" ind2="0"> <marc:subfield code="a">1259</marc:subfield> <marc:subfield code="b">Atlantic</marc:subfield> </marc:datafield> <marc:datafield tag="040" ind1=" " ind2=" "> <marc:subfield code="a">DLC</marc:subfield> <marc:subfield code="c">DLC</marc:subfield> </marc:datafield> <marc:datafield tag="050" ind1="0" ind2="0"> <marc:subfield code="a">Atlantic 1259</marc:subfield> </marc:datafield> <marc:datafield tag="245" ind1="0" ind2="4"> <marc:subfield code="a">The Great Ray Charles</marc:subfield> <marc:subfield code="h">[sound recording].</marc:subfield> </marc:datafield> <marc:datafield tag="260" ind1=" " ind2=" "> <marc:subfield code="a">New York, N.Y. :</marc:subfield> <marc:subfield code="b">Atlantic,</marc:subfield> <marc:subfield code="c">[1957?]</marc:subfield> </marc:datafield> <marc:datafield tag="300" ind1=" " ind2=" "> <marc:subfield code="a">1 sound disc :</marc:subfield> <marc:subfield code="b">analog, 33 1/3 rpm ;</marc:subfield> <marc:subfield code="c">12 in.</marc:subfield> </marc:datafield> <marc:datafield tag="511" ind1="0" ind2=" "> <marc:subfield code="a">Ray Charles, piano & celeste.</marc:subfield> </marc:datafield> <marc:datafield tag="505" ind1="0" ind2=" "> <marc:subfield code="a">The Ray -- My melancholy baby -- Black coffee -- There's no you -- Doodlin' -- Sweet sixteen bars -- I surrender dear -- Undecided.</marc:subfield> </marc:datafield> <marc:datafield tag="500" ind1=" " ind2=" "> <marc:subfield code="a">Brief record.</marc:subfield> </marc:datafield> <marc:datafield tag="650" ind1=" " ind2="0"> <marc:subfield code="a">Jazz</marc:subfield> <marc:subfield code="y">1951-1960.</marc:subfield> </marc:datafield> <marc:datafield tag="650" ind1=" " ind2="0"> <marc:subfield code="a">Piano with jazz ensemble.</marc:subfield> </marc:datafield> <marc:datafield tag="700" ind1="1" ind2=" "> <marc:subfield code="a">Charles, Ray,</marc:subfield> <marc:subfield code="d">1930-</marc:subfield> <marc:subfield code="4">prf</marc:subfield> </marc:datafield> </marc:record> <marc:record> <marc:leader>01832cmma 2200349 a 4500</marc:leader> <marc:controlfield tag="001">12149120</marc:controlfield> <marc:controlfield tag="005">20001005175443.0</marc:controlfield> <marc:controlfield tag="007">cr |||</marc:controlfield> <marc:controlfield tag="008">000407m19949999dcu g m eng d</marc:controlfield> <marc:datafield tag="906" ind1=" " ind2=" "> <marc:subfield code="a">0</marc:subfield> <marc:subfield code="b">ibc</marc:subfield> <marc:subfield code="c">copycat</marc:subfield> <marc:subfield code="d">1</marc:subfield> <marc:subfield code="e">ncip</marc:subfield> <marc:subfield code="f">20</marc:subfield> <marc:subfield code="g">y-gencompf</marc:subfield> </marc:datafield> <marc:datafield tag="925" ind1="0" ind2=" "> <marc:subfield code="a">undetermined</marc:subfield> <marc:subfield code="x">web preservation project (wpp)</marc:subfield> </marc:datafield> <marc:datafield tag="955" ind1=" " ind2=" "> <marc:subfield code="a">vb07 (stars done) 08-19-00 to HLCD lk00; AA3s lk29 received for subject Aug 25, 2000; to DEWEY 08-25-00; aa11 08-28-00</marc:subfield> </marc:datafield> <marc:datafield tag="010" ind1=" " ind2=" "> <marc:subfield code="a"> 00530046 </marc:subfield> </marc:datafield> <marc:datafield tag="035" ind1=" " ind2=" "> <marc:subfield code="a">(OCoLC)ocm44279786</marc:subfield> </marc:datafield> <marc:datafield tag="040" ind1=" " ind2=" "> <marc:subfield code="a">IEU</marc:subfield> <marc:subfield code="c">IEU</marc:subfield> <marc:subfield code="d">N@F</marc:subfield> <marc:subfield code="d">DLC</marc:subfield> </marc:datafield> <marc:datafield tag="042" ind1=" " ind2=" "> <marc:subfield code="a">lccopycat</marc:subfield> </marc:datafield> <marc:datafield tag="043" ind1=" " ind2=" "> <marc:subfield code="a">n-us-dc</marc:subfield> <marc:subfield code="a">n-us---</marc:subfield> </marc:datafield> <marc:datafield tag="050" ind1="0" ind2="0"> <marc:subfield code="a">F204.W5</marc:subfield> </marc:datafield> <marc:datafield tag="082" ind1="1" ind2="0"> <marc:subfield code="a">975.3</marc:subfield> <marc:subfield code="2">13</marc:subfield> </marc:datafield> <marc:datafield tag="245" ind1="0" ind2="4"> <marc:subfield code="a">The White House</marc:subfield> <marc:subfield code="h">[computer file].</marc:subfield> </marc:datafield> <marc:datafield tag="256" ind1=" " ind2=" "> <marc:subfield code="a">Computer data.</marc:subfield> </marc:datafield> <marc:datafield tag="260" ind1=" " ind2=" "> <marc:subfield code="a">Washington, D.C. :</marc:subfield> <marc:subfield code="b">White House Web Team,</marc:subfield> <marc:subfield code="c">1994-</marc:subfield> </marc:datafield> <marc:datafield tag="538" ind1=" " ind2=" "> <marc:subfield code="a">Mode of access: Internet.</marc:subfield> </marc:datafield> <marc:datafield tag="500" ind1=" " ind2=" "> <marc:subfield code="a">Title from home page as viewed on Aug. 19, 2000.</marc:subfield> </marc:datafield> <marc:datafield tag="520" ind1="8" ind2=" "> <marc:subfield code="a">Features the White House. Highlights the Executive Office of the President, which includes senior policy advisors and offices responsible for the President's correspondence and communications, the Office of the Vice President, and the Office of the First Lady. Posts contact information via mailing address, telephone and fax numbers, and e-mail. Contains the Interactive Citizens' Handbook with information on health, travel and tourism, education and training, and housing. Provides a tour and the history of the White House. Links to White House for Kids.</marc:subfield> </marc:datafield> <marc:datafield tag="610" ind1="2" ind2="0"> <marc:subfield code="a">White House (Washington, D.C.)</marc:subfield> </marc:datafield> <marc:datafield tag="610" ind1="1" ind2="0"> <marc:subfield code="a">United States.</marc:subfield> <marc:subfield code="b">Executive Office of the President.</marc:subfield> </marc:datafield> <marc:datafield tag="610" ind1="1" ind2="0"> <marc:subfield code="a">United States.</marc:subfield> <marc:subfield code="b">Office of the Vice President.</marc:subfield> </marc:datafield> <marc:datafield tag="610" ind1="1" ind2="0"> <marc:subfield code="a">United States.</marc:subfield> <marc:subfield code="b">Office of the First Lady.</marc:subfield> </marc:datafield> <marc:datafield tag="710" ind1="2" ind2=" "> <marc:subfield code="a">White House Web Team.</marc:subfield> </marc:datafield> <marc:datafield tag="856" ind1="4" ind2="0"> <marc:subfield code="u">http://www.whitehouse.gov</marc:subfield> </marc:datafield> <marc:datafield tag="856" ind1="4" ind2="0"> <marc:subfield code="u">http://lcweb.loc.gov/staff/wpp/whitehouse.html</marc:subfield> <marc:subfield code="z">Web site archive</marc:subfield> </marc:datafield> </marc:record> </marc:collection>PK�����u]}& G��G��'��test/File_MARC/tests/marc_lint_004.phptnu�[��������--TEST-- marc_lint_004: Tests check_245() called separately --SKIPIF-- <?php include('tests/skipif.inc'); ?> <?php include('tests/skipif_noispn.inc'); ?> --FILE-- <?php $dir = dirname(__FILE__); require __DIR__ . '/bootstrap.php'; // Create test harness to allow direct calls to check methods: class File_MARC_Lint_Test_Harness extends File_MARC_Lint { public function check245($field) { return parent::check245($field); } // override warn method to echo instead of store in object: protected function warn($msg) { echo $msg . "\n"; } } $marc_lint = new File_MARC_Lint_Test_Harness(); $testData = array( array(245, '0', '0', 'a', 'Subfield a.'), array(245, '0', '0', 'b', 'no subfield a.'), array(245, '0', '0', 'a', 'No period at end'), array(245, '0', '0', 'a', 'Other punctuation not followed by period!'), array(245, '0', '0', 'a', 'Other punctuation not followed by period?'), array(245, '0', '0', 'a', 'Precedes sub c', 'c', 'not preceded by space-slash.'), array(245, '0', '0', 'a', 'Precedes sub c/', 'c', 'not preceded by space-slash.'), array(245, '0', '0', 'a', 'Precedes sub c /', 'c', 'initials in sub c B. B.'), array(245, '0', '0', 'a', 'Precedes sub c /', 'c', 'initials in sub c B.B. (no warning).'), array(245, '0', '0', 'a', 'Precedes sub b', 'b', 'not preceded by proper punctuation.'), array(245, '0', '0', 'a', 'Precedes sub b=', 'b', 'not preceded by proper punctuation.'), array(245, '0', '0', 'a', 'Precedes sub b:', 'b', 'not preceded by proper punctuation.'), array(245, '0', '0', 'a', 'Precedes sub b;', 'b', 'not preceded by proper punctuation.'), array(245, '0', '0', 'a', 'Precedes sub b =', 'b', 'preceded by proper punctuation.'), array(245, '0', '0', 'a', 'Precedes sub b :', 'b', 'preceded by proper punctuation.'), array(245, '0', '0', 'a', 'Precedes sub b ;', 'b', 'preceded by proper punctuation.'), array(245, '0', '0', 'a', 'Precedes sub h ', 'h', '[videorecording].'), array(245, '0', '0', 'a', 'Precedes sub h-- ', 'h', '[videorecording] :', 'b', 'with elipses dash before h.'), array(245, '0', '0', 'a', 'Precedes sub h-- ', 'h', 'videorecording :', 'b', 'without brackets around GMD.'), array(245, '0', '0', 'a', 'Precedes sub n.', 'n', 'Number 1.'), array(245, '0', '0', 'a', 'Precedes sub n', 'n', 'Number 2.'), array(245, '0', '0', 'a', 'Precedes sub n.', 'n', 'Number 3.', 'p', 'Sub n has period not comma.'), array(245, '0', '0', 'a', 'Precedes sub n.', 'n', 'Number 3,', 'p', 'Sub n has comma.'), array(245, '0', '0', 'a', 'Precedes sub p.', 'p', 'Sub a has period.'), array(245, '0', '0', 'a', 'Precedes sub p', 'p', 'Sub a has no period.'), array(245, '0', 'a', 'a', 'Invalid filing indicator.'), array(245, '0', '0', 'a', 'The article.'), array(245, '0', '4', 'a', 'The article.'), array(245, '0', '2', 'a', 'An article.'), array(245, '0', '0', 'a', "L'article."), array(245, '0', '2', 'a', 'A la mode.'), array(245, '0', '5', 'a', 'The "quoted article".'), array(245, '0', '5', 'a', 'The (parenthetical article).'), array(245, '0', '6', 'a', '(The) article in parentheses).'), array(245, '0', '9', 'a', "\"(The)\" 'article' in quotes and parentheses)."), array(245, '0', '5', 'a', '[The supplied title].') ); foreach ($testData as $current) { $subfields = array(); for ($i = 3; $i < count($current); $i+=2) { $subfields[] = new File_MARC_Subfield($current[$i], $current[$i+1]); } $field = new File_MARC_Data_Field( $current[0], $subfields, $current[1], $current[2] ); $marc_lint->check245($field); } ?> --EXPECT-- 245: Must have a subfield _a. 245: First subfield must be _a, but it is _b 245: Must end with . (period). 245: MARC21 allows ? or ! as final punctuation but LCRI 1.0C, Nov. 2003 (LCPS 1.7.1 for RDA records), requires period. 245: MARC21 allows ? or ! as final punctuation but LCRI 1.0C, Nov. 2003 (LCPS 1.7.1 for RDA records), requires period. 245: Subfield _c must be preceded by / 245: Subfield _c must be preceded by / 245: Subfield _c initials should not have a space. 245: Subfield _b should be preceded by space-colon, space-semicolon, or space-equals sign. 245: Subfield _b should be preceded by space-colon, space-semicolon, or space-equals sign. 245: Subfield _b should be preceded by space-colon, space-semicolon, or space-equals sign. 245: Subfield _b should be preceded by space-colon, space-semicolon, or space-equals sign. 245: Subfield _h should not be preceded by space. 245: Subfield _h must have matching square brackets, videorecording :. 245: Subfield _n must be preceded by . (period). 245: Subfield _p must be preceded by , (comma) when it follows subfield _n. 245: Subfield _p must be preceded by . (period) when it follows a subfield other than _n. 245: Non-filing indicator is non-numeric 245: First word, the, may be an article, check 2nd indicator (0). 245: First word, an, may be an article, check 2nd indicator (2). 245: First word, l, may be an article, check 2nd indicator (0). 245: First word, a, does not appear to be an article, check 2nd indicator (2). PK�����u]2��������test/File_MARC/tests/skipif.incnu�[��������<?php // Stash the current error_reporting value $error_reporting = error_reporting(); // Restore the error reporting to previous value error_reporting($error_reporting); ?> PK�����u]9D��D��"��test/File_MARC/tests/marc_017.phptnu�[��������--TEST-- marc_017: iterate and print a MARC record to JSON format --SKIPIF-- <?php include('tests/skipif.inc'); ?> --FILE-- <?php $dir = dirname(__FILE__); require __DIR__ . '/bootstrap.php'; $marc_file = new File_MARC($dir . '/' . 'example.mrc'); while ($marc_record = $marc_file->next()) { print $marc_record->toJSON(); print "\n"; } ?> --EXPECT-- {"leader":"01850 2200517 4500","fields":[{"001":"0000000044"},{"003":"EMILDA"},{"008":"980120s1998 fi j 000 0 swe"},{"020":{"ind1":" ","ind2":" ","subfields":[{"a":"9515008808"},{"c":"FIM 72:00"}]}},{"035":{"ind1":" ","ind2":" ","subfields":[{"9":"9515008808"}]}},{"040":{"ind1":" ","ind2":" ","subfields":[{"a":"NB"}]}},{"042":{"ind1":" ","ind2":" ","subfields":[{"9":"NB"},{"9":"SEE"}]}},{"084":{"ind1":" ","ind2":" ","subfields":[{"a":"Hcd,u"},{"2":"kssb\/6"}]}},{"084":{"ind1":" ","ind2":" ","subfields":[{"5":"NB"},{"a":"uHc"},{"2":"kssb"}]}},{"084":{"ind1":" ","ind2":" ","subfields":[{"5":"SEE"},{"a":"Hcf"},{"2":"kssb\/6"}]}},{"084":{"ind1":" ","ind2":" ","subfields":[{"5":"Q"},{"a":"Hcd,uf"},{"2":"kssb\/6"}]}},{"100":{"ind1":"1","ind2":" ","subfields":[{"a":"Jansson, Tove,"},{"d":"1914-2001"}]}},{"245":{"ind1":"0","ind2":"4","subfields":[{"a":"Det osynliga barnet och andra ber\u00e4ttelser \/"},{"c":"Tove Jansson"}]}},{"250":{"ind1":" ","ind2":" ","subfields":[{"a":"7. uppl."}]}},{"260":{"ind1":" ","ind2":" ","subfields":[{"a":"Helsingfors :"},{"b":"Schildt,"},{"c":"1998 ;"},{"e":"(Falun :"},{"f":"Scandbook)"}]}},{"300":{"ind1":" ","ind2":" ","subfields":[{"a":"166, [4] s. :"},{"b":"ill. ;"},{"c":"21 cm"}]}},{"440":{"ind1":" ","ind2":"0","subfields":[{"a":"Mumin-biblioteket,"},{"x":"99-0698931-9"}]}},{"500":{"ind1":" ","ind2":" ","subfields":[{"a":"Originaluppl. 1962"}]}},{"599":{"ind1":" ","ind2":" ","subfields":[{"a":"Li: S"}]}},{"740":{"ind1":"4","ind2":" ","subfields":[{"a":"Det osynliga barnet"}]}},{"775":{"ind1":"1","ind2":" ","subfields":[{"z":"951-50-0385-7"},{"w":"9515003857"},{"9":"07"}]}},{"841":{"ind1":" ","ind2":" ","subfields":[{"5":"Li"},{"a":"xa"},{"b":"0201080u 0 4000uu |000000"},{"e":"1"}]}},{"841":{"ind1":" ","ind2":" ","subfields":[{"5":"SEE"},{"a":"xa"},{"b":"0201080u 0 4000uu |000000"},{"e":"1"}]}},{"841":{"ind1":" ","ind2":" ","subfields":[{"5":"L"},{"a":"xa"},{"b":"0201080u 0 4000uu |000000"},{"e":"1"}]}},{"841":{"ind1":" ","ind2":" ","subfields":[{"5":"NB"},{"a":"xa"},{"b":"0201080u 0 4000uu |000000"},{"e":"1"}]}},{"841":{"ind1":" ","ind2":" ","subfields":[{"5":"Q"},{"a":"xa"},{"b":"0201080u 0 4000uu |000000"},{"e":"1"}]}},{"841":{"ind1":" ","ind2":" ","subfields":[{"5":"S"},{"a":"xa"},{"b":"0201080u 0 4000uu |000000"},{"e":"1"}]}},{"852":{"ind1":" ","ind2":" ","subfields":[{"5":"NB"},{"b":"NB"},{"c":"NB98:12"},{"h":"plikt"},{"j":"R, 980520"}]}},{"852":{"ind1":" ","ind2":" ","subfields":[{"5":"Li"},{"b":"Li"},{"c":"CNB"},{"h":"h,u"}]}},{"852":{"ind1":" ","ind2":" ","subfields":[{"5":"SEE"},{"b":"SEE"}]}},{"852":{"ind1":" ","ind2":" ","subfields":[{"5":"Q"},{"b":"Q"},{"j":"98947"}]}},{"852":{"ind1":" ","ind2":" ","subfields":[{"5":"L"},{"b":"L"},{"c":"0100"},{"h":"98\/"},{"j":"3043 H"}]}},{"852":{"ind1":" ","ind2":" ","subfields":[{"5":"S"},{"b":"S"},{"h":"Sv97"},{"j":"7235"}]}},{"900":{"ind1":"1","ind2":"s","subfields":[{"a":"Yanson, Tobe,"},{"d":"1914-2001"},{"u":"Jansson, Tove,"},{"d":"1914-2001"}]}},{"900":{"ind1":"1","ind2":"s","subfields":[{"a":"Janssonov\u00e1, Tove,"},{"d":"1914-2001"},{"u":"Jansson, Tove,"},{"d":"1914-2001"}]}},{"900":{"ind1":"1","ind2":"s","subfields":[{"a":"Jansone, Tuve,"},{"d":"1914-2001"},{"u":"Jansson, Tove,"},{"d":"1914-2001"}]}},{"900":{"ind1":"1","ind2":"s","subfields":[{"a":"Janson, Tuve,"},{"d":"1914-2001"},{"u":"Jansson, Tove,"},{"d":"1914-2001"}]}},{"900":{"ind1":"1","ind2":"s","subfields":[{"a":"Jansson, Tuve,"},{"d":"1914-2001"},{"u":"Jansson, Tove,"},{"d":"1914-2001"}]}},{"900":{"ind1":"1","ind2":"s","subfields":[{"a":"Janssonova, Tove,"},{"d":"1914-2001"},{"u":"Jansson, Tove,"},{"d":"1914-2001"}]}},{"976":{"ind1":" ","ind2":"2","subfields":[{"a":"Hcd,u"},{"b":"Sk\u00f6nlitteratur"}]}},{"005":"20050204111518.0"}]} PK�����u]����,��test/File_MARC/tests/marc_xml_namespace.phptnu�[��������--TEST-- marc_xml_namespace: iterate and pretty print a MARC record --SKIPIF-- <?php include('tests/skipif.inc'); ?> --FILE-- <?php $dir = dirname(__FILE__); require __DIR__ . '/bootstrap.php'; $marc_file = new File_MARCXML($dir . '/' . 'namespace.xml',File_MARC::SOURCE_FILE,"http://www.loc.gov/MARC21/slim"); while ($marc_record = $marc_file->next()) { print $marc_record->getLeader(); print "\n"; $field = $marc_record->getField('050'); print $field->getIndicator(1); print "\n"; print $field->getIndicator(2); print "\n"; $subfield = $field->getSubfield('a'); print $subfield->getData(); print "\n"; } ?> --EXPECT-- 00925njm 22002777a 4500 0 0 Atlantic 1259 01832cmma 2200349 a 4500 0 0 F204.W5 PK�����u]`����"��test/File_MARC/tests/marc_012.phptnu�[��������--TEST-- marc_012: test isControlField() and isDataField() convenience methods --SKIPIF-- <?php include('tests/skipif.inc'); ?> --FILE-- <?php $dir = dirname(__FILE__); require __DIR__ . '/bootstrap.php'; $marc_file = new File_MARC($dir . '/' . 'music.mrc'); while ($marc_record = $marc_file->next()) { $fields = $marc_record->getFields(); foreach ($fields as $field) { print $field->getTag(); if ($field->isControlField()) { print "\tControl field!"; } if ($field->isDataField()) { print "\tData field!"; } print "\n"; } } ?> --EXPECT-- 001 Control field! 004 Control field! 005 Control field! 008 Control field! 010 Data field! 035 Data field! 035 Data field! 040 Data field! 050 Data field! 245 Data field! 260 Data field! 300 Data field! 500 Data field! 505 Data field! 650 Data field! 650 Data field! 700 Data field! 700 Data field! 700 Data field! 740 Data field! 852 Data field! 001 Control field! 005 Control field! 007 Control field! 008 Control field! 024 Data field! 028 Data field! 035 Data field! 040 Data field! 100 Data field! 245 Data field! 260 Data field! 300 Data field! 511 Data field! 500 Data field! 518 Data field! 500 Data field! 500 Data field! 505 Data field! 650 Data field! 700 Data field! 710 Data field! 740 Data field! 001 Control field! 005 Control field! 007 Control field! 008 Control field! 024 Data field! 028 Data field! 033 Data field! 033 Data field! 033 Data field! 033 Data field! 035 Data field! 040 Data field! 048 Data field! 110 Data field! 245 Data field! 260 Data field! 300 Data field! 440 Data field! 511 Data field! 518 Data field! 500 Data field! 500 Data field! 505 Data field! 650 Data field! 700 Data field! 700 Data field! 700 Data field! 700 Data field! 700 Data field! 852 Data field! PK�����u]cܯ����&��test/File_MARC/tests/marc_xml_006.phptnu�[��������--TEST-- marc_xml_006: test getFields() in XML --SKIPIF-- <?php include('tests/skipif.inc'); ?> --FILE-- <?php $dir = dirname(__FILE__); require __DIR__ . '/bootstrap.php'; // Read MARC records from a stream (a file, in this case) $marc_source = new File_MARCXML($dir . '/' . 'sandburg.xml'); // Retrieve the first MARC record from the source $marc_record = $marc_source->next(); // Retrieve a personal name field from the record $names = $marc_record->getFields('100'); foreach ($names as $name_field) { // Now print the $a subfield switch ($name_field->getIndicator(1)) { case 0: print "Forename: "; break; case 1: print "Surname: "; break; case 2: print "Family name: "; break; } $name = $name_field->getSubfields('a'); if (count($name) == 1) { print $name[0]->getData() . "\n"; } else { print "Error -- \$a subfield appears more than once in this field!"; } } // Retrieve all subject and genre fields // Series statement fields start with a 6 (PCRE) $subjects = $marc_record->getFields('^6', true); // Iterate through all of the returned subject fields foreach ($subjects as $field) { // print with File_MARC_Field_Data's magic __toString() method print "$field\n"; } ?> --EXPECT-- Surname: Sandburg, Carl, 650 0 _aArithmetic _xJuvenile poetry. 650 0 _aChildren's poetry, American. 650 1 _aArithmetic _xPoetry. 650 1 _aAmerican poetry. 650 1 _aVisual perception. PK�����u]c����(��test/File_MARC/tests/marc_xml_16642.phptnu�[��������--TEST-- marc_xml_16642: Fix bug 16642: ensure tag and subfield values are returned as strings --SKIPIF-- <?php include('tests/skipif.inc'); ?> --FILE-- <?php $dir = dirname(__FILE__); require __DIR__ . '/bootstrap.php'; // Retrieve a set of MARC records from a file $marc_file = new File_MARCXML($dir . '/' . 'onerecord.xml'); // Iterate through the retrieved records while ($record = $marc_file->next()) { foreach ($record->getFields() as $tag => $subfields) { // Skip everything except for 650 fields if ($tag == '650') { print "Subject:"; foreach ($subfields->getSubfields() as $code => $value) { print " $value"; } print "\n"; } } } ?> --EXPECT-- Subject: [a]: Arithmetic [x]: Juvenile poetry. Subject: [a]: Children's poetry, American. Subject: [a]: Arithmetic [x]: Poetry. Subject: [a]: American poetry. Subject: [a]: Visual perception. PK�����u]{ �� ��*��test/File_MARC/tests/marc_xml_rsinger.phptnu�[��������--TEST-- marc_xml_rsinger2: iterate and pretty print a non-compliant MARC record (uppercase subfield codes) --SKIPIF-- <?php include('tests/skipif.inc'); ?> --FILE-- <?php $dir = dirname(__FILE__); require __DIR__ . '/bootstrap.php'; $marc_file = new File_MARCXML($dir . '/' . 'bad_example.xml'); while ($marc_record = $marc_file->next()) { print $marc_record; print "\n"; } ?> --EXPECT-- LDR 01850 a2200517 4500 001 0000000044 003 EMILDA 008 980120s1998 fi j 000 0 swe 005 20050204111518.0 020 _a9515008808 _cFIM 72:00 035 _99515008808 040 _aNB 042 _9NB _9SEE 084 _aHcd,u _2kssb/6 084 _5NB _auHc _2kssb 084 _5SEE _aHcf _2kssb/6 084 _5Q _aHcd,uf _2kssb/6 100 1 _aJansson, Tove, _d1914-2001 245 0 _aDet osynliga barnet och andra bert̃telser / _cTove Jansson 250 _a7. uppl. 260 _aHelsingfors : _bSchildt, _c1998 ; _e(Falun : _fScandbook) 440 0 _aMumin-biblioteket, _x99-0698931-9 500 _aOriginaluppl. 1962 599 _aLi: S 740 4 _aDet osynliga barnet 775 1 _z951-50-0385-7 _w9515003857 _907 841 _5Li _axa _b0201080u 0 4000uu |000000 _e1 841 _5SEE _axa _b0201080u 0 4000uu |000000 _e1 841 _5L _axa _b0201080u 0 4000uu |000000 _e1 841 _5NB _axa _b0201080u 0 4000uu |000000 _e1 841 _5Q _axa _b0201080u 0 4000uu |000000 _e1 841 _5S _axa _b0201080u 0 4000uu |000000 _e1 852 _5NB _bNB _cNB98:12 _hplikt _jR, 980520 852 _5Li _bLi _cCNB _hh,u 852 _5SEE _bSEE 852 _5Q _bQ _j98947 852 _5L _bL _c0100 _h98/ _j3043 H 852 _5S _bS _hSv97 _j7235 900 1s _aYanson, Tobe, _d1914-2001 _uJansson, Tove, _d1914-2001 900 1s _aJanssonov,̀ Tove, _d1914-2001 _uJansson, Tove, _d1914-2001 900 1s _aJansone, Tuve, _d1914-2001 _uJansson, Tove, _d1914-2001 900 1s _aJanson, Tuve, _d1914-2001 _uJansson, Tove, _d1914-2001 900 1s _aJansson, Tuve, _d1914-2001 _uJansson, Tove, _d1914-2001 900 1s _aJanssonova, Tove, _d1914-2001 _uJansson, Tove, _d1914-2001 976 2 _aHcd,u _bSkn̲litteratur PK�����u]F;Re%��e%��"��test/File_MARC/tests/marc_004.phptnu�[��������--TEST-- marc_004: Delete fields and subfields --SKIPIF-- <?php include('tests/skipif.inc'); ?> --FILE-- <?php $dir = dirname(__FILE__); require __DIR__ . '/bootstrap.php'; $marc_file = new File_MARC($dir . '/' . 'music.mrc'); print "\nDelete all fields with tag 650\n"; while ($marc_record = $marc_file->next()) { print "\nNext record:\n"; $fields = $marc_record->getFields('650'); foreach ($fields as $field) { $field->delete(); } print $marc_record; } $marc_file = null; $marc_file = new File_MARC($dir . '/' . 'music.mrc'); print "\nDelete all subfields with code 'a' from fields with tag 650\n"; while ($marc_record = $marc_file->next()) { print "\nNext record:\n"; $fields = $marc_record->getFields('650'); foreach ($fields as $field) { $sf = $field->getSubfields('a'); foreach ($sf as $subfield) { $field->deleteSubfield($subfield); } } print $marc_record; } ?> --EXPECT-- Delete all fields with tag 650 Next record: LDR 01145ncm 2200277 i 4500 001 000073594 004 AAJ5802 005 20030415102100.0 008 801107s1977 nyujza 010 _a 77771106 035 _a(CaOTUIC)15460184 035 9 _aAAJ5802 040 _aLC 050 00 _aM1366 _b.M62 _dM1527.2 245 04 _aThe Modern Jazz Quartet : _bThe legendary profile. -- 260 _aNew York : _bM.J.Q. Music, _cc1977. 300 _ascore (72 p.) ; _c31 cm. 500 _aFor piano, vibraphone, drums, and double bass. 505 0 _aLewis, J. Django.--Lewis, J. Plastic dreams (music from the film Kemek).--Lewis, J. Dancing (music from the film Kemek).--Lewis, J. Blues in A minor.--Lewis, J. Blues in B♭.--Lewis, J. Precious joy.--Jackson, M. The martyr.--Jackson, M. The legendary profile. 700 12 _aLewis, John, _d1920- _tSelections. _f1977. 700 12 _aJackson, Milt. _tMartyrs. _f1977. 700 12 _aJackson, Milt. _tLegendary profile. _f1977. 740 4 _aThe legendary profile. 852 00 _bMUSIC _cMAIN _kfolio _hM1366 _iM62 _91 _4Marvin Duchow Music _5 Next record: LDR 01293cjm 2200289 a 4500 001 001878039 005 20050110174900.0 007 sd fungnn|||e| 008 940202r19931981nyujzn i d 024 1 _a7464573372 028 02 _aJK 57337 _bRed Baron 035 _a(OCoLC)29737267 040 _aSVP _cSVP _dLGG 100 1 _aDesmond, Paul, _d1924- 245 10 _aPaul Desmond & the Modern Jazz Quartet _h[sound recording] 260 _aNew York, N.Y. : _bRed Baron : _bManufactured by Sony Music Entertainment, _cp1993. 300 _a1 sound disc (39 min.) : _bdigital ; _c4 3/4 in. 511 0 _aPaul Desmond, alto saxophone; Modern Jazz Quartet: John Lewis, piano; Milt Jackson, vibraphone; Percy Heath, bass; Connie Kay, drums. 500 _aAll arrangements by John Lewis. 518 _aRecorded live on December 25, 1971 at Town Hall, NYC. 500 _aOriginally released in 1981 by Finesse as LP FW 27487. 500 _aProgram notes by Irving Townsend, June 1981, on container insert. 505 0 _aGreensleeves -- You go to my head -- Blue dove -- Jesus Christ Superstar -- Here's that rainy day -- East of the sun -- Bags' new groove. 700 1 _aLewis, John, _d1920- 710 2 _aModern Jazz Quartet. 740 0 _aPaul Desmond and the Modern Jazz Quartet. Next record: LDR 01829cjm 2200385 a 4500 001 001964482 005 20060626132700.0 007 sd fzngnn|m|e| 008 871211p19871957nyujzn d 024 1 _a4228332902 028 01 _a833 290-2 _bVerve 033 0 _a19571027 _b6299 _cD56 033 0 _a196112-- _b3804 _cN4 033 0 _a19571019 _b4104 _cC6 033 0 _a197107-- _b6299 _cV7 035 _a(OCoLC)17222092 040 _aCPL _cCPL _dOCL _dLGG 048 _apz01 _aka01 _asd01 _apd01 110 2 _aModern Jazz Quartet. _4prf 245 14 _aThe Modern Jazz Quartet plus _h[sound recording]. 260 _a[New York] : _bVerve, _cp1987. 300 _a1 sound disc : _bdigital ; _c4 3/4 in. 440 0 _aCompact jazz 511 0 _aModern Jazz Quartet (principally) ; Milt Jackson, vibraphone (2nd and 8th works) ; Oscar Peterson, piano (2nd and 8th works) ; Ray Brown, bass (2nd and 8th works) ; Ed Thigpen (2nd work), Louis Hayes (8th work), drums. 518 _aRecorded live, Oct. 27, 1957, at the Donaueschingen Jazz Festival (1st, 5th, 7th, and 10th works); Dec. 1961, in New York (2nd work); live, Oct. 19, 1957, at the Opera House, Chicago (3rd, 4th, 6th, and 9th works); July 1971, in Villingen, Germany (8th work). 500 _aCompact disc. 500 _aAnalog recording. 505 0 _aThe golden striker (4:08) -- On Green Dolphin Street (7:28) -- D & E (4:55) -- I'll remember April (4:51) -- Cortège (7:15) -- Now's the time (4:43) -- J.B. blues (5:09) -- Reunion blues (6:35) -- 'Round midnight (3:56) -- Three windows (7:20). 700 1 _aJackson, Milt. _4prf 700 1 _aPeterson, Oscar, _d1925- _4prf 700 1 _aBrown, Ray, _d1926-2002. _4prf 700 1 _aThigpen, Ed. _4prf 700 1 _aHayes, Louis, _d1937- _4prf 852 80 _bMUSIC _cAV _hCD 1131 _4Marvin Duchow Music _5Audio-Visual Delete all subfields with code 'a' from fields with tag 650 Next record: LDR 01145ncm 2200277 i 4500 001 000073594 004 AAJ5802 005 20030415102100.0 008 801107s1977 nyujza 010 _a 77771106 035 _a(CaOTUIC)15460184 035 9 _aAAJ5802 040 _aLC 050 00 _aM1366 _b.M62 _dM1527.2 245 04 _aThe Modern Jazz Quartet : _bThe legendary profile. -- 260 _aNew York : _bM.J.Q. Music, _cc1977. 300 _ascore (72 p.) ; _c31 cm. 500 _aFor piano, vibraphone, drums, and double bass. 505 0 _aLewis, J. Django.--Lewis, J. Plastic dreams (music from the film Kemek).--Lewis, J. Dancing (music from the film Kemek).--Lewis, J. Blues in A minor.--Lewis, J. Blues in B♭.--Lewis, J. Precious joy.--Jackson, M. The martyr.--Jackson, M. The legendary profile. 650 0 _vExcerpts _vScores. 700 12 _aLewis, John, _d1920- _tSelections. _f1977. 700 12 _aJackson, Milt. _tMartyrs. _f1977. 700 12 _aJackson, Milt. _tLegendary profile. _f1977. 740 4 _aThe legendary profile. 852 00 _bMUSIC _cMAIN _kfolio _hM1366 _iM62 _91 _4Marvin Duchow Music _5 Next record: LDR 01293cjm 2200289 a 4500 001 001878039 005 20050110174900.0 007 sd fungnn|||e| 008 940202r19931981nyujzn i d 024 1 _a7464573372 028 02 _aJK 57337 _bRed Baron 035 _a(OCoLC)29737267 040 _aSVP _cSVP _dLGG 100 1 _aDesmond, Paul, _d1924- 245 10 _aPaul Desmond & the Modern Jazz Quartet _h[sound recording] 260 _aNew York, N.Y. : _bRed Baron : _bManufactured by Sony Music Entertainment, _cp1993. 300 _a1 sound disc (39 min.) : _bdigital ; _c4 3/4 in. 511 0 _aPaul Desmond, alto saxophone; Modern Jazz Quartet: John Lewis, piano; Milt Jackson, vibraphone; Percy Heath, bass; Connie Kay, drums. 500 _aAll arrangements by John Lewis. 518 _aRecorded live on December 25, 1971 at Town Hall, NYC. 500 _aOriginally released in 1981 by Finesse as LP FW 27487. 500 _aProgram notes by Irving Townsend, June 1981, on container insert. 505 0 _aGreensleeves -- You go to my head -- Blue dove -- Jesus Christ Superstar -- Here's that rainy day -- East of the sun -- Bags' new groove. 650 0 _y1971-1980. 700 1 _aLewis, John, _d1920- 710 2 _aModern Jazz Quartet. 740 0 _aPaul Desmond and the Modern Jazz Quartet. Next record: LDR 01829cjm 2200385 a 4500 001 001964482 005 20060626132700.0 007 sd fzngnn|m|e| 008 871211p19871957nyujzn d 024 1 _a4228332902 028 01 _a833 290-2 _bVerve 033 0 _a19571027 _b6299 _cD56 033 0 _a196112-- _b3804 _cN4 033 0 _a19571019 _b4104 _cC6 033 0 _a197107-- _b6299 _cV7 035 _a(OCoLC)17222092 040 _aCPL _cCPL _dOCL _dLGG 048 _apz01 _aka01 _asd01 _apd01 110 2 _aModern Jazz Quartet. _4prf 245 14 _aThe Modern Jazz Quartet plus _h[sound recording]. 260 _a[New York] : _bVerve, _cp1987. 300 _a1 sound disc : _bdigital ; _c4 3/4 in. 440 0 _aCompact jazz 511 0 _aModern Jazz Quartet (principally) ; Milt Jackson, vibraphone (2nd and 8th works) ; Oscar Peterson, piano (2nd and 8th works) ; Ray Brown, bass (2nd and 8th works) ; Ed Thigpen (2nd work), Louis Hayes (8th work), drums. 518 _aRecorded live, Oct. 27, 1957, at the Donaueschingen Jazz Festival (1st, 5th, 7th, and 10th works); Dec. 1961, in New York (2nd work); live, Oct. 19, 1957, at the Opera House, Chicago (3rd, 4th, 6th, and 9th works); July 1971, in Villingen, Germany (8th work). 500 _aCompact disc. 500 _aAnalog recording. 505 0 _aThe golden striker (4:08) -- On Green Dolphin Street (7:28) -- D & E (4:55) -- I'll remember April (4:51) -- Cortège (7:15) -- Now's the time (4:43) -- J.B. blues (5:09) -- Reunion blues (6:35) -- 'Round midnight (3:56) -- Three windows (7:20). 700 1 _aJackson, Milt. _4prf 700 1 _aPeterson, Oscar, _d1925- _4prf 700 1 _aBrown, Ray, _d1926-2002. _4prf 700 1 _aThigpen, Ed. _4prf 700 1 _aHayes, Louis, _d1937- _4prf 852 80 _bMUSIC _cAV _hCD 1131 _4Marvin Duchow Music _5Audio-Visual PK�����u]B1 �� ��'��test/File_MARC/tests/marc_lint_005.phptnu�[��������--TEST-- marc_lint_005: Tests check_020() called separately --SKIPIF-- <?php include('tests/skipif.inc'); ?> <?php include('tests/skipif_noispn.inc'); ?> --FILE-- <?php $dir = dirname(__FILE__); require __DIR__ . '/bootstrap.php'; // Create test harness to allow direct calls to check methods: class File_MARC_Lint_Test_Harness extends File_MARC_Lint { public function check020($field) { return parent::check020($field); } // override warn method to echo instead of store in object: protected function warn($msg) { echo $msg . "\n"; } } $marc_lint = new File_MARC_Lint_Test_Harness(); $testData = array( array('a' => "154879473"), //too few digits array('a' => "1548794743"), //invalid checksum array('a' => "15487947443"), //11 digits array('a' => "15487947443324"), //14 digits array('a' => "9781548794743"), //13 digit valid array('a' => "9781548794745"), //13 digit invalid array('a' => "1548794740 (10 : good checksum)"), //10 digit valid with qualifier array('a' => "1548794745 (10 : bad checksum)"), //10 digit invalid with qualifier array('a' => "1-54879-474-0 (hyphens and good checksum)"), //10 digit invalid with hyphens and qualifier array('a' => "1-54879-474-5 (hyphens and bad checksum)"), //10 digit invalid with hyphens and qualifier array('a' => "1548794740(10 : unspaced qualifier)"), //10 valid without space before qualifier array('a' => "1548794745(10 : unspaced qualifier : bad checksum)"), //10 invalid without space before qualifier array('z' => "1548794743"), //subfield z ); foreach ($testData as $current) { $subfields = array(); foreach ($current as $key => $value) { $subfields[] = new File_MARC_Subfield($key, $value); } $field = new File_MARC_Data_Field('020', $subfields, '', ''); $marc_lint->check020($field); } ?> --EXPECT-- 020: Subfield a has the wrong number of digits, 154879473. 020: Subfield a has bad checksum, 1548794743. 020: Subfield a has the wrong number of digits, 15487947443. 020: Subfield a has the wrong number of digits, 15487947443324. 020: Subfield a has bad checksum (13 digit), 9781548794745. 020: Subfield a has bad checksum, 1548794745 (10 : bad checksum). 020: Subfield a may have invalid characters. 020: Subfield a may have invalid characters. 020: Subfield a has bad checksum, 1-54879-474-5 (hyphens and bad checksum). 020: Subfield a qualifier must be preceded by space, 1548794740(10 : unspaced qualifier). 020: Subfield a qualifier must be preceded by space, 1548794745(10 : unspaced qualifier : bad checksum). 020: Subfield a has bad checksum, 1548794745(10 : unspaced qualifier : bad checksum). PK�����u]s}����3��test/File_MARC/tests/marc_xml_namespace_prefix.phptnu�[��������--TEST-- marc_xml_namespace: iterate and pretty print a MARC record --SKIPIF-- <?php include('tests/skipif.inc'); ?> --FILE-- <?php $dir = dirname(__FILE__); require __DIR__ . '/bootstrap.php'; $marc_file = new File_MARCXML($dir . '/' . 'namespace.xml',File_MARC::SOURCE_FILE,"marc",true); while ($marc_record = $marc_file->next()) { print $marc_record->getLeader(); print "\n"; $field = $marc_record->getField('050'); print $field->getIndicator(1); print "\n"; print $field->getIndicator(2); print "\n"; $subfield = $field->getSubfield('a'); print $subfield->getData(); print "\n"; } ?> --EXPECT-- 00925njm 22002777a 4500 0 0 Atlantic 1259 01832cmma 2200349 a 4500 0 0 F204.W5 PK�����u]}۶\p��p��$��test/File_MARC/tests/bad_example.xmlnu�[��������<collection xmlns="http://www.loc.gov/MARC21/slim"> <record> <leader>01850 a2200517 4500</leader> <controlfield tag="001">0000000044</controlfield> <controlfield tag="003">EMILDA</controlfield> <controlfield tag="008">980120s1998 fi j 000 0 swe</controlfield> <datafield tag="020" ind1=" " ind2=" "> <subfield code="a">9515008808</subfield> <subfield code="c">FIM 72:00</subfield> </datafield> <datafield tag="035" ind1=" " ind2=" "> <subfield code="9">9515008808</subfield> </datafield> <datafield tag="040" ind1=" " ind2=" "> <subfield code="a">NB</subfield> </datafield> <datafield tag="042" ind1=" " ind2=" "> <subfield code="9">NB</subfield> <subfield code="9">SEE</subfield> </datafield> <datafield tag="084" ind1=" " ind2=" "> <subfield code="a">Hcd,u</subfield> <subfield code="2">kssb/6</subfield> </datafield> <datafield tag="084" ind1=" " ind2=" "> <subfield code="5">NB</subfield> <subfield code="a">uHc</subfield> <subfield code="2">kssb</subfield> </datafield> <datafield tag="084" ind1=" " ind2=" "> <subfield code="5">SEE</subfield> <subfield code="a">Hcf</subfield> <subfield code="2">kssb/6</subfield> </datafield> <datafield tag="084" ind1=" " ind2=" "> <subfield code="5">Q</subfield> <subfield code="a">Hcd,uf</subfield> <subfield code="2">kssb/6</subfield> </datafield> <datafield tag="100" ind1="1" ind2=" "> <subfield code="a">Jansson, Tove,</subfield> <subfield code="d">1914-2001</subfield> </datafield> <datafield tag="245" ind1="0"> <subfield code="a">Det osynliga barnet och andra bert̃telser /</subfield> <subfield code="c">Tove Jansson</subfield> </datafield> <datafield tag="250" ind1=" " ind2=" "> <subfield code="a">7. uppl.</subfield> </datafield> <datafield tag="260" ind1=" " ind2=" "> <subfield code="a">Helsingfors :</subfield> <subfield code="b">Schildt,</subfield> <subfield code="c">1998 ;</subfield> <subfield code="e">(Falun :</subfield> <subfield code="f">Scandbook)</subfield> </datafield> <datafield tag="30-" ind1=" " ind2=" "> <subfield code="a">166, [4] s. :</subfield> <subfield code="b">ill. ;</subfield> <subfield code="c">21 cm</subfield> </datafield> <datafield tag="440" ind1=" " ind2="0"> <subfield code="a">Mumin-biblioteket,</subfield> <subfield code="x">99-0698931-9</subfield> </datafield> <datafield tag="500" ind1=" " ind2=" "> <subfield code="a">Originaluppl. 1962</subfield> </datafield> <datafield tag="599" ind1=" " ind2=" "> <subfield code="a">Li: S</subfield> </datafield> <datafield tag="740" ind1="4" ind2=" "> <subfield code="a">Det osynliga barnet</subfield> </datafield> <datafield tag="775" ind1="1" ind2=" "> <subfield code="z">951-50-0385-7</subfield> <subfield code="w">9515003857</subfield> <subfield code="9">07</subfield> </datafield> <datafield tag="841" ind1=" " ind2=" "> <subfield code="5">Li</subfield> <subfield code="a">xa</subfield> <subfield code="b">0201080u 0 4000uu |000000</subfield> <subfield code="e">1</subfield> </datafield> <datafield tag="841" ind1=" " ind2=" "> <subfield code="5">SEE</subfield> <subfield code="a">xa</subfield> <subfield code="b">0201080u 0 4000uu |000000</subfield> <subfield code="e">1</subfield> </datafield> <datafield tag="841" ind1=" " ind2=" "> <subfield code="5">L</subfield> <subfield code="a">xa</subfield> <subfield code="b">0201080u 0 4000uu |000000</subfield> <subfield code="e">1</subfield> </datafield> <datafield tag="841" ind1=" " ind2=" "> <subfield code="5">NB</subfield> <subfield code="a">xa</subfield> <subfield code="b">0201080u 0 4000uu |000000</subfield> <subfield code="e">1</subfield> </datafield> <datafield tag="841" ind1=" " ind2=" "> <subfield code="5">Q</subfield> <subfield code="a">xa</subfield> <subfield code="b">0201080u 0 4000uu |000000</subfield> <subfield code="e">1</subfield> </datafield> <datafield tag="841" ind1=" " ind2=" "> <subfield code="5">S</subfield> <subfield code="a">xa</subfield> <subfield code="b">0201080u 0 4000uu |000000</subfield> <subfield code="e">1</subfield> </datafield> <datafield tag="852" ind1=" " ind2=" "> <subfield code="5">NB</subfield> <subfield code="b">NB</subfield> <subfield code="c">NB98:12</subfield> <subfield code="h">plikt</subfield> <subfield code="j">R, 980520</subfield> </datafield> <datafield tag="852" ind1=" " ind2=" "> <subfield code="5">Li</subfield> <subfield code="b">Li</subfield> <subfield code="c">CNB</subfield> <subfield code="h">h,u</subfield> </datafield> <datafield tag="852" ind1=" " ind2=" "> <subfield code="5">SEE</subfield> <subfield code="b">SEE</subfield> </datafield> <datafield tag="852" ind1=" " ind2=" "> <subfield code="5">Q</subfield> <subfield code="b">Q</subfield> <subfield code="j">98947</subfield> </datafield> <datafield tag="852" ind1=" " ind2=" "> <subfield code="5">L</subfield> <subfield code="b">L</subfield> <subfield code="c">0100</subfield> <subfield code="h">98/</subfield> <subfield code="j">3043 H</subfield> </datafield> <datafield tag="852" ind1=" " ind2=" "> <subfield code="5">S</subfield> <subfield code="b">S</subfield> <subfield code="h">Sv97</subfield> <subfield code="j">7235</subfield> </datafield> <datafield tag="900" ind1="1" ind2="s"> <subfield code="a">Yanson, Tobe,</subfield> <subfield code="d">1914-2001</subfield> <subfield code="u">Jansson, Tove,</subfield> <subfield code="d">1914-2001</subfield> </datafield> <datafield tag="900" ind1="1" ind2="s"> <subfield code="a">Janssonov,̀ Tove,</subfield> <subfield code="d">1914-2001</subfield> <subfield code="u">Jansson, Tove,</subfield> <subfield code="d">1914-2001</subfield> </datafield> <datafield tag="900" ind1="1" ind2="s"> <subfield code="a">Jansone, Tuve,</subfield> <subfield code="d">1914-2001</subfield> <subfield code="u">Jansson, Tove,</subfield> <subfield code="d">1914-2001</subfield> </datafield> <datafield tag="900" ind1="1" ind2="s"> <subfield code="a">Janson, Tuve,</subfield> <subfield code="d">1914-2001</subfield> <subfield code="u">Jansson, Tove,</subfield> <subfield code="d">1914-2001</subfield> </datafield> <datafield tag="900" ind1="1" ind2="s"> <subfield code="a">Jansson, Tuve,</subfield> <subfield code="d">1914-2001</subfield> <subfield code="u">Jansson, Tove,</subfield> <subfield code="d">1914-2001</subfield> </datafield> <datafield tag="900" ind1="1" ind2="s"> <subfield code="a">Janssonova, Tove,</subfield> <subfield code="d">1914-2001</subfield> <subfield code="u">Jansson, Tove,</subfield> <subfield code="d">1914-2001</subfield> </datafield> <datafield tag="976" ind1=" " ind2="2"> <subfield code="a">Hcd,u</subfield> <subfield code="b">Skn̲litteratur</subfield> </datafield> <controlfield tag="005">20050204111518.0</controlfield> </record> </collection> PK�����u] ����(��test/File_MARC/tests/marc_field_005.phptnu�[��������--TEST-- marc_field_005: Test method getContents --SKIPIF-- <?php include('tests/skipif.inc'); ?> --FILE-- <?php $dir = dirname(__FILE__); require __DIR__ . '/bootstrap.php'; // create some subfields $subfields[] = new File_MARC_Subfield('a', 'nothing'); $subfields[] = new File_MARC_Subfield('z', 'everything'); // create a field $field = new File_MARC_Data_Field('100', $subfields, '0'); // create some new subfields $subfield1 = new File_MARC_Subfield('g', 'a little'); // test the fieldpost corner case by inserting prior to the first subfield $sf = $field->getSubfields('a'); // we might get an array back; in this case, we want the first subfield if (is_array($sf)) { $field->insertSubfield($subfield1, $sf[0], true); } else { $field->insertSubfield($subfield1, $sf, true); } // let's see the results print $field->getContents(); print "\n"; print $field->getContents('###'); print "\n"; ?> --EXPECT-- a littlenothingeverything a little###nothing###everything PK�����u]p̎u1��u1��"��test/File_MARC/tests/marc_016.phptnu�[��������--TEST-- marc_016: generate a single collection of MARCXML records from a MARC record --SKIPIF-- <?php include('tests/skipif.inc'); ?> --FILE-- <?php $dir = dirname(__FILE__); require __DIR__ . '/bootstrap.php'; $records = new File_MARC($dir . '/' . 'music.mrc'); // Add the XML header and opening <collection> element $records->toXMLHeader(); // Iterate through the retrieved records while ($record = $records->next()) { // Change each 852 $c to "Audio-Visual" $holdings = $record->getFields('852'); foreach ($holdings as $holding) { // Get the $c subfields from this field $formats = $holding->getSubfields('c'); foreach ($formats as $format) { if ($format->getData('AV')) { $format->setData('Audio-Visual'); } } } // Generate the XML output for this record print $record->toXML('UTF-8', true, false); } // Add the </collection> closing element and dump the XMLWriter contents print $records->toXMLFooter(); --EXPECT-- <?xml version="1.0" encoding="UTF-8"?> <collection xmlns="http://www.loc.gov/MARC21/slim"> <record xmlns="http://www.loc.gov/MARC21/slim"> <leader>01145ncm 2200277 i 4500</leader> <controlfield tag="001">000073594</controlfield> <controlfield tag="004">AAJ5802</controlfield> <controlfield tag="005">20030415102100.0</controlfield> <controlfield tag="008">801107s1977 nyujza </controlfield> <datafield tag="010" ind1=" " ind2=" "> <subfield code="a"> 77771106 </subfield> </datafield> <datafield tag="035" ind1=" " ind2=" "> <subfield code="a">(CaOTUIC)15460184</subfield> </datafield> <datafield tag="035" ind1="9" ind2=" "> <subfield code="a">AAJ5802</subfield> </datafield> <datafield tag="040" ind1=" " ind2=" "> <subfield code="a">LC</subfield> </datafield> <datafield tag="050" ind1="0" ind2="0"> <subfield code="a">M1366</subfield> <subfield code="b">.M62</subfield> <subfield code="d">M1527.2</subfield> </datafield> <datafield tag="245" ind1="0" ind2="4"> <subfield code="a">The Modern Jazz Quartet :</subfield> <subfield code="b">The legendary profile. --</subfield> </datafield> <datafield tag="260" ind1=" " ind2=" "> <subfield code="a">New York :</subfield> <subfield code="b">M.J.Q. Music,</subfield> <subfield code="c">c1977.</subfield> </datafield> <datafield tag="300" ind1=" " ind2=" "> <subfield code="a">score (72 p.) ;</subfield> <subfield code="c">31 cm.</subfield> </datafield> <datafield tag="500" ind1=" " ind2=" "> <subfield code="a">For piano, vibraphone, drums, and double bass.</subfield> </datafield> <datafield tag="505" ind1="0" ind2=" "> <subfield code="a">Lewis, J. Django.--Lewis, J. Plastic dreams (music from the film Kemek).--Lewis, J. Dancing (music from the film Kemek).--Lewis, J. Blues in A minor.--Lewis, J. Blues in B♭.--Lewis, J. Precious joy.--Jackson, M. The martyr.--Jackson, M. The legendary profile.</subfield> </datafield> <datafield tag="650" ind1=" " ind2="0"> <subfield code="a">Jazz.</subfield> </datafield> <datafield tag="650" ind1=" " ind2="0"> <subfield code="a">Motion picture music</subfield> <subfield code="v">Excerpts</subfield> <subfield code="v">Scores.</subfield> </datafield> <datafield tag="700" ind1="1" ind2="2"> <subfield code="a">Lewis, John,</subfield> <subfield code="d">1920-</subfield> <subfield code="t">Selections.</subfield> <subfield code="f">1977.</subfield> </datafield> <datafield tag="700" ind1="1" ind2="2"> <subfield code="a">Jackson, Milt.</subfield> <subfield code="t">Martyrs.</subfield> <subfield code="f">1977.</subfield> </datafield> <datafield tag="700" ind1="1" ind2="2"> <subfield code="a">Jackson, Milt.</subfield> <subfield code="t">Legendary profile.</subfield> <subfield code="f">1977.</subfield> </datafield> <datafield tag="740" ind1="4" ind2=" "> <subfield code="a">The legendary profile.</subfield> </datafield> <datafield tag="852" ind1="0" ind2="0"> <subfield code="b">MUSIC</subfield> <subfield code="c">Audio-Visual</subfield> <subfield code="k">folio</subfield> <subfield code="h">M1366</subfield> <subfield code="i">M62</subfield> <subfield code="9">1</subfield> <subfield code="4">Marvin Duchow Music</subfield> <subfield code="5"></subfield> </datafield> </record> <record xmlns="http://www.loc.gov/MARC21/slim"> <leader>01293cjm 2200289 a 4500</leader> <controlfield tag="001">001878039</controlfield> <controlfield tag="005">20050110174900.0</controlfield> <controlfield tag="007">sd fungnn|||e|</controlfield> <controlfield tag="008">940202r19931981nyujzn i d</controlfield> <datafield tag="024" ind1="1" ind2=" "> <subfield code="a">7464573372</subfield> </datafield> <datafield tag="028" ind1="0" ind2="2"> <subfield code="a">JK 57337</subfield> <subfield code="b">Red Baron</subfield> </datafield> <datafield tag="035" ind1=" " ind2=" "> <subfield code="a">(OCoLC)29737267</subfield> </datafield> <datafield tag="040" ind1=" " ind2=" "> <subfield code="a">SVP</subfield> <subfield code="c">SVP</subfield> <subfield code="d">LGG</subfield> </datafield> <datafield tag="100" ind1="1" ind2=" "> <subfield code="a">Desmond, Paul,</subfield> <subfield code="d">1924-</subfield> </datafield> <datafield tag="245" ind1="1" ind2="0"> <subfield code="a">Paul Desmond & the Modern Jazz Quartet</subfield> <subfield code="h">[sound recording]</subfield> </datafield> <datafield tag="260" ind1=" " ind2=" "> <subfield code="a">New York, N.Y. :</subfield> <subfield code="b">Red Baron :</subfield> <subfield code="b">Manufactured by Sony Music Entertainment,</subfield> <subfield code="c">p1993.</subfield> </datafield> <datafield tag="300" ind1=" " ind2=" "> <subfield code="a">1 sound disc (39 min.) :</subfield> <subfield code="b">digital ;</subfield> <subfield code="c">4 3/4 in.</subfield> </datafield> <datafield tag="511" ind1="0" ind2=" "> <subfield code="a">Paul Desmond, alto saxophone; Modern Jazz Quartet: John Lewis, piano; Milt Jackson, vibraphone; Percy Heath, bass; Connie Kay, drums.</subfield> </datafield> <datafield tag="500" ind1=" " ind2=" "> <subfield code="a">All arrangements by John Lewis.</subfield> </datafield> <datafield tag="518" ind1=" " ind2=" "> <subfield code="a">Recorded live on December 25, 1971 at Town Hall, NYC.</subfield> </datafield> <datafield tag="500" ind1=" " ind2=" "> <subfield code="a">Originally released in 1981 by Finesse as LP FW 27487.</subfield> </datafield> <datafield tag="500" ind1=" " ind2=" "> <subfield code="a">Program notes by Irving Townsend, June 1981, on container insert.</subfield> </datafield> <datafield tag="505" ind1="0" ind2=" "> <subfield code="a">Greensleeves -- You go to my head -- Blue dove -- Jesus Christ Superstar -- Here's that rainy day -- East of the sun -- Bags' new groove.</subfield> </datafield> <datafield tag="650" ind1=" " ind2="0"> <subfield code="a">Jazz</subfield> <subfield code="y">1971-1980.</subfield> </datafield> <datafield tag="700" ind1="1" ind2=" "> <subfield code="a">Lewis, John,</subfield> <subfield code="d">1920-</subfield> </datafield> <datafield tag="710" ind1="2" ind2=" "> <subfield code="a">Modern Jazz Quartet.</subfield> </datafield> <datafield tag="740" ind1="0" ind2=" "> <subfield code="a">Paul Desmond and the Modern Jazz Quartet.</subfield> </datafield> </record> <record xmlns="http://www.loc.gov/MARC21/slim"> <leader>01829cjm 2200385 a 4500</leader> <controlfield tag="001">001964482</controlfield> <controlfield tag="005">20060626132700.0</controlfield> <controlfield tag="007">sd fzngnn|m|e|</controlfield> <controlfield tag="008">871211p19871957nyujzn d</controlfield> <datafield tag="024" ind1="1" ind2=" "> <subfield code="a">4228332902</subfield> </datafield> <datafield tag="028" ind1="0" ind2="1"> <subfield code="a">833 290-2</subfield> <subfield code="b">Verve</subfield> </datafield> <datafield tag="033" ind1="0" ind2=" "> <subfield code="a">19571027</subfield> <subfield code="b">6299</subfield> <subfield code="c">D56</subfield> </datafield> <datafield tag="033" ind1="0" ind2=" "> <subfield code="a">196112--</subfield> <subfield code="b">3804</subfield> <subfield code="c">N4</subfield> </datafield> <datafield tag="033" ind1="0" ind2=" "> <subfield code="a">19571019</subfield> <subfield code="b">4104</subfield> <subfield code="c">C6</subfield> </datafield> <datafield tag="033" ind1="0" ind2=" "> <subfield code="a">197107--</subfield> <subfield code="b">6299</subfield> <subfield code="c">V7</subfield> </datafield> <datafield tag="035" ind1=" " ind2=" "> <subfield code="a">(OCoLC)17222092</subfield> </datafield> <datafield tag="040" ind1=" " ind2=" "> <subfield code="a">CPL</subfield> <subfield code="c">CPL</subfield> <subfield code="d">OCL</subfield> <subfield code="d">LGG</subfield> </datafield> <datafield tag="048" ind1=" " ind2=" "> <subfield code="a">pz01</subfield> <subfield code="a">ka01</subfield> <subfield code="a">sd01</subfield> <subfield code="a">pd01</subfield> </datafield> <datafield tag="110" ind1="2" ind2=" "> <subfield code="a">Modern Jazz Quartet.</subfield> <subfield code="4">prf</subfield> </datafield> <datafield tag="245" ind1="1" ind2="4"> <subfield code="a">The Modern Jazz Quartet plus</subfield> <subfield code="h">[sound recording].</subfield> </datafield> <datafield tag="260" ind1=" " ind2=" "> <subfield code="a">[New York] :</subfield> <subfield code="b">Verve,</subfield> <subfield code="c">p1987.</subfield> </datafield> <datafield tag="300" ind1=" " ind2=" "> <subfield code="a">1 sound disc :</subfield> <subfield code="b">digital ;</subfield> <subfield code="c">4 3/4 in.</subfield> </datafield> <datafield tag="440" ind1=" " ind2="0"> <subfield code="a">Compact jazz</subfield> </datafield> <datafield tag="511" ind1="0" ind2=" "> <subfield code="a">Modern Jazz Quartet (principally) ; Milt Jackson, vibraphone (2nd and 8th works) ; Oscar Peterson, piano (2nd and 8th works) ; Ray Brown, bass (2nd and 8th works) ; Ed Thigpen (2nd work), Louis Hayes (8th work), drums.</subfield> </datafield> <datafield tag="518" ind1=" " ind2=" "> <subfield code="a">Recorded live, Oct. 27, 1957, at the Donaueschingen Jazz Festival (1st, 5th, 7th, and 10th works); Dec. 1961, in New York (2nd work); live, Oct. 19, 1957, at the Opera House, Chicago (3rd, 4th, 6th, and 9th works); July 1971, in Villingen, Germany (8th work).</subfield> </datafield> <datafield tag="500" ind1=" " ind2=" "> <subfield code="a">Compact disc.</subfield> </datafield> <datafield tag="500" ind1=" " ind2=" "> <subfield code="a">Analog recording.</subfield> </datafield> <datafield tag="505" ind1="0" ind2=" "> <subfield code="a">The golden striker (4:08) -- On Green Dolphin Street (7:28) -- D & E (4:55) -- I'll remember April (4:51) -- Cortège (7:15) -- Now's the time (4:43) -- J.B. blues (5:09) -- Reunion blues (6:35) -- 'Round midnight (3:56) -- Three windows (7:20).</subfield> </datafield> <datafield tag="650" ind1=" " ind2="0"> <subfield code="a">Jazz.</subfield> </datafield> <datafield tag="700" ind1="1" ind2=" "> <subfield code="a">Jackson, Milt.</subfield> <subfield code="4">prf</subfield> </datafield> <datafield tag="700" ind1="1" ind2=" "> <subfield code="a">Peterson, Oscar,</subfield> <subfield code="d">1925-</subfield> <subfield code="4">prf</subfield> </datafield> <datafield tag="700" ind1="1" ind2=" "> <subfield code="a">Brown, Ray,</subfield> <subfield code="d">1926-2002.</subfield> <subfield code="4">prf</subfield> </datafield> <datafield tag="700" ind1="1" ind2=" "> <subfield code="a">Thigpen, Ed.</subfield> <subfield code="4">prf</subfield> </datafield> <datafield tag="700" ind1="1" ind2=" "> <subfield code="a">Hayes, Louis,</subfield> <subfield code="d">1937-</subfield> <subfield code="4">prf</subfield> </datafield> <datafield tag="852" ind1="8" ind2="0"> <subfield code="b">MUSIC</subfield> <subfield code="c">Audio-Visual</subfield> <subfield code="h">CD 1131</subfield> <subfield code="4">Marvin Duchow Music</subfield> <subfield code="5">Audio-Visual</subfield> </datafield> </record> </collection> PK�����u](N��N����test/File_MARC/tests/camel.mrcnu�[��������00755cam 22002414a 4500001001300000003000600013005001700019008004100036010001700077020004300094040001800137042000800155050002600163082001700189100003100206245005400237260004200291300007200333500003300405650003700438630002500475630001300500fol05731351 IMchF20000613133448.0000107s2000 nyua 001 0 eng  a 00020737  a0471383147 (paper/cd-rom : alk. paper) aDLCcDLCdDLC apcc00aQA76.73.P22bM33 200000a005.13/32211 aMartinsson, Tobias,d1976-10aActivePerl with ASP and ADO /cTobias Martinsson. aNew York :bJohn Wiley & Sons,c2000. axxi, 289 p. :bill. ;c23 cm. +e1 computer laser disc (4 3/4 in.) a"Wiley Computer Publishing." 0aPerl (Computer program language)00aActive server pages.00aActiveX.00647pam 2200241 a 4500001001300000003000600013005001700019008004100036010001700077020001500094040001800109042000800127050002600135082001500161100002600176245006700202260003800269263000900307300001100316650003700327650002500364700001600389fol05754809 IMchF20000601115601.0000203s2000 mau 001 0 eng  a 00022023  a1565926994 aDLCcDLCdDLC apcc00aQA76.73.P22bD47 200000a005.742211 aDescartes, Alligator.10aProgramming the Perl DBI /cAlligator Descartes and Tim Bunce. aCmabridge, MA :bO'Reilly,c2000. a1111 ap. cm. 0aPerl (Computer program language) 0aDatabase management.1 aBunce, Tim.00605cam 22002054a 4500001001300000003000600013005001700019008004100036010001700077040001800094042000800112050002700120082001700147100002100164245005500185260004500240300002600285504005100311650003700362fol05843555 IMchF20000525142739.0000318s1999 cau b 001 0 eng  a 00501349  aDLCcDLCdDLC apcc00aQA76.73.P22bB763 199900a005.13/32211 aBrown, Martin C.10aPerl :bprogrammer's reference /cMartin C. Brown. aBerkeley :bOsborne/McGraw-Hill,cc1999. axix, 380 p. ;c22 cm. aIncludes bibliographical references and index. 0aPerl (Computer program language)00579cam 22002054a 4500001001300000003000600013005001700019008004100036010001700077020001500094040001800109042000800127050002700135082001700162100002100179245005500200260004500255300003600300650003700336fol05843579 IMchF20000525142716.0000318s1999 caua 001 0 eng  a 00502116  a0072120002 aDLCcDLCdDLC apcc00aQA76.73.P22bB762 199900a005.13/32211 aBrown, Martin C.10aPerl :bthe complete reference /cMartin C. Brown. aBerkeley :bOsborne/McGraw-Hill,cc1999. axxxv, 1179 p. :bill. ;c24 cm. 0aPerl (Computer program language)00801nam 22002778a 4500001001300000003000600013005001700019008004100036010001700077020001500094040001300109042000800122050002600130082001800156100002000174245008800194250003200282260004100314263000900355300001100364650003700375650003600412650002600448700002500474700002400499fol05848297 IMchF20000524125727.0000518s2000 mau 001 0 eng  a 00041664  a1565924193 aDLCcDLC apcc00aQA76.73.P22bG84 200000a005.2/7622211 aGuelich, Scott.10aCGI programming with Perl /cScott Guelich, Shishir Gundavaram & Gunther Birznieks. a2nd ed., expanded & updated aCambridge, Mass. :bO'Reilly,c2000. a0006 ap. cm. 0aPerl (Computer program language) 0aCGI (Computer network protocol) 0aInternet programming.1 aGundavaram, Shishir.1 aBirznieks, Gunther.00665nam 22002298a 4500001001300000003000600013005001700019008004100036010001700077020001500094040001300109042000800122050002700130082001700157111005200174245008600226250001200312260004100324263000900365300001100374650005000385fol05865950 IMchF20000615103017.0000612s2000 mau 100 0 eng  a 00055759  a0596000138 aDLCcDLC apcc00aQA76.73.P22bP475 200000a005.13/32212 aPerl Conference 4.0d(2000 :cMonterey, Calif.)10aProceedings of the Perl Conference 4.0 :bJuly 17-20, 2000, Monterey, California. a1st ed. aCambridge, Mass. :bO'Reilly,c2000. a0006 ap. cm. 0aPerl (Computer program language)vCongresses.00579nam 22002178a 4500001001300000003000600013005001700019008004100036010001700077020001500094040001300109042000800122050002600130082001700156100002800173245006200201260004100263263000900304300001100313650003700324fol05865956 IMchF20000615102948.0000612s2000 mau 000 0 eng  a 00055770  a1565926099 aDLCcDLC apcc00aQA76.73.P22bB43 200000a005.13/32211 aBlank-Edelman, David N.10aPerl for system administration /cDavid N. Blank-Edelman. aCambridge, Mass. :bO'Reilly,c2000. a0006 ap. cm. 0aPerl (Computer program language)00661nam 22002538a 4500001001300000003000600013005001700019008004100036010001700077020001500094040001300109042000800122050002600130082001700156100001700173245006700190250001200257260004100269263000900310300001100319650003700330700002300367700001700390fol05865967 IMchF20000615102611.0000614s2000 mau 000 0 eng  a 00055799  a0596000278 aDLCcDLC apcc00aQA76.73.P22bW35 200000a005.13/32211 aWall, Larry.10aProgramming Perl /cLarry Wall, Tom Christiansen & Jon Orwant. a3rd ed. aCambridge, Mass. :bO'Reilly,c2000. a0007 ap. cm. 0aPerl (Computer program language)1 aChristiansen, Tom.1 aOrwant, Jon.00603cam 22002054a 4500001001300000003000600013005001700019008004100036010001700077020001500094040001800109042000800127050002600135082001700161100003200178245006000210260005700270300003300327650003700360fol05872355 IMchF20000706095105.0000315s1999 njua 001 0 eng  a 00500678  a013020868X aDLCcDLCdDLC apcc00aQA76.73.P22bL69 199900a005.13/32211 aLowe, Vincentq(Vincent D.)10aPerl programmer's interactive workbook /cVincent Lowe. aUpper Saddle River, NJ :bPrentice Hall PTP,cc1999. axx, 633 p. :bill. ;c23 cm. 0aPerl (Computer program language)00696nam 22002538a 4500001001300000003000600013005001700019008004100036010001700077020002800094040001300122042000800135050002600143082001700169100002600186245004400212260005100256263000900307300001100316500002000327650003700347650001700384650004100401fol05882032 IMchF20000707091904.0000630s2000 cau 001 0 eng  a 00058174  a0764547291 (alk. paper) aDLCcDLC apcc00aQA76.73.P22bF64 200000a005.13/32212 aFoster-Johnson, Eric.10aCross-platform Perl /cEric F. Johnson. aFoster City, CA :bIDG Books Worldwide,c2000. a0009 ap. cm. aIncludes index. 0aPerl (Computer program language) 0aWeb servers. 0aCross-platform software development.00399ngm 2200121 a 4500001001300000003000700013007002800020008004100048245005600089260003800145300006000183538003400243ttt05000099 TEST avbfc dcebfaghhoiu050224s2005 ilu999 vleng d00aTest subfields in control fieldsh[videorecording]. aOregon, Ill. :bB. Baldus,c2005. a1 videocassette (ca. 1000 min.) :bsd., col. ;c1/2 in. aVHS format, SP playback mode.PK�����u])] �� ��"��test/File_MARC/tests/marc_005.phptnu�[��������--TEST-- marc_005: Ensure a duplicated record is a deep copy; test deleteFields() --SKIPIF-- <?php include('tests/skipif.inc'); ?> --FILE-- <?php $dir = dirname(__FILE__); require __DIR__ . '/bootstrap.php'; $marc_file = new File_MARC($dir . '/' . 'example.mrc'); $marc_record = $marc_file->next(); $copy_record = $marc_record; $duplicate_record = clone $marc_record; $num_deleted1 = $marc_record->deleteFields('020'); print "Deleted $num_deleted1 fields from the original record.\n"; $num_deleted2 = $copy_record->deleteFields('8\\d\\d', true); print "Deleted $num_deleted2 fields from the shallow copy record.\n"; $num_deleted3 = $duplicate_record->deleteFields('9\\d\\d', true); print "Deleted $num_deleted3 fields from the duplicate record.\n"; print "Original:\n"; print $marc_record; print "\nCopy:\n"; print $copy_record; print "\nDuplicate:\n"; print $duplicate_record; print "\n"; ?> --EXPECT-- Deleted 1 fields from the original record. Deleted 12 fields from the shallow copy record. Deleted 7 fields from the duplicate record. Original: LDR 01850 2200517 4500 001 0000000044 003 EMILDA 008 980120s1998 fi j 000 0 swe 035 _99515008808 040 _aNB 042 _9NB _9SEE 084 _aHcd,u _2kssb/6 084 _5NB _auHc _2kssb 084 _5SEE _aHcf _2kssb/6 084 _5Q _aHcd,uf _2kssb/6 100 1 _aJansson, Tove, _d1914-2001 245 04 _aDet osynliga barnet och andra berttelser / _cTove Jansson 250 _a7. uppl. 260 _aHelsingfors : _bSchildt, _c1998 ; _e(Falun : _fScandbook) 300 _a166, [4] s. : _bill. ; _c21 cm 440 0 _aMumin-biblioteket, _x99-0698931-9 500 _aOriginaluppl. 1962 599 _aLi: S 740 4 _aDet osynliga barnet 775 1 _z951-50-0385-7 _w9515003857 _907 005 20050204111518.0 Copy: LDR 01850 2200517 4500 001 0000000044 003 EMILDA 008 980120s1998 fi j 000 0 swe 035 _99515008808 040 _aNB 042 _9NB _9SEE 084 _aHcd,u _2kssb/6 084 _5NB _auHc _2kssb 084 _5SEE _aHcf _2kssb/6 084 _5Q _aHcd,uf _2kssb/6 100 1 _aJansson, Tove, _d1914-2001 245 04 _aDet osynliga barnet och andra berttelser / _cTove Jansson 250 _a7. uppl. 260 _aHelsingfors : _bSchildt, _c1998 ; _e(Falun : _fScandbook) 300 _a166, [4] s. : _bill. ; _c21 cm 440 0 _aMumin-biblioteket, _x99-0698931-9 500 _aOriginaluppl. 1962 599 _aLi: S 740 4 _aDet osynliga barnet 775 1 _z951-50-0385-7 _w9515003857 _907 005 20050204111518.0 Duplicate: LDR 01850 2200517 4500 001 0000000044 003 EMILDA 008 980120s1998 fi j 000 0 swe 035 _99515008808 040 _aNB 042 _9NB _9SEE 084 _aHcd,u _2kssb/6 084 _5NB _auHc _2kssb 084 _5SEE _aHcf _2kssb/6 084 _5Q _aHcd,uf _2kssb/6 100 1 _aJansson, Tove, _d1914-2001 245 04 _aDet osynliga barnet och andra berttelser / _cTove Jansson 250 _a7. uppl. 260 _aHelsingfors : _bSchildt, _c1998 ; _e(Falun : _fScandbook) 300 _a166, [4] s. : _bill. ; _c21 cm 440 0 _aMumin-biblioteket, _x99-0698931-9 500 _aOriginaluppl. 1962 599 _aLi: S 740 4 _aDet osynliga barnet 775 1 _z951-50-0385-7 _w9515003857 _907 005 20050204111518.0 PK�����u]W)��)��"��test/File_MARC/tests/marc_019.phptnu�[��������--TEST-- marc_019: generate a MARCXML record not in a collection element --SKIPIF-- <?php include('tests/skipif.inc'); ?> --FILE-- <?php $dir = dirname(__FILE__); require __DIR__ . '/bootstrap.php'; $records = new File_MARC($dir . '/' . 'music.mrc'); // Iterate through the retrieved records $record = $records->next(); // Change each 852 $c to "Audio-Visual" $holdings = $record->getFields('852'); foreach ($holdings as $holding) { // Get the $c subfields from this field $formats = $holding->getSubfields('c'); foreach ($formats as $format) { if ($format->getData('AV')) { $format->setData('Audio-Visual'); } } } // Generate the XML output for this record print($record->toXML('UTF-8', true, true)); --EXPECT-- <?xml version="1.0" encoding="UTF-8"?> <collection xmlns="http://www.loc.gov/MARC21/slim"> <record> <leader>01145ncm 2200277 i 4500</leader> <controlfield tag="001">000073594</controlfield> <controlfield tag="004">AAJ5802</controlfield> <controlfield tag="005">20030415102100.0</controlfield> <controlfield tag="008">801107s1977 nyujza </controlfield> <datafield tag="010" ind1=" " ind2=" "> <subfield code="a"> 77771106 </subfield> </datafield> <datafield tag="035" ind1=" " ind2=" "> <subfield code="a">(CaOTUIC)15460184</subfield> </datafield> <datafield tag="035" ind1="9" ind2=" "> <subfield code="a">AAJ5802</subfield> </datafield> <datafield tag="040" ind1=" " ind2=" "> <subfield code="a">LC</subfield> </datafield> <datafield tag="050" ind1="0" ind2="0"> <subfield code="a">M1366</subfield> <subfield code="b">.M62</subfield> <subfield code="d">M1527.2</subfield> </datafield> <datafield tag="245" ind1="0" ind2="4"> <subfield code="a">The Modern Jazz Quartet :</subfield> <subfield code="b">The legendary profile. --</subfield> </datafield> <datafield tag="260" ind1=" " ind2=" "> <subfield code="a">New York :</subfield> <subfield code="b">M.J.Q. Music,</subfield> <subfield code="c">c1977.</subfield> </datafield> <datafield tag="300" ind1=" " ind2=" "> <subfield code="a">score (72 p.) ;</subfield> <subfield code="c">31 cm.</subfield> </datafield> <datafield tag="500" ind1=" " ind2=" "> <subfield code="a">For piano, vibraphone, drums, and double bass.</subfield> </datafield> <datafield tag="505" ind1="0" ind2=" "> <subfield code="a">Lewis, J. Django.--Lewis, J. Plastic dreams (music from the film Kemek).--Lewis, J. Dancing (music from the film Kemek).--Lewis, J. Blues in A minor.--Lewis, J. Blues in B♭.--Lewis, J. Precious joy.--Jackson, M. The martyr.--Jackson, M. The legendary profile.</subfield> </datafield> <datafield tag="650" ind1=" " ind2="0"> <subfield code="a">Jazz.</subfield> </datafield> <datafield tag="650" ind1=" " ind2="0"> <subfield code="a">Motion picture music</subfield> <subfield code="v">Excerpts</subfield> <subfield code="v">Scores.</subfield> </datafield> <datafield tag="700" ind1="1" ind2="2"> <subfield code="a">Lewis, John,</subfield> <subfield code="d">1920-</subfield> <subfield code="t">Selections.</subfield> <subfield code="f">1977.</subfield> </datafield> <datafield tag="700" ind1="1" ind2="2"> <subfield code="a">Jackson, Milt.</subfield> <subfield code="t">Martyrs.</subfield> <subfield code="f">1977.</subfield> </datafield> <datafield tag="700" ind1="1" ind2="2"> <subfield code="a">Jackson, Milt.</subfield> <subfield code="t">Legendary profile.</subfield> <subfield code="f">1977.</subfield> </datafield> <datafield tag="740" ind1="4" ind2=" "> <subfield code="a">The legendary profile.</subfield> </datafield> <datafield tag="852" ind1="0" ind2="0"> <subfield code="b">MUSIC</subfield> <subfield code="c">Audio-Visual</subfield> <subfield code="k">folio</subfield> <subfield code="h">M1366</subfield> <subfield code="i">M62</subfield> <subfield code="9">1</subfield> <subfield code="4">Marvin Duchow Music</subfield> <subfield code="5"></subfield> </datafield> </record> </collection> PK�����u]=O �� ��!��test/File_MARC/tests/sandburg.xmlnu�[��������<?xml version="1.0" encoding="UTF-8"?> <collection xmlns="http://www.loc.gov/MARC21/slim"> <record> <leader>01142cam 2200301 a 4500</leader> <controlfield tag="001"> 92005291 </controlfield> <controlfield tag="003">DLC</controlfield> <controlfield tag="005">19930521155141.9</controlfield> <controlfield tag="008">920219s1993 caua j 000 0 eng </controlfield> <datafield tag="010" ind1=" " ind2=" "> <subfield code="a"> 92005291 </subfield> </datafield> <datafield tag="020" ind1=" " ind2=" "> <subfield code="a">0152038655 :</subfield> <subfield code="c">$15.95</subfield> </datafield> <datafield tag="040" ind1=" " ind2=" "> <subfield code="a">DLC</subfield> <subfield code="c">DLC</subfield> <subfield code="d">DLC</subfield> </datafield> <datafield tag="042" ind1=" " ind2=" "> <subfield code="a">lcac</subfield> </datafield> <datafield tag="050" ind1="0" ind2="0"> <subfield code="a">PS3537.A618</subfield> <subfield code="b">A88 1993</subfield> </datafield> <datafield tag="082" ind1="0" ind2="0"> <subfield code="a">811/.52</subfield> <subfield code="2">20</subfield> </datafield> <datafield tag="100" ind1="1" ind2=" "> <subfield code="a">Sandburg, Carl,</subfield> <subfield code="d">1878-1967.</subfield> </datafield> <datafield tag="245" ind1="1" ind2="0"> <subfield code="a">Arithmetic /</subfield> <subfield code="c">Carl Sandburg ; illustrated as an anamorphic adventure by Ted Rand.</subfield> </datafield> <datafield tag="250" ind1=" " ind2=" "> <subfield code="a">1st ed.</subfield> </datafield> <datafield tag="260" ind1=" " ind2=" "> <subfield code="a">San Diego :</subfield> <subfield code="b">Harcourt Brace Jovanovich,</subfield> <subfield code="c">c1993.</subfield> </datafield> <datafield tag="300" ind1=" " ind2=" "> <subfield code="a">1 v. (unpaged) :</subfield> <subfield code="b">ill. (some col.) ;</subfield> <subfield code="c">26 cm.</subfield> </datafield> <datafield tag="500" ind1=" " ind2=" "> <subfield code="a">One Mylar sheet included in pocket.</subfield> </datafield> <datafield tag="520" ind1=" " ind2=" "> <subfield code="a">A poem about numbers and their characteristics. Features anamorphic, or distorted, drawings which can be restored to normal by viewing from a particular angle or by viewing the image's reflection in the provided Mylar cone.</subfield> </datafield> <datafield tag="650" ind1=" " ind2="0"> <subfield code="a">Arithmetic</subfield> <subfield code="x">Juvenile poetry.</subfield> </datafield> <datafield tag="650" ind1=" " ind2="0"> <subfield code="a">Children's poetry, American.</subfield> </datafield> <datafield tag="650" ind1=" " ind2="1"> <subfield code="a">Arithmetic</subfield> <subfield code="x">Poetry.</subfield> </datafield> <datafield tag="650" ind1=" " ind2="1"> <subfield code="a">American poetry.</subfield> </datafield> <datafield tag="650" ind1=" " ind2="1"> <subfield code="a">Visual perception.</subfield> </datafield> <datafield tag="700" ind1="1" ind2=" "> <subfield code="a">Rand, Ted,</subfield> <subfield code="e">ill.</subfield> </datafield> </record> </collection> PK�����u] VU,��,��*��test/File_MARC/tests/marc_field_21246.phptnu�[��������--TEST-- marc_field_21246: Delete multiple subfields --SKIPIF-- <?php include('tests/skipif.inc'); ?> --FILE-- <?php $dir = dirname(__FILE__); require __DIR__ . '/bootstrap.php'; $field = new File_MARC_Data_Field(650, [ new File_MARC_Subfield('9', 'test1'), new File_MARC_Subfield('9', 'test2'), new File_MARC_Subfield('0', 'test3'), new File_MARC_Subfield('9', 'test4'), ] ); echo "--- Before: ---\n$field\n\n"; foreach ($field->getSubfields('9') as $subfield) { echo "Deleting subfield: $subfield\n"; $field->deleteSubfield($subfield); } echo "\n--- After: ---\n$field\n\n"; ?> --EXPECT-- --- Before: --- 650 _9test1 _9test2 _0test3 _9test4 Deleting subfield: [9]: test1 Deleting subfield: [9]: test2 Deleting subfield: [9]: test4 --- After: --- 650 _0test3 PK�����u]O~iK!��K!��"��test/File_MARC/tests/marc_013.phptnu�[��������--TEST-- marc_013: test formatField() convenience method --SKIPIF-- <?php include('tests/skipif.inc'); ?> --FILE-- <?php $dir = dirname(__FILE__); require __DIR__ . '/bootstrap.php'; $marc_file = new File_MARC($dir . '/' . 'music.mrc'); while ($marc_record = $marc_file->next()) { $fields = $marc_record->getFields(); foreach ($fields as $field) { print $field; print "\n"; print $field->formatField(); print "\n"; print $field->formatField(array('a', '2', 'c')); print "\n"; } } ?> --EXPECT-- 001 000073594 000073594 000073594 004 AAJ5802 AAJ5802 AAJ5802 005 20030415102100.0 20030415102100.0 20030415102100.0 008 801107s1977 nyujza 801107s1977 nyujza 801107s1977 nyujza 010 _a 77771106 77771106 035 _a(CaOTUIC)15460184 (CaOTUIC)15460184 035 9 _aAAJ5802 AAJ5802 040 _aLC LC 050 00 _aM1366 _b.M62 _dM1527.2 M1366 .M62 M1527.2 .M62 M1527.2 245 04 _aThe Modern Jazz Quartet : _bThe legendary profile. -- The Modern Jazz Quartet : The legendary profile. -- The legendary profile. -- 260 _aNew York : _bM.J.Q. Music, _cc1977. New York : M.J.Q. Music, c1977. M.J.Q. Music, 300 _ascore (72 p.) ; _c31 cm. score (72 p.) ; 31 cm. 500 _aFor piano, vibraphone, drums, and double bass. For piano, vibraphone, drums, and double bass. 505 0 _aLewis, J. Django.--Lewis, J. Plastic dreams (music from the film Kemek).--Lewis, J. Dancing (music from the film Kemek).--Lewis, J. Blues in A minor.--Lewis, J. Blues in B♭.--Lewis, J. Precious joy.--Jackson, M. The martyr.--Jackson, M. The legendary profile. Lewis, J. Django.--Lewis, J. Plastic dreams (music from the film Kemek).--Lewis, J. Dancing (music from the film Kemek).--Lewis, J. Blues in A minor.--Lewis, J. Blues in B♭.--Lewis, J. Precious joy.--Jackson, M. The martyr.--Jackson, M. The legendary profile. 650 0 _aJazz. Jazz. 650 0 _aMotion picture music _vExcerpts _vScores. Motion picture music -- Excerpts -- Scores. -- Excerpts -- Scores. 700 12 _aLewis, John, _d1920- _tSelections. _f1977. Lewis, John, 1920- Selections. 1977. 1920- Selections. 1977. 700 12 _aJackson, Milt. _tMartyrs. _f1977. Jackson, Milt. Martyrs. 1977. Martyrs. 1977. 700 12 _aJackson, Milt. _tLegendary profile. _f1977. Jackson, Milt. Legendary profile. 1977. Legendary profile. 1977. 740 4 _aThe legendary profile. The legendary profile. 852 00 _bMUSIC _cMAIN _kfolio _hM1366 _iM62 _91 _4Marvin Duchow Music _5 MUSIC MAIN folio M1366 M62 1 Marvin Duchow Music MUSIC folio M1366 M62 1 Marvin Duchow Music 001 001878039 001878039 001878039 005 20050110174900.0 20050110174900.0 20050110174900.0 007 sd fungnn|||e| sd fungnn|||e| sd fungnn|||e| 008 940202r19931981nyujzn i d 940202r19931981nyujzn i d 940202r19931981nyujzn i d 024 1 _a7464573372 7464573372 028 02 _aJK 57337 _bRed Baron JK 57337 Red Baron Red Baron 035 _a(OCoLC)29737267 (OCoLC)29737267 040 _aSVP _cSVP _dLGG SVP SVP LGG LGG 100 1 _aDesmond, Paul, _d1924- Desmond, Paul, 1924- 1924- 245 10 _aPaul Desmond & the Modern Jazz Quartet _h[sound recording] Paul Desmond & the Modern Jazz Quartet [sound recording] [sound recording] 260 _aNew York, N.Y. : _bRed Baron : _bManufactured by Sony Music Entertainment, _cp1993. New York, N.Y. : Red Baron : Manufactured by Sony Music Entertainment, p1993. Red Baron : Manufactured by Sony Music Entertainment, 300 _a1 sound disc (39 min.) : _bdigital ; _c4 3/4 in. 1 sound disc (39 min.) : digital ; 4 3/4 in. digital ; 511 0 _aPaul Desmond, alto saxophone; Modern Jazz Quartet: John Lewis, piano; Milt Jackson, vibraphone; Percy Heath, bass; Connie Kay, drums. Paul Desmond, alto saxophone; Modern Jazz Quartet: John Lewis, piano; Milt Jackson, vibraphone; Percy Heath, bass; Connie Kay, drums. 500 _aAll arrangements by John Lewis. All arrangements by John Lewis. 518 _aRecorded live on December 25, 1971 at Town Hall, NYC. Recorded live on December 25, 1971 at Town Hall, NYC. 500 _aOriginally released in 1981 by Finesse as LP FW 27487. Originally released in 1981 by Finesse as LP FW 27487. 500 _aProgram notes by Irving Townsend, June 1981, on container insert. Program notes by Irving Townsend, June 1981, on container insert. 505 0 _aGreensleeves -- You go to my head -- Blue dove -- Jesus Christ Superstar -- Here's that rainy day -- East of the sun -- Bags' new groove. Greensleeves -- You go to my head -- Blue dove -- Jesus Christ Superstar -- Here's that rainy day -- East of the sun -- Bags' new groove. 650 0 _aJazz _y1971-1980. Jazz -- 1971-1980. -- 1971-1980. 700 1 _aLewis, John, _d1920- Lewis, John, 1920- 1920- 710 2 _aModern Jazz Quartet. Modern Jazz Quartet. 740 0 _aPaul Desmond and the Modern Jazz Quartet. Paul Desmond and the Modern Jazz Quartet. 001 001964482 001964482 001964482 005 20060626132700.0 20060626132700.0 20060626132700.0 007 sd fzngnn|m|e| sd fzngnn|m|e| sd fzngnn|m|e| 008 871211p19871957nyujzn d 871211p19871957nyujzn d 871211p19871957nyujzn d 024 1 _a4228332902 4228332902 028 01 _a833 290-2 _bVerve 833 290-2 Verve Verve 033 0 _a19571027 _b6299 _cD56 19571027 6299 D56 6299 033 0 _a196112-- _b3804 _cN4 196112-- 3804 N4 3804 033 0 _a19571019 _b4104 _cC6 19571019 4104 C6 4104 033 0 _a197107-- _b6299 _cV7 197107-- 6299 V7 6299 035 _a(OCoLC)17222092 (OCoLC)17222092 040 _aCPL _cCPL _dOCL _dLGG CPL CPL OCL LGG OCL LGG 048 _apz01 _aka01 _asd01 _apd01 pz01 ka01 sd01 pd01 110 2 _aModern Jazz Quartet. _4prf Modern Jazz Quartet. prf prf 245 14 _aThe Modern Jazz Quartet plus _h[sound recording]. The Modern Jazz Quartet plus [sound recording]. [sound recording]. 260 _a[New York] : _bVerve, _cp1987. [New York] : Verve, p1987. Verve, 300 _a1 sound disc : _bdigital ; _c4 3/4 in. 1 sound disc : digital ; 4 3/4 in. digital ; 440 0 _aCompact jazz Compact jazz 511 0 _aModern Jazz Quartet (principally) ; Milt Jackson, vibraphone (2nd and 8th works) ; Oscar Peterson, piano (2nd and 8th works) ; Ray Brown, bass (2nd and 8th works) ; Ed Thigpen (2nd work), Louis Hayes (8th work), drums. Modern Jazz Quartet (principally) ; Milt Jackson, vibraphone (2nd and 8th works) ; Oscar Peterson, piano (2nd and 8th works) ; Ray Brown, bass (2nd and 8th works) ; Ed Thigpen (2nd work), Louis Hayes (8th work), drums. 518 _aRecorded live, Oct. 27, 1957, at the Donaueschingen Jazz Festival (1st, 5th, 7th, and 10th works); Dec. 1961, in New York (2nd work); live, Oct. 19, 1957, at the Opera House, Chicago (3rd, 4th, 6th, and 9th works); July 1971, in Villingen, Germany (8th work). Recorded live, Oct. 27, 1957, at the Donaueschingen Jazz Festival (1st, 5th, 7th, and 10th works); Dec. 1961, in New York (2nd work); live, Oct. 19, 1957, at the Opera House, Chicago (3rd, 4th, 6th, and 9th works); July 1971, in Villingen, Germany (8th work). 500 _aCompact disc. Compact disc. 500 _aAnalog recording. Analog recording. 505 0 _aThe golden striker (4:08) -- On Green Dolphin Street (7:28) -- D & E (4:55) -- I'll remember April (4:51) -- Cortège (7:15) -- Now's the time (4:43) -- J.B. blues (5:09) -- Reunion blues (6:35) -- 'Round midnight (3:56) -- Three windows (7:20). The golden striker (4:08) -- On Green Dolphin Street (7:28) -- D & E (4:55) -- I'll remember April (4:51) -- Cortège (7:15) -- Now's the time (4:43) -- J.B. blues (5:09) -- Reunion blues (6:35) -- 'Round midnight (3:56) -- Three windows (7:20). 650 0 _aJazz. Jazz. 700 1 _aJackson, Milt. _4prf Jackson, Milt. prf prf 700 1 _aPeterson, Oscar, _d1925- _4prf Peterson, Oscar, 1925- prf 1925- prf 700 1 _aBrown, Ray, _d1926-2002. _4prf Brown, Ray, 1926-2002. prf 1926-2002. prf 700 1 _aThigpen, Ed. _4prf Thigpen, Ed. prf prf 700 1 _aHayes, Louis, _d1937- _4prf Hayes, Louis, 1937- prf 1937- prf 852 80 _bMUSIC _cAV _hCD 1131 _4Marvin Duchow Music _5Audio-Visual MUSIC AV CD 1131 Marvin Duchow Music Audio-Visual MUSIC CD 1131 Marvin Duchow Music Audio-Visual PK�����u]ye@����&��test/File_MARC/tests/marc_xml_007.phptnu�[��������--TEST-- marc_xml_007: test getTag(), isControlField(), and isDataField() convenience methods on MARCXML --SKIPIF-- <?php include('tests/skipif.inc'); ?> --FILE-- <?php $dir = dirname(__FILE__); require __DIR__ . '/bootstrap.php'; $marc_file = new File_MARCXML($dir . '/' . 'bigarchive.xml'); while ($marc_record = $marc_file->next()) { $fields = $marc_record->getFields(); foreach ($fields as $field) { print $field->getTag(); if ($field->isControlField()) { print "\tControl field!"; } if ($field->isDataField()) { print "\tData field!"; } print "\n"; } } ?> --EXPECT-- 001 Control field! 003 Control field! 005 Control field! 006 Control field! 007 Control field! 008 Control field! 037 Data field! 040 Data field! 245 Data field! 246 Data field! 260 Data field! 300 Data field! 500 Data field! 500 Data field! 500 Data field! 510 Data field! 510 Data field! 533 Data field! 651 Data field! 830 Data field! 856 Data field! 909 Data field! PK�����u]44-����(��test/File_MARC/tests/marc_field_003.phptnu�[��������--TEST-- marc_field_003: Add subfields to an existing field --SKIPIF-- <?php include('tests/skipif.inc'); ?> --FILE-- <?php $dir = dirname(__FILE__); require __DIR__ . '/bootstrap.php'; // create some subfields $subfields[] = new File_MARC_Subfield('a', 'nothing'); $subfields[] = new File_MARC_Subfield('z', 'everything'); // create a field $field = new File_MARC_Data_Field('100', $subfields, '0'); // create some new subfields $subfield1 = new File_MARC_Subfield('g', 'a little'); $subfield2 = new File_MARC_Subfield('k', 'a bit more'); $subfield3 = new File_MARC_Subfield('t', 'a lot'); $subfield4 = new File_MARC_Subfield('0', 'first post'); // append a new subfield to the existing set of subfields // expected order: a-z-g $field->appendSubfield($subfield1); // insert a new subfield after the first subfield with code 'z' // expected order: a-z-k-g $sf = $field->getSubfields('z'); // we might get an array back; in this case, we want the first subfield if (is_array($sf)) { $field->insertSubfield($subfield2, $sf[0]); } else { $field->insertSubfield($subfield2, $sf); } // insert a new subfield prior to the first subfield with code 'z' // expected order: a-t-z-k-g $sf = $field->getSubfields('z'); // we might get an array back; in this case, we want the first subfield if (is_array($sf)) { $field->insertSubfield($subfield3, $sf[0], true); } else { $field->insertSubfield($subfield3, $sf, true); } // insert a new subfield at the very start of the field $field->prependSubfield($subfield4); // let's see the results print $field; print "\n"; ?> --EXPECT-- 100 0 _0first post _anothing _ta lot _zeverything _ka bit more _ga little PK�����u]1��1��&��test/File_MARC/tests/marc_xml_008.phptnu�[��������--TEST-- marc_xml_008: generate a single collection of MARCXML records from a MARCXML record --SKIPIF-- <?php include('tests/skipif.inc'); ?> --FILE-- <?php $dir = dirname(__FILE__); require __DIR__ . '/bootstrap.php'; $records = new File_MARCXML($dir . '/' . 'music.xml'); // Add the XML header and opening <collection> element $records->toXMLHeader(); // Iterate through the retrieved records while ($record = $records->next()) { // Change each 852 $c to "Audio-Visual" $holdings = $record->getFields('852'); foreach ($holdings as $holding) { // Get the $c subfields from this field $formats = $holding->getSubfields('c'); foreach ($formats as $format) { if ($format->getData('AV')) { $format->setData('Audio-Visual'); } } } // Generate the XML output for this record print $record->toXML('UTF-8', true, false); } // Add the </collection> closing element and dump the XMLWriter contents print $records->toXMLFooter(); --EXPECT-- <?xml version="1.0" encoding="UTF-8"?> <collection xmlns="http://www.loc.gov/MARC21/slim"> <record xmlns="http://www.loc.gov/MARC21/slim"> <leader>01145ncm a2200277 i 4500</leader> <controlfield tag="001">000073594</controlfield> <controlfield tag="004">AAJ5802</controlfield> <controlfield tag="005">20030415102100.0</controlfield> <controlfield tag="008">801107s1977 nyujza </controlfield> <datafield tag="010" ind1=" " ind2=" "> <subfield code="a"> 77771106 </subfield> </datafield> <datafield tag="035" ind1=" " ind2=" "> <subfield code="a">(CaOTUIC)15460184</subfield> </datafield> <datafield tag="035" ind1="9" ind2=" "> <subfield code="a">AAJ5802</subfield> </datafield> <datafield tag="040" ind1=" " ind2=" "> <subfield code="a">LC</subfield> </datafield> <datafield tag="050" ind1="0" ind2="0"> <subfield code="a">M1366</subfield> <subfield code="b">.M62</subfield> <subfield code="d">M1527.2</subfield> </datafield> <datafield tag="245" ind1="0" ind2="4"> <subfield code="a">The Modern Jazz Quartet :</subfield> <subfield code="b">The legendary profile. --</subfield> </datafield> <datafield tag="260" ind1=" " ind2=" "> <subfield code="a">New York :</subfield> <subfield code="b">M.J.Q. Music,</subfield> <subfield code="c">c1977.</subfield> </datafield> <datafield tag="300" ind1=" " ind2=" "> <subfield code="a">score (72 p.) ;</subfield> <subfield code="c">31 cm.</subfield> </datafield> <datafield tag="500" ind1=" " ind2=" "> <subfield code="a">For piano, vibraphone, drums, and double bass.</subfield> </datafield> <datafield tag="505" ind1="0" ind2=" "> <subfield code="a">Lewis, J. Django.--Lewis, J. Plastic dreams (music from the film Kemek).--Lewis, J. Dancing (music from the film Kemek).--Lewis, J. Blues in A minor.--Lewis, J. Blues in B́Ư.--Lewis, J. Precious joy.--Jackson, M. The martyr.--Jackson, M. The legendary profile.</subfield> </datafield> <datafield tag="650" ind1=" " ind2="0"> <subfield code="a">Jazz.</subfield> </datafield> <datafield tag="650" ind1=" " ind2="0"> <subfield code="a">Motion picture music</subfield> <subfield code="v">Excerpts</subfield> <subfield code="v">Scores.</subfield> </datafield> <datafield tag="700" ind1="1" ind2="2"> <subfield code="a">Lewis, John,</subfield> <subfield code="d">1920-</subfield> <subfield code="t">Selections.</subfield> <subfield code="f">1977.</subfield> </datafield> <datafield tag="700" ind1="1" ind2="2"> <subfield code="a">Jackson, Milt.</subfield> <subfield code="t">Martyrs.</subfield> <subfield code="f">1977.</subfield> </datafield> <datafield tag="700" ind1="1" ind2="2"> <subfield code="a">Jackson, Milt.</subfield> <subfield code="t">Legendary profile.</subfield> <subfield code="f">1977.</subfield> </datafield> <datafield tag="740" ind1="4" ind2=" "> <subfield code="a">The legendary profile.</subfield> </datafield> <datafield tag="852" ind1="0" ind2="0"> <subfield code="b">MUSIC</subfield> <subfield code="c">Audio-Visual</subfield> <subfield code="k">folio</subfield> <subfield code="h">M1366</subfield> <subfield code="i">M62</subfield> <subfield code="9">1</subfield> <subfield code="4">Marvin Duchow Music</subfield> <subfield code="5"></subfield> </datafield> </record> <record xmlns="http://www.loc.gov/MARC21/slim"> <leader>01293cjm a2200289 a 4500</leader> <controlfield tag="001">001878039</controlfield> <controlfield tag="005">20050110174900.0</controlfield> <controlfield tag="007">sd fungnn|||e|</controlfield> <controlfield tag="008">940202r19931981nyujzn i d</controlfield> <datafield tag="024" ind1="1" ind2=" "> <subfield code="a">7464573372</subfield> </datafield> <datafield tag="028" ind1="0" ind2="2"> <subfield code="a">JK 57337</subfield> <subfield code="b">Red Baron</subfield> </datafield> <datafield tag="035" ind1=" " ind2=" "> <subfield code="a">(OCoLC)29737267</subfield> </datafield> <datafield tag="040" ind1=" " ind2=" "> <subfield code="a">SVP</subfield> <subfield code="c">SVP</subfield> <subfield code="d">LGG</subfield> </datafield> <datafield tag="100" ind1="1" ind2=" "> <subfield code="a">Desmond, Paul,</subfield> <subfield code="d">1924-</subfield> </datafield> <datafield tag="245" ind1="1" ind2="0"> <subfield code="a">Paul Desmond & the Modern Jazz Quartet</subfield> <subfield code="h">[sound recording]</subfield> </datafield> <datafield tag="260" ind1=" " ind2=" "> <subfield code="a">New York, N.Y. :</subfield> <subfield code="b">Red Baron :</subfield> <subfield code="b">Manufactured by Sony Music Entertainment,</subfield> <subfield code="c">p1993.</subfield> </datafield> <datafield tag="300" ind1=" " ind2=" "> <subfield code="a">1 sound disc (39 min.) :</subfield> <subfield code="b">digital ;</subfield> <subfield code="c">4 3/4 in.</subfield> </datafield> <datafield tag="511" ind1="0" ind2=" "> <subfield code="a">Paul Desmond, alto saxophone; Modern Jazz Quartet: John Lewis, piano; Milt Jackson, vibraphone; Percy Heath, bass; Connie Kay, drums.</subfield> </datafield> <datafield tag="500" ind1=" " ind2=" "> <subfield code="a">All arrangements by John Lewis.</subfield> </datafield> <datafield tag="518" ind1=" " ind2=" "> <subfield code="a">Recorded live on December 25, 1971 at Town Hall, NYC.</subfield> </datafield> <datafield tag="500" ind1=" " ind2=" "> <subfield code="a">Originally released in 1981 by Finesse as LP FW 27487.</subfield> </datafield> <datafield tag="500" ind1=" " ind2=" "> <subfield code="a">Program notes by Irving Townsend, June 1981, on container insert.</subfield> </datafield> <datafield tag="505" ind1="0" ind2=" "> <subfield code="a">Greensleeves -- You go to my head -- Blue dove -- Jesus Christ Superstar -- Here's that rainy day -- East of the sun -- Bags' new groove.</subfield> </datafield> <datafield tag="650" ind1=" " ind2="0"> <subfield code="a">Jazz</subfield> <subfield code="y">1971-1980.</subfield> </datafield> <datafield tag="700" ind1="1" ind2=" "> <subfield code="a">Lewis, John,</subfield> <subfield code="d">1920-</subfield> </datafield> <datafield tag="710" ind1="2" ind2=" "> <subfield code="a">Modern Jazz Quartet.</subfield> </datafield> <datafield tag="740" ind1="0" ind2=" "> <subfield code="a">Paul Desmond and the Modern Jazz Quartet.</subfield> </datafield> </record> <record xmlns="http://www.loc.gov/MARC21/slim"> <leader>01829cjm a2200385 a 4500</leader> <controlfield tag="001">001964482</controlfield> <controlfield tag="005">20060626132700.0</controlfield> <controlfield tag="007">sd fzngnn|m|e|</controlfield> <controlfield tag="008">871211p19871957nyujzn d</controlfield> <datafield tag="024" ind1="1" ind2=" "> <subfield code="a">4228332902</subfield> </datafield> <datafield tag="028" ind1="0" ind2="1"> <subfield code="a">833 290-2</subfield> <subfield code="b">Verve</subfield> </datafield> <datafield tag="033" ind1="0" ind2=" "> <subfield code="a">19571027</subfield> <subfield code="b">6299</subfield> <subfield code="c">D56</subfield> </datafield> <datafield tag="033" ind1="0" ind2=" "> <subfield code="a">196112--</subfield> <subfield code="b">3804</subfield> <subfield code="c">N4</subfield> </datafield> <datafield tag="033" ind1="0" ind2=" "> <subfield code="a">19571019</subfield> <subfield code="b">4104</subfield> <subfield code="c">C6</subfield> </datafield> <datafield tag="033" ind1="0" ind2=" "> <subfield code="a">197107--</subfield> <subfield code="b">6299</subfield> <subfield code="c">V7</subfield> </datafield> <datafield tag="035" ind1=" " ind2=" "> <subfield code="a">(OCoLC)17222092</subfield> </datafield> <datafield tag="040" ind1=" " ind2=" "> <subfield code="a">CPL</subfield> <subfield code="c">CPL</subfield> <subfield code="d">OCL</subfield> <subfield code="d">LGG</subfield> </datafield> <datafield tag="048" ind1=" " ind2=" "> <subfield code="a">pz01</subfield> <subfield code="a">ka01</subfield> <subfield code="a">sd01</subfield> <subfield code="a">pd01</subfield> </datafield> <datafield tag="110" ind1="2" ind2=" "> <subfield code="a">Modern Jazz Quartet.</subfield> <subfield code="4">prf</subfield> </datafield> <datafield tag="245" ind1="1" ind2="4"> <subfield code="a">The Modern Jazz Quartet plus</subfield> <subfield code="h">[sound recording].</subfield> </datafield> <datafield tag="260" ind1=" " ind2=" "> <subfield code="a">[New York] :</subfield> <subfield code="b">Verve,</subfield> <subfield code="c">p1987.</subfield> </datafield> <datafield tag="300" ind1=" " ind2=" "> <subfield code="a">1 sound disc :</subfield> <subfield code="b">digital ;</subfield> <subfield code="c">4 3/4 in.</subfield> </datafield> <datafield tag="440" ind1=" " ind2="0"> <subfield code="a">Compact jazz</subfield> </datafield> <datafield tag="511" ind1="0" ind2=" "> <subfield code="a">Modern Jazz Quartet (principally) ; Milt Jackson, vibraphone (2nd and 8th works) ; Oscar Peterson, piano (2nd and 8th works) ; Ray Brown, bass (2nd and 8th works) ; Ed Thigpen (2nd work), Louis Hayes (8th work), drums.</subfield> </datafield> <datafield tag="518" ind1=" " ind2=" "> <subfield code="a">Recorded live, Oct. 27, 1957, at the Donaueschingen Jazz Festival (1st, 5th, 7th, and 10th works); Dec. 1961, in New York (2nd work); live, Oct. 19, 1957, at the Opera House, Chicago (3rd, 4th, 6th, and 9th works); July 1971, in Villingen, Germany (8th work).</subfield> </datafield> <datafield tag="500" ind1=" " ind2=" "> <subfield code="a">Compact disc.</subfield> </datafield> <datafield tag="500" ind1=" " ind2=" "> <subfield code="a">Analog recording.</subfield> </datafield> <datafield tag="505" ind1="0" ind2=" "> <subfield code="a">The golden striker (4:08) -- On Green Dolphin Street (7:28) -- D & E (4:55) -- I'll remember April (4:51) -- Cort©·ge (7:15) -- Now's the time (4:43) -- J.B. blues (5:09) -- Reunion blues (6:35) -- 'Round midnight (3:56) -- Three windows (7:20).</subfield> </datafield> <datafield tag="650" ind1=" " ind2="0"> <subfield code="a">Jazz.</subfield> </datafield> <datafield tag="700" ind1="1" ind2=" "> <subfield code="a">Jackson, Milt.</subfield> <subfield code="4">prf</subfield> </datafield> <datafield tag="700" ind1="1" ind2=" "> <subfield code="a">Peterson, Oscar,</subfield> <subfield code="d">1925-</subfield> <subfield code="4">prf</subfield> </datafield> <datafield tag="700" ind1="1" ind2=" "> <subfield code="a">Brown, Ray,</subfield> <subfield code="d">1926-2002.</subfield> <subfield code="4">prf</subfield> </datafield> <datafield tag="700" ind1="1" ind2=" "> <subfield code="a">Thigpen, Ed.</subfield> <subfield code="4">prf</subfield> </datafield> <datafield tag="700" ind1="1" ind2=" "> <subfield code="a">Hayes, Louis,</subfield> <subfield code="d">1937-</subfield> <subfield code="4">prf</subfield> </datafield> <datafield tag="852" ind1="8" ind2="0"> <subfield code="b">MUSIC</subfield> <subfield code="c">Audio-Visual</subfield> <subfield code="h">CD 1131</subfield> <subfield code="4">Marvin Duchow Music</subfield> <subfield code="5">Audio-Visual</subfield> </datafield> </record> </collection> PK�����u] \����'��test/File_MARC/tests/marc_lint_001.phptnu�[��������--TEST-- marc_lint_001: Full test of Lint suite --SKIPIF-- <?php include('tests/skipif.inc'); ?> <?php include('tests/skipif_noispn.inc'); ?> --FILE-- <?php $dir = dirname(__FILE__); require __DIR__ . '/bootstrap.php'; $marc_lint = new File_MARC_Lint(); print "Test records in camel.mrc\n"; $marc_file = new File_MARC($dir . '/' . 'camel.mrc'); while ($marc_record = $marc_file->next()) { $warnings = $marc_lint->checkRecord($marc_record); foreach ($warnings as $warning) { print $warning . "\n"; } } print "\nTest from a constructed record\n"; $rec = new File_MARC_Record(); $rec->setLeader("00000nam 22002538a 4500"); $rec->appendField( new File_MARC_Data_Field( '041', array( new File_MARC_Subfield('a', 'end'), new File_MARC_Subfield('a', 'fren') ), "0", "" ) ); $rec->appendField( new File_MARC_Data_Field( '043', array( new File_MARC_Subfield('a', 'n-us-pn') ), "", "" ) ); $rec->appendField( new File_MARC_Data_Field( '082', array( new File_MARC_Subfield('a', '005.13/3'), // typo 'R' for 'W' and missing 'b' subfield new File_MARC_Subfield('R', 'all'), new File_MARC_Subfield('2', '21') ), "0", "4" ) ); $rec->appendField( new File_MARC_Data_Field( '082', array( new File_MARC_Subfield('a', '005.13'), new File_MARC_Subfield('b', 'Wall'), new File_MARC_Subfield('2', '14') ), "1", "4" ) ); $rec->appendField( new File_MARC_Data_Field( '100', array( new File_MARC_Subfield('a', 'Wall, Larry') ), "1", "4" ) ); $rec->appendField( new File_MARC_Data_Field( '110', array( new File_MARC_Subfield('a', "O'Reilly & Associates.") ), "1", "" ) ); $rec->appendField( new File_MARC_Data_Field( '245', array( new File_MARC_Subfield('a', 'Programming Perl / '), new File_MARC_Subfield('a', 'Big Book of Perl /'), new File_MARC_Subfield('c', 'Larry Wall, Tom Christiansen & Jon Orwant.') ), "9", "0" ) ); $rec->appendField( new File_MARC_Data_Field( '250', array( new File_MARC_Subfield('a', '3rd ed.') ), "", "" ) ); $rec->appendField( new File_MARC_Data_Field( '250', array( new File_MARC_Subfield('a', '3rd ed.') ), "", "" ) ); $rec->appendField( new File_MARC_Data_Field( '260', array( new File_MARC_Subfield('a', 'Cambridge, Mass. : '), new File_MARC_Subfield('b', "O'Reilly, "), new File_MARC_Subfield('r', '2000.') ), "", "" ) ); $rec->appendField( new File_MARC_Data_Field( '590', array( new File_MARC_Subfield('a', 'Personally signed by Larry.') ), "4", "" ) ); $rec->appendField( new File_MARC_Data_Field( '650', array( new File_MARC_Subfield('a', 'Perl (Computer program language)'), new File_MARC_Subfield('0', '(DLC)sh 95010633') ), "", "0" ) ); $rec->appendField( new File_MARC_Data_Field( '856', array( new File_MARC_Subfield('u', 'http://www.perl.com/') ), "4", "3" ) ); $rec->appendField( new File_MARC_Data_Field( '886', array( new File_MARC_Subfield('4', 'Some foreign thing'), new File_MARC_Subfield('q', 'Another foreign thing') ), "0", "" ) ); $warnings = $marc_lint->checkRecord($rec); foreach ($warnings as $warning) { print $warning . "\n"; } ?> --EXPECT-- Test records in camel.mrc 100: Indicator 1 must be 0, 1 or 3 but it's "2" 007: Subfields are not allowed in fields lower than 010 Test from a constructed record 1XX: Only one 1XX tag is allowed, but I found 2 of them. 041: Subfield _a, end (end), is not valid. 041: Subfield _a must be evenly divisible by 3 or exactly three characters if ind2 is not 7, (fren). 043: Subfield _a, n-us-pn, is not valid. 082: Subfield _R is not allowed. 100: Indicator 2 must be blank but it's "4" 245: Indicator 1 must be 0 or 1 but it's "9" 245: Subfield _a is not repeatable. 260: Subfield _r is not allowed. 856: Indicator 2 must be blank, 0, 1, 2 or 8 but it's "3" PK�����u]Y��Y��&��test/File_MARC/tests/marc_xml_009.phptnu�[��������--TEST-- marc_xml_009: convert a MARCXML record with an overly long leader to MARC --SKIPIF-- <?php include('tests/skipif.inc'); ?> --FILE-- <?php $dir = dirname(__FILE__); require __DIR__ . '/bootstrap.php'; $marc_file = new File_MARCXML($dir . '/' . 'bad_leader.xml'); while ($marc_record = $marc_file->next()) { print $marc_record->toRaw(); } ?> --EXPECT-- 00749cam a2200241 454500001001400000003000600014005001700020008004100037020001800078020001500096035002100111040003600132050002400168100002500192245007800217260003700295300002100332504004100353650001700394650002200411852004800433901002600481LIBN539044247OCoLC20081030150430.0070630||||| ||| 000 0 eng d a9781856075442 a1856075443 a(OCoLC)156822300 aBTCTAcBTCTAdYDXCPdBAKERdEMT 4aBL2747.2b.W45 20061 aWhite, Stephen Ross.10aSpace for unknowing :bthe place of agnosis in faith /cStephen R. White. aDublin :bColumba Press,cc2006. a160 p. ;c22 cm. aIncludes bibliographical references. 0aAgnosticism. 0aBelief and doubt. a1h230 WHIp11111027105040t65112549p26.95 aLIBN539044247bSystem PK�����u]����"��test/File_MARC/tests/marc_008.phptnu�[��������--TEST-- marc_008: Attempt to open a file that does not exist --SKIPIF-- <?php include('tests/skipif.inc'); ?> --FILE-- <?php $dir = dirname(__FILE__); require __DIR__ . '/bootstrap.php'; try { $marc_file = new File_MARC('super_bogus_file'); } catch (File_MARC_Exception $fme) { print $fme->getMessage(); } ?> --EXPECTF-- Warning: fopen(super_bogus_file): failed to open stream: No such file or directory in %sMARC.php on line %d Invalid input file "super_bogus_file" PK�����u]+W �� ��#��test/File_MARC/tests/bigarchive.xmlnu�[��������<?xml version="1.0"?> <record xmlns="http://www.loc.gov/MARC21/slim"><leader>00000nam 2200277 4500</leader><controlfield tag="001">99865026e</controlfield><controlfield tag="003">UnM</controlfield><controlfield tag="005">19961010163452.0</controlfield><controlfield tag="006">m g d</controlfield><controlfield tag="007">cr bn |||a|bb|</controlfield><controlfield tag="008">940112s1649 enk s 00| | eng d</controlfield><datafield tag="037" ind1=" " ind2=" "><subfield code="a">CL0051000003</subfield><subfield code="b">ProQuest Information and Learning. 300 N. Zeeb Rd., Ann Arbor, MI 48106</subfield></datafield><datafield tag="040" ind1=" " ind2=" "><subfield code="a">Cu-RivES</subfield><subfield code="c">Cu-RivES</subfield><subfield code="d">CStRLIN</subfield><subfield code="e">dcrb</subfield><subfield code="d">WaOLN</subfield></datafield><datafield tag="245" ind1="0" ind2="4"><subfield code="a">The VVelsh embassador, or the happy newes his vvorship hath brought to London.</subfield><subfield code="h">[electronic resource] :</subfield><subfield code="b">Togetherwith her thirteen articles of acreements, which her propounds to all her cousens in her principality of Wales,and her Cities of London.</subfield></datafield><datafield tag="246" ind1="2" ind2=" "><subfield code="a">Happy newes his vvorship hath brought to London</subfield></datafield><datafield tag="260" ind1=" " ind2=" "><subfield code="a">[London] :</subfield><subfield code="b">Printed for George Roberts, and are to be soldat the Maiden Head on Snow-Hill neer Holborn Conduit,</subfield><subfield code="c">1649.</subfield></datafield><datafield tag="300" ind1=" " ind2=" "><subfield code="a">[2], 6 p.</subfield></datafield><datafield tag="500" ind1=" " ind2=" "><subfield code="a">Place of publication from Wing.</subfield></datafield><datafield tag="500" ind1=" " ind2=" "><subfield code="a">Annotation on Thomason copy: "May 4th".</subfield></datafield><datafield tag="500" ind1=" " ind2=" "><subfield code="a">Reproduction of the original in the British Library.</subfield></datafield><datafield tag="510" ind1="4" ind2=" "><subfield code="a">Wing (2nd ed.)</subfield><subfield code="c">W1315.</subfield></datafield><datafield tag="510" ind1="4" ind2=" "><subfield code="a">Thomason</subfield><subfield code="c">E.552[19].</subfield></datafield><datafield tag="533" ind1=" " ind2=" "><subfield code="a">Electronic reproduction.</subfield><subfield code="b">Ann Arbor, Mich. :</subfield><subfield code="c">UMI,</subfield><subfield code="d">1999-</subfield><subfield code="f">(Early English books online)</subfield><subfield code="n">Digital version of: (Thomason Tracts ; 85:E552[19])</subfield><subfield code="7">s1999 miun s</subfield></datafield><datafield tag="651" ind1=" " ind2="4"><subfield code="a">Great Britain</subfield><subfield code="x">Politics and government</subfield><subfield code="y">1642-1649</subfield><subfield code="v">Early works to 1800.</subfield></datafield><datafield tag="830" ind1=" " ind2="0"><subfield code="a">Early English books online.</subfield></datafield><datafield tag="856" ind1="4" ind2="0"><subfield code="z">E-book (Onsite access at NYPL Research Libraries)</subfield><subfield code="u">http://gateway.proquest.com/openurl?ctx_ver=Z39.88-2003&res_id=xri:eebo&rft_val_fmt=&rft_id=xri:eebo:image:117259</subfield></datafield><datafield tag="909" ind1=" " ind2=" "><subfield code="a">Not for export in OCLC Reclamation Project</subfield></datafield></record> PK�����u]x;#��#��"��test/File_MARC/tests/marc_006.phptnu�[��������--TEST-- marc_006: test read.php --SKIPIF-- <?php include('tests/skipif.inc'); ?> --FILE-- <?php $dir = dirname(__FILE__); require __DIR__ . '/bootstrap.php'; // Read MARC records from a stream (a file, in this case) $marc_source = new File_MARC($dir . '/' . 'example.mrc'); // Retrieve the first MARC record from the source $marc_record = $marc_source->next(); // Retrieve a personal name field from the record $names = $marc_record->getFields('100'); foreach ($names as $name_field) { // Now print the $a subfield switch ($name_field->getIndicator(1)) { case 0: print "Forename: "; break; case 1: print "Surname: "; break; case 2: print "Family name: "; break; } $name = $name_field->getSubfields('a'); if (count($name) == 1) { print $name[0]->getData() . "\n"; } else { print "Error -- \$a subfield appears more than once in this field!"; } } // Retrieve all series statement fields // Series statement fields start with a 4 (PCRE) $subjects = $marc_record->getFields('^4', true); // Iterate through all of the returned series statement fields foreach ($subjects as $field) { // print with File_MARC_Field_Data's magic __toString() method print $field; } ?> --EXPECT-- Surname: Jansson, Tove, 440 0 _aMumin-biblioteket, _x99-0698931-9 PK�����u]kP����"��test/File_MARC/tests/marc_023.phptnu�[��������--TEST-- marc_023: test extended Record interface --SKIPIF-- <?php include('tests/skipif.inc'); ?> --FILE-- <?php $dir = dirname(__FILE__); require __DIR__ . '/bootstrap.php'; class MyRecord extends File_MARC_Record { public function myNewMethod() { return $this->getField('040')->getSubfield('a')->getData(); } } $marc_file = new File_MARC($dir . '/' . 'example.mrc', File_MARC::SOURCE_FILE, MyRecord::class); $rec = $marc_file->next(); print get_class($rec) . "\n"; print $rec->myNewMethod() . "\n"; ?> --EXPECT-- MyRecord NB PK�����u]f~����(��test/File_MARC/tests/marc_field_001.phptnu�[��������--TEST-- marc_field_001: Exercise basic methods for File_MARC_Field class --SKIPIF-- <?php include('tests/skipif.inc'); ?> --FILE-- <?php $dir = dirname(__FILE__); require __DIR__ . '/bootstrap.php'; // create some subfields $subfields[] = new File_MARC_Subfield('a', 'nothing'); $subfields[] = new File_MARC_Subfield('z', 'everything'); // test constructor $field = new File_MARC_Data_Field('100', $subfields, '0'); // test basic getter methods print "Tag: " . $field->getTag() . "\n"; print "Get Ind1: " . $field->getIndicator(1) . "\n"; print "Get Ind2: " . $field->getIndicator(2) . "\n"; // test basic setter methods print "Set Ind1: " . $field->setIndicator(1, '3') . "\n"; // test pretty print print $field; print "\n"; // test raw print print $field->toRaw(); ?> --EXPECT-- Tag: 100 Get Ind1: 0 Get Ind2: Set Ind1: 3 100 3 _anothing _zeverything 3 anothingzeverything PK�����u]%Hh��h��"��test/File_MARC/tests/marc_003.phptnu�[��������--TEST-- marc_003: getFields() with various regular expressions --SKIPIF-- <?php include('tests/skipif.inc'); ?> --FILE-- <?php $dir = dirname(__FILE__); require __DIR__ . '/bootstrap.php'; $marc_file = new File_MARC($dir . '/' . 'music.mrc'); print "Test with a simple string\n"; while ($marc_record = $marc_file->next()) { print "\nNext record:\n"; $fields = $marc_record->getFields('650'); foreach ($fields as $field) { print $field; print "\n"; } } print "\nTest with regular expression\n"; $marc_file = new File_MARC($dir . '/' . 'music.mrc'); while ($marc_record = $marc_file->next()) { print "\nNext record:\n"; $fields = $marc_record->getFields('00\d', true); foreach ($fields as $field) { print $field; print "\n"; } } ?> --EXPECT-- Test with a simple string Next record: 650 0 _aJazz. 650 0 _aMotion picture music _vExcerpts _vScores. Next record: 650 0 _aJazz _y1971-1980. Next record: 650 0 _aJazz. Test with regular expression Next record: 001 000073594 004 AAJ5802 005 20030415102100.0 008 801107s1977 nyujza Next record: 001 001878039 005 20050110174900.0 007 sd fungnn|||e| 008 940202r19931981nyujzn i d Next record: 001 001964482 005 20060626132700.0 007 sd fzngnn|m|e| 008 871211p19871957nyujzn d PK�����u]S3 �� ��"��test/File_MARC/tests/marc_021.phptnu�[��������--TEST-- marc_021: test MARC-in-JSON serialization with subfield 0 --SKIPIF-- <?php include('tests/skipif.inc'); ?> --FILE-- <?php $dir = dirname(__FILE__); require __DIR__ . '/bootstrap.php'; $marc_file = new File_MARC($dir . '/' . 'example.mrc'); while ($marc_record = $marc_file->next()) { // create some subfields $subfields[] = new File_MARC_Subfield('0', 'nothing'); $subfields[] = new File_MARC_Subfield('1', 'everything'); $field = new File_MARC_Data_Field('999', $subfields, '', ''); $marc_record->appendField($field); $subfields = null; $field = null; $subfields[] = new File_MARC_Subfield('a', 'bee'); $subfields[] = new File_MARC_Subfield('0', 'cee'); $subfields[] = new File_MARC_Subfield('d', 'eee'); $field = new File_MARC_Data_Field('999', $subfields, '', ''); $marc_record->appendField($field); print $marc_record->toJSON(); print "\n"; } ?> --EXPECT-- {"leader":"01850 2200517 4500","fields":[{"001":"0000000044"},{"003":"EMILDA"},{"008":"980120s1998 fi j 000 0 swe"},{"020":{"ind1":" ","ind2":" ","subfields":[{"a":"9515008808"},{"c":"FIM 72:00"}]}},{"035":{"ind1":" ","ind2":" ","subfields":[{"9":"9515008808"}]}},{"040":{"ind1":" ","ind2":" ","subfields":[{"a":"NB"}]}},{"042":{"ind1":" ","ind2":" ","subfields":[{"9":"NB"},{"9":"SEE"}]}},{"084":{"ind1":" ","ind2":" ","subfields":[{"a":"Hcd,u"},{"2":"kssb\/6"}]}},{"084":{"ind1":" ","ind2":" ","subfields":[{"5":"NB"},{"a":"uHc"},{"2":"kssb"}]}},{"084":{"ind1":" ","ind2":" ","subfields":[{"5":"SEE"},{"a":"Hcf"},{"2":"kssb\/6"}]}},{"084":{"ind1":" ","ind2":" ","subfields":[{"5":"Q"},{"a":"Hcd,uf"},{"2":"kssb\/6"}]}},{"100":{"ind1":"1","ind2":" ","subfields":[{"a":"Jansson, Tove,"},{"d":"1914-2001"}]}},{"245":{"ind1":"0","ind2":"4","subfields":[{"a":"Det osynliga barnet och andra ber\u00e4ttelser \/"},{"c":"Tove Jansson"}]}},{"250":{"ind1":" ","ind2":" ","subfields":[{"a":"7. uppl."}]}},{"260":{"ind1":" ","ind2":" ","subfields":[{"a":"Helsingfors :"},{"b":"Schildt,"},{"c":"1998 ;"},{"e":"(Falun :"},{"f":"Scandbook)"}]}},{"300":{"ind1":" ","ind2":" ","subfields":[{"a":"166, [4] s. :"},{"b":"ill. ;"},{"c":"21 cm"}]}},{"440":{"ind1":" ","ind2":"0","subfields":[{"a":"Mumin-biblioteket,"},{"x":"99-0698931-9"}]}},{"500":{"ind1":" ","ind2":" ","subfields":[{"a":"Originaluppl. 1962"}]}},{"599":{"ind1":" ","ind2":" ","subfields":[{"a":"Li: S"}]}},{"740":{"ind1":"4","ind2":" ","subfields":[{"a":"Det osynliga barnet"}]}},{"775":{"ind1":"1","ind2":" ","subfields":[{"z":"951-50-0385-7"},{"w":"9515003857"},{"9":"07"}]}},{"841":{"ind1":" ","ind2":" ","subfields":[{"5":"Li"},{"a":"xa"},{"b":"0201080u 0 4000uu |000000"},{"e":"1"}]}},{"841":{"ind1":" ","ind2":" ","subfields":[{"5":"SEE"},{"a":"xa"},{"b":"0201080u 0 4000uu |000000"},{"e":"1"}]}},{"841":{"ind1":" ","ind2":" ","subfields":[{"5":"L"},{"a":"xa"},{"b":"0201080u 0 4000uu |000000"},{"e":"1"}]}},{"841":{"ind1":" ","ind2":" ","subfields":[{"5":"NB"},{"a":"xa"},{"b":"0201080u 0 4000uu |000000"},{"e":"1"}]}},{"841":{"ind1":" ","ind2":" ","subfields":[{"5":"Q"},{"a":"xa"},{"b":"0201080u 0 4000uu |000000"},{"e":"1"}]}},{"841":{"ind1":" ","ind2":" ","subfields":[{"5":"S"},{"a":"xa"},{"b":"0201080u 0 4000uu |000000"},{"e":"1"}]}},{"852":{"ind1":" ","ind2":" ","subfields":[{"5":"NB"},{"b":"NB"},{"c":"NB98:12"},{"h":"plikt"},{"j":"R, 980520"}]}},{"852":{"ind1":" ","ind2":" ","subfields":[{"5":"Li"},{"b":"Li"},{"c":"CNB"},{"h":"h,u"}]}},{"852":{"ind1":" ","ind2":" ","subfields":[{"5":"SEE"},{"b":"SEE"}]}},{"852":{"ind1":" ","ind2":" ","subfields":[{"5":"Q"},{"b":"Q"},{"j":"98947"}]}},{"852":{"ind1":" ","ind2":" ","subfields":[{"5":"L"},{"b":"L"},{"c":"0100"},{"h":"98\/"},{"j":"3043 H"}]}},{"852":{"ind1":" ","ind2":" ","subfields":[{"5":"S"},{"b":"S"},{"h":"Sv97"},{"j":"7235"}]}},{"900":{"ind1":"1","ind2":"s","subfields":[{"a":"Yanson, Tobe,"},{"d":"1914-2001"},{"u":"Jansson, Tove,"},{"d":"1914-2001"}]}},{"900":{"ind1":"1","ind2":"s","subfields":[{"a":"Janssonov\u00e1, Tove,"},{"d":"1914-2001"},{"u":"Jansson, Tove,"},{"d":"1914-2001"}]}},{"900":{"ind1":"1","ind2":"s","subfields":[{"a":"Jansone, Tuve,"},{"d":"1914-2001"},{"u":"Jansson, Tove,"},{"d":"1914-2001"}]}},{"900":{"ind1":"1","ind2":"s","subfields":[{"a":"Janson, Tuve,"},{"d":"1914-2001"},{"u":"Jansson, Tove,"},{"d":"1914-2001"}]}},{"900":{"ind1":"1","ind2":"s","subfields":[{"a":"Jansson, Tuve,"},{"d":"1914-2001"},{"u":"Jansson, Tove,"},{"d":"1914-2001"}]}},{"900":{"ind1":"1","ind2":"s","subfields":[{"a":"Janssonova, Tove,"},{"d":"1914-2001"},{"u":"Jansson, Tove,"},{"d":"1914-2001"}]}},{"976":{"ind1":" ","ind2":"2","subfields":[{"a":"Hcd,u"},{"b":"Sk\u00f6nlitteratur"}]}},{"005":"20050204111518.0"},{"999":{"ind1":" ","ind2":" ","subfields":[{"0":"nothing"},{"1":"everything"}]}},{"999":{"ind1":" ","ind2":" ","subfields":[{"a":"bee"},{"0":"cee"},{"d":"eee"}]}}]} PK�����u]p޸����"��test/File_MARC/tests/marc_007.phptnu�[��������--TEST-- marc_007: Use key=>value iteration for tags and codes --SKIPIF-- <?php include('tests/skipif.inc'); ?> --FILE-- <?php $dir = dirname(__FILE__); require __DIR__ . '/bootstrap.php'; $marc_file = new File_MARC($dir . '/' . 'example.mrc'); if ($marc_record = $marc_file->next()) { foreach ($marc_record->getFields() as $tag=>$value) { print "$tag: "; if ($value instanceof File_MARC_Control_Field) { print $value->getData(); } else { foreach ($value->getSubfields() as $code=>$subdata) { print "_$code"; } } print "\n"; } } ?> --EXPECT-- 001: 0000000044 003: EMILDA 008: 980120s1998 fi j 000 0 swe 020: _a_c 035: _9 040: _a 042: _9_9 084: _a_2 084: _5_a_2 084: _5_a_2 084: _5_a_2 100: _a_d 245: _a_c 250: _a 260: _a_b_c_e_f 300: _a_b_c 440: _a_x 500: _a 599: _a 740: _a 775: _z_w_9 841: _5_a_b_e 841: _5_a_b_e 841: _5_a_b_e 841: _5_a_b_e 841: _5_a_b_e 841: _5_a_b_e 852: _5_b_c_h_j 852: _5_b_c_h 852: _5_b 852: _5_b_j 852: _5_b_c_h_j 852: _5_b_h_j 900: _a_d_u_d 900: _a_d_u_d 900: _a_d_u_d 900: _a_d_u_d 900: _a_d_u_d 900: _a_d_u_d 976: _a_b 005: 20050204111518.0 PK�����u]N&��&��&��test/File_MARC/tests/marc_xml_002.phptnu�[��������--TEST-- marc_xml_002: iterate and pretty print a MARC record (LOC standard) --SKIPIF-- <?php include('tests/skipif.inc'); ?> --FILE-- <?php $dir = dirname(__FILE__); require __DIR__ . '/bootstrap.php'; $marc_file = new File_MARC($dir . '/' . 'sandburg.mrc'); while ($marc_record = $marc_file->next()) { print $marc_record->toXML(); print "\n"; } ?> --EXPECT-- <?xml version="1.0" encoding="UTF-8"?> <collection xmlns="http://www.loc.gov/MARC21/slim"> <record> <leader>01142cam 2200301 a 4500</leader> <controlfield tag="001"> 92005291 </controlfield> <controlfield tag="003">DLC</controlfield> <controlfield tag="005">19930521155141.9</controlfield> <controlfield tag="008">920219s1993 caua j 000 0 eng </controlfield> <datafield tag="010" ind1=" " ind2=" "> <subfield code="a"> 92005291 </subfield> </datafield> <datafield tag="020" ind1=" " ind2=" "> <subfield code="a">0152038655 :</subfield> <subfield code="c">$15.95</subfield> </datafield> <datafield tag="040" ind1=" " ind2=" "> <subfield code="a">DLC</subfield> <subfield code="c">DLC</subfield> <subfield code="d">DLC</subfield> </datafield> <datafield tag="042" ind1=" " ind2=" "> <subfield code="a">lcac</subfield> </datafield> <datafield tag="050" ind1="0" ind2="0"> <subfield code="a">PS3537.A618</subfield> <subfield code="b">A88 1993</subfield> </datafield> <datafield tag="082" ind1="0" ind2="0"> <subfield code="a">811/.52</subfield> <subfield code="2">20</subfield> </datafield> <datafield tag="100" ind1="1" ind2=" "> <subfield code="a">Sandburg, Carl,</subfield> <subfield code="d">1878-1967.</subfield> </datafield> <datafield tag="245" ind1="1" ind2="0"> <subfield code="a">Arithmetic /</subfield> <subfield code="c">Carl Sandburg ; illustrated as an anamorphic adventure by Ted Rand.</subfield> </datafield> <datafield tag="250" ind1=" " ind2=" "> <subfield code="a">1st ed.</subfield> </datafield> <datafield tag="260" ind1=" " ind2=" "> <subfield code="a">San Diego :</subfield> <subfield code="b">Harcourt Brace Jovanovich,</subfield> <subfield code="c">c1993.</subfield> </datafield> <datafield tag="300" ind1=" " ind2=" "> <subfield code="a">1 v. (unpaged) :</subfield> <subfield code="b">ill. (some col.) ;</subfield> <subfield code="c">26 cm.</subfield> </datafield> <datafield tag="500" ind1=" " ind2=" "> <subfield code="a">One Mylar sheet included in pocket.</subfield> </datafield> <datafield tag="520" ind1=" " ind2=" "> <subfield code="a">A poem about numbers and their characteristics. Features anamorphic, or distorted, drawings which can be restored to normal by viewing from a particular angle or by viewing the image's reflection in the provided Mylar cone.</subfield> </datafield> <datafield tag="650" ind1=" " ind2="0"> <subfield code="a">Arithmetic</subfield> <subfield code="x">Juvenile poetry.</subfield> </datafield> <datafield tag="650" ind1=" " ind2="0"> <subfield code="a">Children's poetry, American.</subfield> </datafield> <datafield tag="650" ind1=" " ind2="1"> <subfield code="a">Arithmetic</subfield> <subfield code="x">Poetry.</subfield> </datafield> <datafield tag="650" ind1=" " ind2="1"> <subfield code="a">American poetry.</subfield> </datafield> <datafield tag="650" ind1=" " ind2="1"> <subfield code="a">Visual perception.</subfield> </datafield> <datafield tag="700" ind1="1" ind2=" "> <subfield code="a">Rand, Ted,</subfield> <subfield code="e">ill.</subfield> </datafield> </record> </collection> PK�����u]5;-��-����test/File_MARC/tests/music.xmlnu�[��������<?xml version="1.0" encoding="UTF-8"?> <collection xmlns="http://www.loc.gov/MARC21/slim"> <record> <leader>01145ncm a2200277 i 4500</leader> <controlfield tag="001">000073594</controlfield> <controlfield tag="004">AAJ5802</controlfield> <controlfield tag="005">20030415102100.0</controlfield> <controlfield tag="008">801107s1977 nyujza </controlfield> <datafield tag="010" ind1=" " ind2=" "> <subfield code="a"> 77771106 </subfield> </datafield> <datafield tag="035" ind1=" " ind2=" "> <subfield code="a">(CaOTUIC)15460184</subfield> </datafield> <datafield tag="035" ind1="9" ind2=" "> <subfield code="a">AAJ5802</subfield> </datafield> <datafield tag="040" ind1=" " ind2=" "> <subfield code="a">LC</subfield> </datafield> <datafield tag="050" ind1="0" ind2="0"> <subfield code="a">M1366</subfield> <subfield code="b">.M62</subfield> <subfield code="d">M1527.2</subfield> </datafield> <datafield tag="245" ind1="0" ind2="4"> <subfield code="a">The Modern Jazz Quartet :</subfield> <subfield code="b">The legendary profile. --</subfield> </datafield> <datafield tag="260" ind1=" " ind2=" "> <subfield code="a">New York :</subfield> <subfield code="b">M.J.Q. Music,</subfield> <subfield code="c">c1977.</subfield> </datafield> <datafield tag="300" ind1=" " ind2=" "> <subfield code="a">score (72 p.) ;</subfield> <subfield code="c">31 cm.</subfield> </datafield> <datafield tag="500" ind1=" " ind2=" "> <subfield code="a">For piano, vibraphone, drums, and double bass.</subfield> </datafield> <datafield tag="505" ind1="0" ind2=" "> <subfield code="a">Lewis, J. Django.--Lewis, J. Plastic dreams (music from the film Kemek).--Lewis, J. Dancing (music from the film Kemek).--Lewis, J. Blues in A minor.--Lewis, J. Blues in B́Ư.--Lewis, J. Precious joy.--Jackson, M. The martyr.--Jackson, M. The legendary profile.</subfield> </datafield> <datafield tag="650" ind1=" " ind2="0"> <subfield code="a">Jazz.</subfield> </datafield> <datafield tag="650" ind1=" " ind2="0"> <subfield code="a">Motion picture music</subfield> <subfield code="v">Excerpts</subfield> <subfield code="v">Scores.</subfield> </datafield> <datafield tag="700" ind1="1" ind2="2"> <subfield code="a">Lewis, John,</subfield> <subfield code="d">1920-</subfield> <subfield code="t">Selections.</subfield> <subfield code="f">1977.</subfield> </datafield> <datafield tag="700" ind1="1" ind2="2"> <subfield code="a">Jackson, Milt.</subfield> <subfield code="t">Martyrs.</subfield> <subfield code="f">1977.</subfield> </datafield> <datafield tag="700" ind1="1" ind2="2"> <subfield code="a">Jackson, Milt.</subfield> <subfield code="t">Legendary profile.</subfield> <subfield code="f">1977.</subfield> </datafield> <datafield tag="740" ind1="4" ind2=" "> <subfield code="a">The legendary profile.</subfield> </datafield> <datafield tag="852" ind1="0" ind2="0"> <subfield code="b">MUSIC</subfield> <subfield code="c">MAIN</subfield> <subfield code="k">folio</subfield> <subfield code="h">M1366</subfield> <subfield code="i">M62</subfield> <subfield code="9">1</subfield> <subfield code="4">Marvin Duchow Music</subfield> <subfield code="5"></subfield> </datafield> </record> <record> <leader>01293cjm a2200289 a 4500</leader> <controlfield tag="001">001878039</controlfield> <controlfield tag="005">20050110174900.0</controlfield> <controlfield tag="007">sd fungnn|||e|</controlfield> <controlfield tag="008">940202r19931981nyujzn i d</controlfield> <datafield tag="024" ind1="1" ind2=" "> <subfield code="a">7464573372</subfield> </datafield> <datafield tag="028" ind1="0" ind2="2"> <subfield code="a">JK 57337</subfield> <subfield code="b">Red Baron</subfield> </datafield> <datafield tag="035" ind1=" " ind2=" "> <subfield code="a">(OCoLC)29737267</subfield> </datafield> <datafield tag="040" ind1=" " ind2=" "> <subfield code="a">SVP</subfield> <subfield code="c">SVP</subfield> <subfield code="d">LGG</subfield> </datafield> <datafield tag="100" ind1="1" ind2=" "> <subfield code="a">Desmond, Paul,</subfield> <subfield code="d">1924-</subfield> </datafield> <datafield tag="245" ind1="1" ind2="0"> <subfield code="a">Paul Desmond & the Modern Jazz Quartet</subfield> <subfield code="h">[sound recording]</subfield> </datafield> <datafield tag="260" ind1=" " ind2=" "> <subfield code="a">New York, N.Y. :</subfield> <subfield code="b">Red Baron :</subfield> <subfield code="b">Manufactured by Sony Music Entertainment,</subfield> <subfield code="c">p1993.</subfield> </datafield> <datafield tag="300" ind1=" " ind2=" "> <subfield code="a">1 sound disc (39 min.) :</subfield> <subfield code="b">digital ;</subfield> <subfield code="c">4 3/4 in.</subfield> </datafield> <datafield tag="511" ind1="0" ind2=" "> <subfield code="a">Paul Desmond, alto saxophone; Modern Jazz Quartet: John Lewis, piano; Milt Jackson, vibraphone; Percy Heath, bass; Connie Kay, drums.</subfield> </datafield> <datafield tag="500" ind1=" " ind2=" "> <subfield code="a">All arrangements by John Lewis.</subfield> </datafield> <datafield tag="518" ind1=" " ind2=" "> <subfield code="a">Recorded live on December 25, 1971 at Town Hall, NYC.</subfield> </datafield> <datafield tag="500" ind1=" " ind2=" "> <subfield code="a">Originally released in 1981 by Finesse as LP FW 27487.</subfield> </datafield> <datafield tag="500" ind1=" " ind2=" "> <subfield code="a">Program notes by Irving Townsend, June 1981, on container insert.</subfield> </datafield> <datafield tag="505" ind1="0" ind2=" "> <subfield code="a">Greensleeves -- You go to my head -- Blue dove -- Jesus Christ Superstar -- Here's that rainy day -- East of the sun -- Bags' new groove.</subfield> </datafield> <datafield tag="650" ind1=" " ind2="0"> <subfield code="a">Jazz</subfield> <subfield code="y">1971-1980.</subfield> </datafield> <datafield tag="700" ind1="1" ind2=" "> <subfield code="a">Lewis, John,</subfield> <subfield code="d">1920-</subfield> </datafield> <datafield tag="710" ind1="2" ind2=" "> <subfield code="a">Modern Jazz Quartet.</subfield> </datafield> <datafield tag="740" ind1="0" ind2=" "> <subfield code="a">Paul Desmond and the Modern Jazz Quartet.</subfield> </datafield> </record> <record> <leader>01829cjm a2200385 a 4500</leader> <controlfield tag="001">001964482</controlfield> <controlfield tag="005">20060626132700.0</controlfield> <controlfield tag="007">sd fzngnn|m|e|</controlfield> <controlfield tag="008">871211p19871957nyujzn d</controlfield> <datafield tag="024" ind1="1" ind2=" "> <subfield code="a">4228332902</subfield> </datafield> <datafield tag="028" ind1="0" ind2="1"> <subfield code="a">833 290-2</subfield> <subfield code="b">Verve</subfield> </datafield> <datafield tag="033" ind1="0" ind2=" "> <subfield code="a">19571027</subfield> <subfield code="b">6299</subfield> <subfield code="c">D56</subfield> </datafield> <datafield tag="033" ind1="0" ind2=" "> <subfield code="a">196112--</subfield> <subfield code="b">3804</subfield> <subfield code="c">N4</subfield> </datafield> <datafield tag="033" ind1="0" ind2=" "> <subfield code="a">19571019</subfield> <subfield code="b">4104</subfield> <subfield code="c">C6</subfield> </datafield> <datafield tag="033" ind1="0" ind2=" "> <subfield code="a">197107--</subfield> <subfield code="b">6299</subfield> <subfield code="c">V7</subfield> </datafield> <datafield tag="035" ind1=" " ind2=" "> <subfield code="a">(OCoLC)17222092</subfield> </datafield> <datafield tag="040" ind1=" " ind2=" "> <subfield code="a">CPL</subfield> <subfield code="c">CPL</subfield> <subfield code="d">OCL</subfield> <subfield code="d">LGG</subfield> </datafield> <datafield tag="048" ind1=" " ind2=" "> <subfield code="a">pz01</subfield> <subfield code="a">ka01</subfield> <subfield code="a">sd01</subfield> <subfield code="a">pd01</subfield> </datafield> <datafield tag="110" ind1="2" ind2=" "> <subfield code="a">Modern Jazz Quartet.</subfield> <subfield code="4">prf</subfield> </datafield> <datafield tag="245" ind1="1" ind2="4"> <subfield code="a">The Modern Jazz Quartet plus</subfield> <subfield code="h">[sound recording].</subfield> </datafield> <datafield tag="260" ind1=" " ind2=" "> <subfield code="a">[New York] :</subfield> <subfield code="b">Verve,</subfield> <subfield code="c">p1987.</subfield> </datafield> <datafield tag="300" ind1=" " ind2=" "> <subfield code="a">1 sound disc :</subfield> <subfield code="b">digital ;</subfield> <subfield code="c">4 3/4 in.</subfield> </datafield> <datafield tag="440" ind1=" " ind2="0"> <subfield code="a">Compact jazz</subfield> </datafield> <datafield tag="511" ind1="0" ind2=" "> <subfield code="a">Modern Jazz Quartet (principally) ; Milt Jackson, vibraphone (2nd and 8th works) ; Oscar Peterson, piano (2nd and 8th works) ; Ray Brown, bass (2nd and 8th works) ; Ed Thigpen (2nd work), Louis Hayes (8th work), drums.</subfield> </datafield> <datafield tag="518" ind1=" " ind2=" "> <subfield code="a">Recorded live, Oct. 27, 1957, at the Donaueschingen Jazz Festival (1st, 5th, 7th, and 10th works); Dec. 1961, in New York (2nd work); live, Oct. 19, 1957, at the Opera House, Chicago (3rd, 4th, 6th, and 9th works); July 1971, in Villingen, Germany (8th work).</subfield> </datafield> <datafield tag="500" ind1=" " ind2=" "> <subfield code="a">Compact disc.</subfield> </datafield> <datafield tag="500" ind1=" " ind2=" "> <subfield code="a">Analog recording.</subfield> </datafield> <datafield tag="505" ind1="0" ind2=" "> <subfield code="a">The golden striker (4:08) -- On Green Dolphin Street (7:28) -- D & E (4:55) -- I'll remember April (4:51) -- Cort©·ge (7:15) -- Now's the time (4:43) -- J.B. blues (5:09) -- Reunion blues (6:35) -- 'Round midnight (3:56) -- Three windows (7:20).</subfield> </datafield> <datafield tag="650" ind1=" " ind2="0"> <subfield code="a">Jazz.</subfield> </datafield> <datafield tag="700" ind1="1" ind2=" "> <subfield code="a">Jackson, Milt.</subfield> <subfield code="4">prf</subfield> </datafield> <datafield tag="700" ind1="1" ind2=" "> <subfield code="a">Peterson, Oscar,</subfield> <subfield code="d">1925-</subfield> <subfield code="4">prf</subfield> </datafield> <datafield tag="700" ind1="1" ind2=" "> <subfield code="a">Brown, Ray,</subfield> <subfield code="d">1926-2002.</subfield> <subfield code="4">prf</subfield> </datafield> <datafield tag="700" ind1="1" ind2=" "> <subfield code="a">Thigpen, Ed.</subfield> <subfield code="4">prf</subfield> </datafield> <datafield tag="700" ind1="1" ind2=" "> <subfield code="a">Hayes, Louis,</subfield> <subfield code="d">1937-</subfield> <subfield code="4">prf</subfield> </datafield> <datafield tag="852" ind1="8" ind2="0"> <subfield code="b">MUSIC</subfield> <subfield code="c">AV</subfield> <subfield code="h">CD 1131</subfield> <subfield code="4">Marvin Duchow Music</subfield> <subfield code="5">Audio-Visual</subfield> </datafield> </record> </collection> PK�����u]ԛ �� ��"��test/File_MARC/tests/marc_014.phptnu�[��������--TEST-- marc_014: Add fields to a MARC record --SKIPIF-- <?php include('tests/skipif.inc'); ?> --FILE-- <?php $dir = dirname(__FILE__); require __DIR__ . '/bootstrap.php'; // Get ourselves a MARC record $marc_file = new File_MARC($dir . '/' . 'example.mrc'); $marc_record = $marc_file->next(); // create some subfields $subfields[] = new File_MARC_Subfield('a', 'nothing'); $subfields[] = new File_MARC_Subfield('z', 'everything'); // create a data field $data_field = new File_MARC_Data_Field('100', $subfields, '0'); // append the data field $marc_record->appendField($data_field); // create a control field $ctrl_field = new File_MARC_Control_Field('001', '01234567890'); // prepend the control field $marc_record->prependField($ctrl_field); // reproduce test case reported by Mark Jordan $subfields_966_2[] = new File_MARC_Subfield('l', 'web'); $subfields_966_2[] = new File_MARC_Subfield('r', '0'); $subfields_966_2[] = new File_MARC_Subfield('s', 'b'); $subfields_966_2[] = new File_MARC_Subfield('i', '49'); $subfields_966_2[] = new File_MARC_Subfield('c', '1'); $field_966_2 = new File_MARC_Data_Field('966', $subfields_966_2, null, null); $marc_record->appendField($field_966_2); // let's see the results print utf8_encode($marc_record); print "\n"; ?> --EXPECT-- LDR 01850 2200517 4500 001 01234567890 001 0000000044 003 EMILDA 008 980120s1998 fi j 000 0 swe 020 _a9515008808 _cFIM 72:00 035 _99515008808 040 _aNB 042 _9NB _9SEE 084 _aHcd,u _2kssb/6 084 _5NB _auHc _2kssb 084 _5SEE _aHcf _2kssb/6 084 _5Q _aHcd,uf _2kssb/6 100 1 _aJansson, Tove, _d1914-2001 245 04 _aDet osynliga barnet och andra berättelser / _cTove Jansson 250 _a7. uppl. 260 _aHelsingfors : _bSchildt, _c1998 ; _e(Falun : _fScandbook) 300 _a166, [4] s. : _bill. ; _c21 cm 440 0 _aMumin-biblioteket, _x99-0698931-9 500 _aOriginaluppl. 1962 599 _aLi: S 740 4 _aDet osynliga barnet 775 1 _z951-50-0385-7 _w9515003857 _907 841 _5Li _axa _b0201080u 0 4000uu |000000 _e1 841 _5SEE _axa _b0201080u 0 4000uu |000000 _e1 841 _5L _axa _b0201080u 0 4000uu |000000 _e1 841 _5NB _axa _b0201080u 0 4000uu |000000 _e1 841 _5Q _axa _b0201080u 0 4000uu |000000 _e1 841 _5S _axa _b0201080u 0 4000uu |000000 _e1 852 _5NB _bNB _cNB98:12 _hplikt _jR, 980520 852 _5Li _bLi _cCNB _hh,u 852 _5SEE _bSEE 852 _5Q _bQ _j98947 852 _5L _bL _c0100 _h98/ _j3043 H 852 _5S _bS _hSv97 _j7235 900 1s _aYanson, Tobe, _d1914-2001 _uJansson, Tove, _d1914-2001 900 1s _aJanssonová, Tove, _d1914-2001 _uJansson, Tove, _d1914-2001 900 1s _aJansone, Tuve, _d1914-2001 _uJansson, Tove, _d1914-2001 900 1s _aJanson, Tuve, _d1914-2001 _uJansson, Tove, _d1914-2001 900 1s _aJansson, Tuve, _d1914-2001 _uJansson, Tove, _d1914-2001 900 1s _aJanssonova, Tove, _d1914-2001 _uJansson, Tove, _d1914-2001 976 2 _aHcd,u _bSkönlitteratur 005 20050204111518.0 100 0 _anothing _zeverything 966 _lweb _r0 _sb _i49 _c1 PK�����u]f=��=��$��test/File_MARC/tests/bad_example.mrcnu�[��������01853 a2200517 450000100110000000300070001100800390001802000260005703500150008304000070009804200120010508400180011708400180013508400210015308400220017410000300019624500630022625000130028926000580030230-0033003604400037003935000023004305990010004537400024004637750034004878410048005218410049005698410047006188410048006658410047007138410047007608520038008078520021008458520013008668520016008798520028008958520021009239000056009449000061010009000057010619000056011189000057011749000060012319760027012910050017013180000000044EMILDA980120s1998 fi j 000 0 swe a9515008808cFIM 72:00 99515008808 aNB 9NB9SEE aHcd,u2kssb/6 5NBauHc2kssb 5SEEaHcf2kssb/6 5QaHcd,uf2kssb/61 aJansson, Tove,d1914-200104aDet osynliga barnet och andra bert̃telser /cTove Jansson a7. uppl. aHelsingfors :bSchildt,c1998 ;e(Falun :fScandbook) a166, [4] s. :bill. ;c21 cm 0aMumin-biblioteket,x99-0698931-9 aOriginaluppl. 1962 aLi: S4 aDet osynliga barnet1 z951-50-0385-7w9515003857907 5Liaxab0201080u 0 4000uu |000000e1 5SEEaxab0201080u 0 4000uu |000000e1 5Laxab0201080u 0 4000uu |000000e1 5NBaxab0201080u 0 4000uu |000000e1 5Qaxab0201080u 0 4000uu |000000e1 5Saxab0201080u 0 4000uu |000000e1 5NBbNBcNB98:12hpliktjR, 980520 5LibLicCNBhh,u 5SEEbSEE 5QbQj98947 5LbLc0100h98/j3043 H 5SbShSv97j72351saYanson, Tobe,d1914-2001uJansson, Tove,d1914-20011saJanssonov,̀ Tove,d1914-2001uJansson, Tove,d1914-20011saJansone, Tuve,d1914-2001uJansson, Tove,d1914-20011saJanson, Tuve,d1914-2001uJansson, Tove,d1914-20011saJansson, Tuve,d1914-2001uJansson, Tove,d1914-20011saJanssonova, Tove,d1914-2001uJansson, Tove,d1914-2001 2aHcd,ubSkn̲litteratur20050204111518.0PK�����u]e �� ��"��test/File_MARC/tests/marc_011.phptnu�[��������--TEST-- marc_011: iterate and pretty print a MARC record (SOURCE_STRING) --SKIPIF-- <?php include('tests/skipif.inc'); ?> --FILE-- <?php $dir = dirname(__FILE__); require __DIR__ . '/bootstrap.php'; // Pull the MARC records into a string (as though we got it from YAZ) $marc_string = file_get_contents($dir . '/' . 'example.mrc'); // Use the File_MARC::SOURCE_STRING flag to indicate that our source is a, uh, string $marc_file = new File_MARC($marc_string, File_MARC::SOURCE_STRING); while ($marc_record = $marc_file->next()) { print $marc_record; print "\n"; } ?> --EXPECT-- LDR 01850 2200517 4500 001 0000000044 003 EMILDA 008 980120s1998 fi j 000 0 swe 020 _a9515008808 _cFIM 72:00 035 _99515008808 040 _aNB 042 _9NB _9SEE 084 _aHcd,u _2kssb/6 084 _5NB _auHc _2kssb 084 _5SEE _aHcf _2kssb/6 084 _5Q _aHcd,uf _2kssb/6 100 1 _aJansson, Tove, _d1914-2001 245 04 _aDet osynliga barnet och andra berttelser / _cTove Jansson 250 _a7. uppl. 260 _aHelsingfors : _bSchildt, _c1998 ; _e(Falun : _fScandbook) 300 _a166, [4] s. : _bill. ; _c21 cm 440 0 _aMumin-biblioteket, _x99-0698931-9 500 _aOriginaluppl. 1962 599 _aLi: S 740 4 _aDet osynliga barnet 775 1 _z951-50-0385-7 _w9515003857 _907 841 _5Li _axa _b0201080u 0 4000uu |000000 _e1 841 _5SEE _axa _b0201080u 0 4000uu |000000 _e1 841 _5L _axa _b0201080u 0 4000uu |000000 _e1 841 _5NB _axa _b0201080u 0 4000uu |000000 _e1 841 _5Q _axa _b0201080u 0 4000uu |000000 _e1 841 _5S _axa _b0201080u 0 4000uu |000000 _e1 852 _5NB _bNB _cNB98:12 _hplikt _jR, 980520 852 _5Li _bLi _cCNB _hh,u 852 _5SEE _bSEE 852 _5Q _bQ _j98947 852 _5L _bL _c0100 _h98/ _j3043 H 852 _5S _bS _hSv97 _j7235 900 1s _aYanson, Tobe, _d1914-2001 _uJansson, Tove, _d1914-2001 900 1s _aJanssonov, Tove, _d1914-2001 _uJansson, Tove, _d1914-2001 900 1s _aJansone, Tuve, _d1914-2001 _uJansson, Tove, _d1914-2001 900 1s _aJanson, Tuve, _d1914-2001 _uJansson, Tove, _d1914-2001 900 1s _aJansson, Tuve, _d1914-2001 _uJansson, Tove, _d1914-2001 900 1s _aJanssonova, Tove, _d1914-2001 _uJansson, Tove, _d1914-2001 976 2 _aHcd,u _bSknlitteratur 005 20050204111518.0 PK�����u]Ҕ �� ��$��test/File_MARC/tests/marc_16783.phptnu�[��������--TEST-- marc_16783: iterate and pretty print a non-compliant MARC record (tag = '30-') --SKIPIF-- <?php include('tests/skipif.inc'); ?> --FILE-- <?php $dir = dirname(__FILE__); require __DIR__ . '/bootstrap.php'; $marc_file = new File_MARC($dir . '/' . 'bad_example.mrc'); while ($marc_record = $marc_file->next()) { print $marc_record; print "\n"; } ?> --EXPECT-- LDR 01853 a2200517 4500 001 0000000044 003 EMILDA 008 980120s1998 fi j 000 0 swe 020 _a9515008808 _cFIM 72:00 035 _99515008808 040 _aNB 042 _9NB _9SEE 084 _aHcd,u _2kssb/6 084 _5NB _auHc _2kssb 084 _5SEE _aHcf _2kssb/6 084 _5Q _aHcd,uf _2kssb/6 100 1 _aJansson, Tove, _d1914-2001 245 04 _aDet osynliga barnet och andra bert̃telser / _cTove Jansson 250 _a7. uppl. 260 _aHelsingfors : _bSchildt, _c1998 ; _e(Falun : _fScandbook) 440 0 _aMumin-biblioteket, _x99-0698931-9 500 _aOriginaluppl. 1962 599 _aLi: S 740 4 _aDet osynliga barnet 775 1 _z951-50-0385-7 _w9515003857 _907 841 _5Li _axa _b0201080u 0 4000uu |000000 _e1 841 _5SEE _axa _b0201080u 0 4000uu |000000 _e1 841 _5L _axa _b0201080u 0 4000uu |000000 _e1 841 _5NB _axa _b0201080u 0 4000uu |000000 _e1 841 _5Q _axa _b0201080u 0 4000uu |000000 _e1 841 _5S _axa _b0201080u 0 4000uu |000000 _e1 852 _5NB _bNB _cNB98:12 _hplikt _jR, 980520 852 _5Li _bLi _cCNB _hh,u 852 _5SEE _bSEE 852 _5Q _bQ _j98947 852 _5L _bL _c0100 _h98/ _j3043 H 852 _5S _bS _hSv97 _j7235 900 1s _aYanson, Tobe, _d1914-2001 _uJansson, Tove, _d1914-2001 900 1s _aJanssonov,̀ Tove, _d1914-2001 _uJansson, Tove, _d1914-2001 900 1s _aJansone, Tuve, _d1914-2001 _uJansson, Tove, _d1914-2001 900 1s _aJanson, Tuve, _d1914-2001 _uJansson, Tove, _d1914-2001 900 1s _aJansson, Tuve, _d1914-2001 _uJansson, Tove, _d1914-2001 900 1s _aJanssonova, Tove, _d1914-2001 _uJansson, Tove, _d1914-2001 976 2 _aHcd,u _bSkn̲litteratur 005 20050204111518.0 PK�����u]7����"��test/File_MARC/tests/marc_009.phptnu�[��������--TEST-- marc_009: Parse a record where leader record length != real record length --SKIPIF-- <?php include('tests/skipif.inc'); ?> --FILE-- <?php $dir = dirname(__FILE__); require __DIR__ . '/bootstrap.php'; $marc_file = new File_MARC($dir . '/' . 'wronglen.mrc'); while ($marc_record = $marc_file->next()) { print $marc_record; print "\n"; print "WARNINGS:\n"; foreach ($marc_record->getWarnings() as $warning) { print " * $warning\n"; } } ?> --EXPECT-- LDR 00727nam 2200205 a 4500 001 03-0016458 005 19971103184734.0 008 970701s1997 oru u000 0 eng u 035 _a(Sirsi) a351664 050 00 _aML270.2 _b.A6 1997 100 1 _aAnthony, James R. 245 00 _aFrench baroque music from Beaujoyeulx to Rameau 250 _aRev. and expanded ed. 260 _aPortland, OR : _bAmadeus Press, _c1997. 300 _a586 p. : _bmusic 650 0 _aMusic _<France _y16th century _xHistory and criticism. 650 0 _aMusic _zFrance _y17th century _xHistory and criticism. 650 0 _aMusic _zFrance _y18th century _xHistory and criticism. 949 _aML 270.2 A6 1997 _wLC _i30007006841505 _rY _tBOOKS _lHUNT-CIRC _mHUNEXTRALON WARNINGS: * Invalid record length: Leader says "00727" bytes; actual record length is "741" * Field for tag "949" does not end with an end of field character * Field for tag "596" does not end with an end of field character * Invalid indicators "GSTUFF" forced to blanks for tag "596" PK�����u]81��1��)��test/File_MARC/tests/marc_record_001.phptnu�[��������--TEST-- marc_record_001: create a MARC record from scratch --SKIPIF-- <?php include('tests/skipif.inc'); ?> --FILE-- <?php $dir = dirname(__FILE__); require __DIR__ . '/bootstrap.php'; $marc = new File_MARC_Record(); $marc->appendField(new File_MARC_Data_Field('245', array( new File_MARC_Subfield('a', 'Main title: '), new File_MARC_Subfield('b', 'subtitle'), new File_MARC_Subfield('c', 'author') ), null, null )); print $marc; ?> --EXPECT-- LDR 245 _aMain title: _bsubtitle _cauthor PK�����u]è{��{��"��test/File_MARC/tests/marc_020.phptnu�[��������--TEST-- marc_020: Test MARC binary output --SKIPIF-- <?php include('tests/skipif.inc'); ?> --FILE-- <?php $dir = dirname(__FILE__); require __DIR__ . '/bootstrap.php'; // Get ourselves a MARC record $marc_file = new File_MARC($dir . '/' . 'example.mrc'); $marc_record = $marc_file->next(); // create some subfields $subfields[] = new File_MARC_Subfield('a', 'nothing'); $subfields[] = new File_MARC_Subfield('z', 'everything'); // create a data field $data_field = new File_MARC_Data_Field('100', $subfields, '0'); // append the data field $marc_record->appendField($data_field); // create a control field $ctrl_field = new File_MARC_Control_Field('001', '01234567890'); // prepend the control field $marc_record->prependField($ctrl_field); // reproduce test case reported by Mark Jordan $subfields_966_2[] = new File_MARC_Subfield('l', 'web'); $subfields_966_2[] = new File_MARC_Subfield('r', '0'); $subfields_966_2[] = new File_MARC_Subfield('s', 'b'); $subfields_966_2[] = new File_MARC_Subfield('i', '49'); $subfields_966_2[] = new File_MARC_Subfield('c', '1'); $field_966_2 = new File_MARC_Data_Field('966', $subfields_966_2, null, null); $marc_record->appendField($field_966_2); // let's see the results print convert_uuencode($marc_record->toRaw()); ?> --EXPECT-- M,#$Y-#,@("`@(#(R,#`U-3,@("`T-3`P,#`Q,#`Q,C`P,#`P,#`Q,#`Q,3`P M,#$R,#`S,#`P-S`P,#(S,#`X,#`S.3`P,#,P,#(P,#`R-C`P,#8Y,#,U,#`Q M-3`P,#DU,#0P,#`P-S`P,3$P,#0R,#`Q,C`P,3$W,#@T,#`Q.#`P,3(Y,#@T M,#`Q.#`P,30W,#@T,#`R,3`P,38U,#@T,#`R,C`P,3@V,3`P,#`S,#`P,C`X M,C0U,#`V,C`P,C,X,C4P,#`Q,S`P,S`P,C8P,#`U.#`P,S$S,S`P,#`S,S`P M,S<Q-#0P,#`S-S`P-#`T-3`P,#`R,S`P-#0Q-3DY,#`Q,#`P-#8T-S0P,#`R M-#`P-#<T-S<U,#`S-#`P-#DX.#0Q,#`T.#`P-3,R.#0Q,#`T.3`P-3@P.#0Q M,#`T-S`P-C(Y.#0Q,#`T.#`P-C<V.#0Q,#`T-S`P-S(T.#0Q,#`T-S`P-S<Q M.#4R,#`S.#`P.#$X.#4R,#`R,3`P.#4V.#4R,#`Q,S`P.#<W.#4R,#`Q-C`P M.#DP.#4R,#`R.#`P.3`V.#4R,#`R,3`P.3,T.3`P,#`U-C`P.34U.3`P,#`V M,#`Q,#$Q.3`P,#`U-S`Q,#<Q.3`P,#`U-C`Q,3(X.3`P,#`U-S`Q,3@T.3`P M,#`V,#`Q,C0Q.3<V,#`R-C`Q,S`Q,#`U,#`Q-S`Q,S(W,3`P,#`R-#`Q,S0T M.38V,#`R,3`Q,S8X'C`Q,C,T-38W.#DP'C`P,#`P,#`P-#0>14U)3$1!'CDX M,#$R,',Q.3DX("`@(&9I("`@("!J("`@("`@,#`P(#`@<W=E'B`@'V$Y-3$U M,#`X.#`X'V-&24T@-S(Z,#`>("`?.3DU,34P,#@X,#@>("`?84Y"'B`@'SE. M0A\Y4T5%'B`@'V%(8V0L=1\R:W-S8B\V'B`@'S5.0A]A=4AC'S)K<W-B'B`@ M'S53144?84AC9A\R:W-S8B\V'B`@'S51'V%(8V0L=68?,FMS<V(O-AXQ(!]A M2F%N<W-O;BP@5&]V92P?9#$Y,30M,C`P,1XP-!]A1&5T(&]S>6YL:6=A(&)A M<FYE="!O8V@@86YD<F$@8F5RY'1T96QS97(@+Q]C5&]V92!*86YS<V]N'B`@ M'V$W+B!U<'!L+AX@(!]A2&5L<VEN9V9O<G,@.A]B4V-H:6QD="P?8S$Y.3@@ M.Q]E*$9A;'5N(#H?9E-C86YD8F]O:RD>("`?83$V-BP@6S1=(',N(#H?8FEL M;"X@.Q]C,C$@8VT>(#`?84UU;6EN+6)I8FQI;W1E:V5T+!]X.3DM,#8Y.#DS M,2TY'B`@'V%/<FEG:6YA;'5P<&PN(#$Y-C(>("`?84QI.B!3'C0@'V%$970@ M;W-Y;FQI9V$@8F%R;F5T'C$@'WHY-3$M-3`M,#,X-2TW'W<Y-3$U,#`S.#4W M'SDP-QX@(!\U3&D?87AA'V(P,C`Q,#@P=2`@("`P("`@-#`P,'5U("`@?#`P M,#`P,!]E,1X@(!\U4T5%'V%X81]B,#(P,3`X,'4@("`@,"`@(#0P,#!U=2`@ M('PP,#`P,#`?93$>("`?-4P?87AA'V(P,C`Q,#@P=2`@("`P("`@-#`P,'5U M("`@?#`P,#`P,!]E,1X@(!\U3D(?87AA'V(P,C`Q,#@P=2`@("`P("`@-#`P M,'5U("`@?#`P,#`P,!]E,1X@(!\U41]A>&$?8C`R,#$P.#!U("`@(#`@("`T M,#`P=74@("!\,#`P,#`P'V4Q'B`@'S53'V%X81]B,#(P,3`X,'4@("`@,"`@ M(#0P,#!U=2`@('PP,#`P,#`?93$>("`?-4Y"'V).0A]C3D(Y.#HQ,A]H<&QI M:W0?:E(L(#DX,#4R,!X@(!\U3&D?8DQI'V-#3D(?:&@L=1X@(!\U4T5%'V)3 M144>("`?-5$?8E$?:CDX.30W'B`@'S5,'V),'V,P,3`P'V@Y."\?:C,P-#,@ M2!X@(!\U4Q]B4Q]H4W8Y-Q]J-S(S-1XQ<Q]A66%N<V]N+"!4;V)E+!]D,3DQ M-"TR,#`Q'W5*86YS<V]N+"!4;W9E+!]D,3DQ-"TR,#`Q'C%S'V%*86YS<V]N M;W;A+"!4;W9E+!]D,3DQ-"TR,#`Q'W5*86YS<V]N+"!4;W9E+!]D,3DQ-"TR M,#`Q'C%S'V%*86YS;VYE+"!4=79E+!]D,3DQ-"TR,#`Q'W5*86YS<V]N+"!4 M;W9E+!]D,3DQ-"TR,#`Q'C%S'V%*86YS;VXL(%1U=F4L'V0Q.3$T+3(P,#$? M=4IA;G-S;VXL(%1O=F4L'V0Q.3$T+3(P,#$>,7,?84IA;G-S;VXL(%1U=F4L M'V0Q.3$T+3(P,#$?=4IA;G-S;VXL(%1O=F4L'V0Q.3$T+3(P,#$>,7,?84IA M;G-S;VYO=F$L(%1O=F4L'V0Q.3$T+3(P,#$?=4IA;G-S;VXL(%1O=F4L'V0Q M.3$T+3(P,#$>(#(?84AC9"QU'V)3:_9N;&ET=&5R871U<AXR,#`U,#(P-#$Q M,34Q."XP'C`@'V%N;W1H:6YG'WIE=F5R>71H:6YG'B`@'VQW96(?<C`?<V(? (:30Y'V,Q'AT` ` PK�����u]&c��c��"��test/File_MARC/tests/marc_002.phptnu�[��������--TEST-- marc_002: iterate and pretty print MARC records from a file with multiple records --SKIPIF-- <?php include('tests/skipif.inc'); ?> --FILE-- <?php $dir = dirname(__FILE__); require __DIR__ . '/bootstrap.php'; $marc_file = new File_MARC($dir . '/' . 'music.mrc'); while ($marc_record = $marc_file->next()) { print $marc_record; print "\n"; } ?> --EXPECT-- LDR 01145ncm 2200277 i 4500 001 000073594 004 AAJ5802 005 20030415102100.0 008 801107s1977 nyujza 010 _a 77771106 035 _a(CaOTUIC)15460184 035 9 _aAAJ5802 040 _aLC 050 00 _aM1366 _b.M62 _dM1527.2 245 04 _aThe Modern Jazz Quartet : _bThe legendary profile. -- 260 _aNew York : _bM.J.Q. Music, _cc1977. 300 _ascore (72 p.) ; _c31 cm. 500 _aFor piano, vibraphone, drums, and double bass. 505 0 _aLewis, J. Django.--Lewis, J. Plastic dreams (music from the film Kemek).--Lewis, J. Dancing (music from the film Kemek).--Lewis, J. Blues in A minor.--Lewis, J. Blues in B♭.--Lewis, J. Precious joy.--Jackson, M. The martyr.--Jackson, M. The legendary profile. 650 0 _aJazz. 650 0 _aMotion picture music _vExcerpts _vScores. 700 12 _aLewis, John, _d1920- _tSelections. _f1977. 700 12 _aJackson, Milt. _tMartyrs. _f1977. 700 12 _aJackson, Milt. _tLegendary profile. _f1977. 740 4 _aThe legendary profile. 852 00 _bMUSIC _cMAIN _kfolio _hM1366 _iM62 _91 _4Marvin Duchow Music _5 LDR 01293cjm 2200289 a 4500 001 001878039 005 20050110174900.0 007 sd fungnn|||e| 008 940202r19931981nyujzn i d 024 1 _a7464573372 028 02 _aJK 57337 _bRed Baron 035 _a(OCoLC)29737267 040 _aSVP _cSVP _dLGG 100 1 _aDesmond, Paul, _d1924- 245 10 _aPaul Desmond & the Modern Jazz Quartet _h[sound recording] 260 _aNew York, N.Y. : _bRed Baron : _bManufactured by Sony Music Entertainment, _cp1993. 300 _a1 sound disc (39 min.) : _bdigital ; _c4 3/4 in. 511 0 _aPaul Desmond, alto saxophone; Modern Jazz Quartet: John Lewis, piano; Milt Jackson, vibraphone; Percy Heath, bass; Connie Kay, drums. 500 _aAll arrangements by John Lewis. 518 _aRecorded live on December 25, 1971 at Town Hall, NYC. 500 _aOriginally released in 1981 by Finesse as LP FW 27487. 500 _aProgram notes by Irving Townsend, June 1981, on container insert. 505 0 _aGreensleeves -- You go to my head -- Blue dove -- Jesus Christ Superstar -- Here's that rainy day -- East of the sun -- Bags' new groove. 650 0 _aJazz _y1971-1980. 700 1 _aLewis, John, _d1920- 710 2 _aModern Jazz Quartet. 740 0 _aPaul Desmond and the Modern Jazz Quartet. LDR 01829cjm 2200385 a 4500 001 001964482 005 20060626132700.0 007 sd fzngnn|m|e| 008 871211p19871957nyujzn d 024 1 _a4228332902 028 01 _a833 290-2 _bVerve 033 0 _a19571027 _b6299 _cD56 033 0 _a196112-- _b3804 _cN4 033 0 _a19571019 _b4104 _cC6 033 0 _a197107-- _b6299 _cV7 035 _a(OCoLC)17222092 040 _aCPL _cCPL _dOCL _dLGG 048 _apz01 _aka01 _asd01 _apd01 110 2 _aModern Jazz Quartet. _4prf 245 14 _aThe Modern Jazz Quartet plus _h[sound recording]. 260 _a[New York] : _bVerve, _cp1987. 300 _a1 sound disc : _bdigital ; _c4 3/4 in. 440 0 _aCompact jazz 511 0 _aModern Jazz Quartet (principally) ; Milt Jackson, vibraphone (2nd and 8th works) ; Oscar Peterson, piano (2nd and 8th works) ; Ray Brown, bass (2nd and 8th works) ; Ed Thigpen (2nd work), Louis Hayes (8th work), drums. 518 _aRecorded live, Oct. 27, 1957, at the Donaueschingen Jazz Festival (1st, 5th, 7th, and 10th works); Dec. 1961, in New York (2nd work); live, Oct. 19, 1957, at the Opera House, Chicago (3rd, 4th, 6th, and 9th works); July 1971, in Villingen, Germany (8th work). 500 _aCompact disc. 500 _aAnalog recording. 505 0 _aThe golden striker (4:08) -- On Green Dolphin Street (7:28) -- D & E (4:55) -- I'll remember April (4:51) -- Cortège (7:15) -- Now's the time (4:43) -- J.B. blues (5:09) -- Reunion blues (6:35) -- 'Round midnight (3:56) -- Three windows (7:20). 650 0 _aJazz. 700 1 _aJackson, Milt. _4prf 700 1 _aPeterson, Oscar, _d1925- _4prf 700 1 _aBrown, Ray, _d1926-2002. _4prf 700 1 _aThigpen, Ed. _4prf 700 1 _aHayes, Louis, _d1937- _4prf 852 80 _bMUSIC _cAV _hCD 1131 _4Marvin Duchow Music _5Audio-Visual PK�����u]>����&��test/File_MARC/tests/marc_xml_003.phptnu�[��������--TEST-- marc_xml_003: Round-trip a MARCXML record to MARC21 (LOC standard) --SKIPIF-- <?php include('tests/skipif.inc'); ?> --FILE-- <?php $dir = dirname(__FILE__); require __DIR__ . '/bootstrap.php'; $marc_file = new File_MARCXML($dir . '/' . 'sandburg.xml'); while ($marc_record = $marc_file->next()) { print $marc_record->toRaw(); } ?> --EXPECT-- 01142cam 2200301 a 4500001001300000003000400013005001700017008004100034010001700075020002500092040001800117042000900135050002600144082001600170100003200186245008600218250001200304260005200316300004900368500004000417520022800457650003300685650003300718650002400751650002100775650002300796700002100819 92005291 DLC19930521155141.9920219s1993 caua j 000 0 eng  a 92005291  a0152038655 :c$15.95 aDLCcDLCdDLC alcac00aPS3537.A618bA88 199300a811/.522201 aSandburg, Carl,d1878-1967.10aArithmetic /cCarl Sandburg ; illustrated as an anamorphic adventure by Ted Rand. a1st ed. aSan Diego :bHarcourt Brace Jovanovich,cc1993. a1 v. (unpaged) :bill. (some col.) ;c26 cm. aOne Mylar sheet included in pocket. aA poem about numbers and their characteristics. Features anamorphic, or distorted, drawings which can be restored to normal by viewing from a particular angle or by viewing the image's reflection in the provided Mylar cone. 0aArithmeticxJuvenile poetry. 0aChildren's poetry, American. 1aArithmeticxPoetry. 1aAmerican poetry. 1aVisual perception.1 aRand, Ted,eill. PK�����u]*������test/Mail/tests/9137.phptnu�[��������--TEST-- Mail: Test for bug #9137 --FILE-- <?php require_once dirname(__FILE__) . '/../Mail/RFC822.php'; require_once 'PEAR.php'; $addresses = array( array('name' => 'John Doe', 'email' => 'test@example.com'), array('name' => 'John Doe\\', 'email' => 'test@example.com'), array('name' => 'John "Doe', 'email' => 'test@example.com'), array('name' => 'John "Doe\\', 'email' => 'test@example.com'), ); for ($i = 0; $i < count($addresses); $i++) { // construct the address $address = "\"" . addslashes($addresses[$i]['name']) . "\" ". "<".$addresses[$i]['email'].">"; $parsedAddresses = Mail_RFC822::parseAddressList($address); if (is_a($parsedAddresses, 'PEAR_Error')) { echo $address." :: Failed to validate\n"; } else { echo $address." :: Parsed\n"; } } --EXPECT-- "John Doe" <test@example.com> :: Parsed "John Doe\\" <test@example.com> :: Parsed "John \"Doe" <test@example.com> :: Parsed "John \"Doe\\" <test@example.com> :: Parsed PK�����u]w������test/Mail/tests/smtp_error.phptnu�[��������--TEST-- Mail: SMTP Error Reporting --SKIPIF-- <?php require_once 'PEAR/Registry.php'; $registry = new PEAR_Registry(); if (!$registry->packageExists('Net_SMTP')) die("skip\n"); --FILE-- <?php require_once 'Mail.php'; /* Reference a bogus SMTP server address to guarantee a connection failure. */ $params = array('host' => 'bogus.host.tld'); /* Create our SMTP-based mailer object. */ $mailer = Mail::factory('smtp', $params); /* Attempt to send an empty message in order to trigger an error. */ $e = $mailer->send(array(), array(), ''); if (is_a($e, 'PEAR_Error')) { $err = $e->getMessage(); if (preg_match('/Failed to connect to bogus.host.tld:25 \[SMTP: Failed to connect socket:.*/i', $err)) { echo "OK"; } } --EXPECT-- OKPK�����u]q/������test/Mail/tests/13659.phptnu�[��������--TEST-- Mail: Test for bug #13659 --FILE-- <?php //require_once dirname(__FILE__) . '/../Mail/RFC822.php'; require_once 'Mail/RFC822.php'; require_once 'PEAR.php'; $address = '"Test Student" <test@mydomain.com> (test)'; $parser = new Mail_RFC822(); $result = $parser->parseAddressList($address, 'anydomain.com', TRUE); if (!PEAR::isError($result) && is_array($result) && is_object($result[0])) if ($result[0]->personal == '"Test Student"' && $result[0]->mailbox == "test" && $result[0]->host == "mydomain.com" && is_array($result[0]->comment) && $result[0]->comment[0] == 'test') { print("OK"); } ?> --EXPECT-- OK PK�����u]ó������test/Mail/tests/9137_2.phptnu�[��������--TEST-- Mail: Test for bug #9137, take 2 --FILE-- <?php require_once dirname(__FILE__) . '/../Mail/RFC822.php'; require_once 'PEAR.php'; $addresses = array( array('raw' => '"John Doe" <test@example.com>'), array('raw' => '"John Doe' . chr(92) . '" <test@example.com>'), array('raw' => '"John Doe' . chr(92) . chr(92) . '" <test@example.com>'), array('raw' => '"John Doe' . chr(92) . chr(92) . chr(92) . '" <test@example.com>'), array('raw' => '"John Doe' . chr(92) . chr(92) . chr(92) . chr(92) . '" <test@example.com>'), array('raw' => '"John Doe <test@example.com>'), ); for ($i = 0; $i < count($addresses); $i++) { // construct the address $address = $addresses[$i]['raw']; $parsedAddresses = Mail_RFC822::parseAddressList($address); if (PEAR::isError($parsedAddresses)) { echo $address." :: Failed to validate\n"; } else { echo $address." :: Parsed\n"; } } --EXPECT-- "John Doe" <test@example.com> :: Parsed "John Doe\" <test@example.com> :: Failed to validate "John Doe\\" <test@example.com> :: Parsed "John Doe\\\" <test@example.com> :: Failed to validate "John Doe\\\\" <test@example.com> :: Parsed "John Doe <test@example.com> :: Failed to validate PK�����u])f$! ��! ����test/Mail/tests/rfc822.phptnu�[��������--TEST-- Mail_RFC822: Address Parsing --FILE-- <?php require_once 'Mail/RFC822.php'; $parser = new Mail_RFC822(); /* A simple, bare address. */ $address = 'user@example.com'; print_r($parser->parseAddressList($address, null, true, true)); /* Address groups. */ $address = 'My Group: "Richard" <richard@localhost> (A comment), ted@example.com (Ted Bloggs), Barney;'; print_r($parser->parseAddressList($address, null, true, true)); /* A valid address with spaces in the local part. */ $address = '<"Jon Parise"@php.net>'; print_r($parser->parseAddressList($address, null, true, true)); /* An invalid address with spaces in the local part. */ $address = '<Jon Parise@php.net>'; $result = $parser->parseAddressList($address, null, true, true); if (is_a($result, 'PEAR_Error')) echo $result->getMessage() . "\n"; /* A valid address with an uncommon TLD. */ $address = 'jon@host.longtld'; $result = $parser->parseAddressList($address, null, true, true); if (is_a($result, 'PEAR_Error')) echo $result->getMessage() . "\n"; --EXPECT-- Array ( [0] => stdClass Object ( [personal] => [comment] => Array ( ) [mailbox] => user [host] => example.com ) ) Array ( [0] => stdClass Object ( [groupname] => My Group [addresses] => Array ( [0] => stdClass Object ( [personal] => "Richard" [comment] => Array ( [0] => A comment ) [mailbox] => richard [host] => localhost ) [1] => stdClass Object ( [personal] => [comment] => Array ( [0] => Ted Bloggs ) [mailbox] => ted [host] => example.com ) [2] => stdClass Object ( [personal] => [comment] => Array ( ) [mailbox] => Barney [host] => localhost ) ) ) ) Array ( [0] => stdClass Object ( [personal] => [comment] => Array ( ) [mailbox] => "Jon Parise" [host] => php.net ) ) Validation failed for: <Jon Parise@php.net> PK�����u]x`(������test/Mail/tests/bug17317.phptnu�[��������--TEST-- Mail_RFC822::parseAddressList invalid periods in mail address --FILE-- <?php require "Mail/RFC822.php"; $result[] = Mail_RFC822::parseAddressList('.name@example.com'); $result[] = Mail_RFC822::parseAddressList('name.@example.com'); $result[] = Mail_RFC822::parseAddressList('name..name@example.com'); foreach ($result as $r) { if (is_a($r, 'PEAR_Error')) { echo "OK\n"; } } --EXPECT-- OK OK OK PK�����u]8x��������test/Mail/tests/bug17178.phptnu�[��������--TEST-- Mail_RFC822::parseAddressList does not accept RFC-valid group syntax --FILE-- <?php require "Mail/RFC822.php"; var_dump(Mail_RFC822::parseAddressList("empty-group:;","invalid",false,false)); --EXPECT-- array(0) { } PK�����u]V����(��test/Structures_Graph/tests/AllTests.phpnu�[��������<?php require_once dirname(__FILE__) . '/helper.inc'; class Structures_Graph_AllTests { public static function main() { PHPUnit_TextUI_TestRunner::run(self::suite()); } public static function suite() { $suite = new PHPUnit_Framework_TestSuite('Structures_Graph Tests'); $dir = new GlobIterator(dirname(__FILE__) . '/*Test.php'); $suite->addTestFiles($dir); return $suite; } } PK�����u]W8j#��j#��.��test/Structures_Graph/tests/BasicGraphTest.phpnu�[��������<?php /* vim: set expandtab tabstop=4 shiftwidth=4 foldmethod=marker: */ // +-----------------------------------------------------------------------------+ // | Copyright (c) 2003 Srgio Gonalves Carvalho | // +-----------------------------------------------------------------------------+ // | This file is part of Structures_Graph. | // | | // | Structures_Graph is free software; you can redistribute it and/or modify | // | it under the terms of the GNU Lesser General Public License as published by | // | the Free Software Foundation; either version 2.1 of the License, or | // | (at your option) any later version. | // | | // | Structures_Graph is distributed in the hope that it will be useful, | // | but WITHOUT ANY WARRANTY; without even the implied warranty of | // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | // | GNU Lesser General Public License for more details. | // | | // | You should have received a copy of the GNU Lesser General Public License | // | along with Structures_Graph; if not, write to the Free Software | // | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | // | 02111-1307 USA | // +-----------------------------------------------------------------------------+ // | Author: Srgio Carvalho <sergio.carvalho@portugalmail.com> | // +-----------------------------------------------------------------------------+ // require_once dirname(__FILE__) . '/helper.inc'; /** * @access private */ class BasicGraph extends PHPUnit_Framework_TestCase { var $_graph = null; function test_create_graph() { $this->_graph = new Structures_Graph(); $this->assertTrue(is_a($this->_graph, 'Structures_Graph')); } function test_add_node() { $this->_graph = new Structures_Graph(); $data = 1; $node = new Structures_Graph_Node($data); $this->_graph->addNode($node); $node = new Structures_Graph_Node($data); $this->_graph->addNode($node); $node = new Structures_Graph_Node($data); $this->_graph->addNode($node); } function test_connect_node() { $this->_graph = new Structures_Graph(); $data = 1; $node1 = new Structures_Graph_Node($data); $node2 = new Structures_Graph_Node($data); $this->_graph->addNode($node1); $this->_graph->addNode($node2); $node1->connectTo($node2); $node =& $this->_graph->getNodes(); $node =& $node[0]; $node = $node->getNeighbours(); $node =& $node[0]; /* ZE1 == and === operators fail on $node,$node2 because of the recursion introduced by the _graph field in the Node object. So, we'll use the stupid method for reference testing */ $node = true; $this->assertTrue($node2); $node = false; $this->assertFalse($node2); } function test_data_references() { $this->_graph = new Structures_Graph(); $data = 1; $node = new Structures_Graph_Node(); $node->setData($data); $this->_graph->addNode($node); $data = 2; $dataInNode =& $this->_graph->getNodes(); $dataInNode =& $dataInNode[0]; $dataInNode =& $dataInNode->getData(); $this->assertEquals($data, $dataInNode); } function test_metadata_references() { $this->_graph = new Structures_Graph(); $data = 1; $node = new Structures_Graph_Node(); $node->setMetadata('5', $data); $data = 2; $dataInNode =& $node->getMetadata('5'); $this->assertEquals($data, $dataInNode); } function test_metadata_key_exists() { $this->_graph = new Structures_Graph(); $data = 1; $node = new Structures_Graph_Node(); $node->setMetadata('5', $data); $this->assertTrue($node->metadataKeyExists('5')); $this->assertFalse($node->metadataKeyExists('1')); } function test_directed_degree() { $this->_graph = new Structures_Graph(true); $node = array(); $node[] = new Structures_Graph_Node(); $node[] = new Structures_Graph_Node(); $node[] = new Structures_Graph_Node(); $this->_graph->addNode($node[0]); $this->_graph->addNode($node[1]); $this->_graph->addNode($node[2]); $this->assertEquals(0, $node[0]->inDegree(), 'inDegree test failed for node 0 with 0 arcs'); $this->assertEquals(0, $node[1]->inDegree(), 'inDegree test failed for node 1 with 0 arcs'); $this->assertEquals(0, $node[2]->inDegree(), 'inDegree test failed for node 2 with 0 arcs'); $this->assertEquals(0, $node[0]->outDegree(), 'outDegree test failed for node 0 with 0 arcs'); $this->assertEquals(0, $node[1]->outDegree(), 'outDegree test failed for node 1 with 0 arcs'); $this->assertEquals(0, $node[2]->outDegree(), 'outDegree test failed for node 2 with 0 arcs'); $node[0]->connectTo($node[1]); $this->assertEquals(0, $node[0]->inDegree(), 'inDegree test failed for node 0 with 1 arc'); $this->assertEquals(1, $node[1]->inDegree(), 'inDegree test failed for node 1 with 1 arc'); $this->assertEquals(0, $node[2]->inDegree(), 'inDegree test failed for node 2 with 1 arc'); $this->assertEquals(1, $node[0]->outDegree(), 'outDegree test failed for node 0 with 1 arc'); $this->assertEquals(0, $node[1]->outDegree(), 'outDegree test failed for node 1 with 1 arc'); $this->assertEquals(0, $node[2]->outDegree(), 'outDegree test failed for node 2 with 1 arc'); $node[0]->connectTo($node[2]); $this->assertEquals(0, $node[0]->inDegree(), 'inDegree test failed for node 0 with 2 arcs'); $this->assertEquals(1, $node[1]->inDegree(), 'inDegree test failed for node 1 with 2 arcs'); $this->assertEquals(1, $node[2]->inDegree(), 'inDegree test failed for node 2 with 2 arcs'); $this->assertEquals(2, $node[0]->outDegree(), 'outDegree test failed for node 0 with 2 arcs'); $this->assertEquals(0, $node[1]->outDegree(), 'outDegree test failed for node 1 with 2 arcs'); $this->assertEquals(0, $node[2]->outDegree(), 'outDegree test failed for node 2 with 2 arcs'); } function test_undirected_degree() { $this->_graph = new Structures_Graph(false); $node = array(); $node[] = new Structures_Graph_Node(); $node[] = new Structures_Graph_Node(); $node[] = new Structures_Graph_Node(); $this->_graph->addNode($node[0]); $this->_graph->addNode($node[1]); $this->_graph->addNode($node[2]); $this->assertEquals(0, $node[0]->inDegree(), 'inDegree test failed for node 0 with 0 arcs'); $this->assertEquals(0, $node[1]->inDegree(), 'inDegree test failed for node 1 with 0 arcs'); $this->assertEquals(0, $node[2]->inDegree(), 'inDegree test failed for node 2 with 0 arcs'); $this->assertEquals(0, $node[0]->outDegree(), 'outDegree test failed for node 0 with 0 arcs'); $this->assertEquals(0, $node[1]->outDegree(), 'outDegree test failed for node 1 with 0 arcs'); $this->assertEquals(0, $node[2]->outDegree(), 'outDegree test failed for node 2 with 0 arcs'); $node[0]->connectTo($node[1]); $this->assertEquals(1, $node[0]->inDegree(), 'inDegree test failed for node 0 with 1 arc'); $this->assertEquals(1, $node[1]->inDegree(), 'inDegree test failed for node 1 with 1 arc'); $this->assertEquals(0, $node[2]->inDegree(), 'inDegree test failed for node 2 with 1 arc'); $this->assertEquals(1, $node[0]->outDegree(), 'outDegree test failed for node 0 with 1 arc'); $this->assertEquals(1, $node[1]->outDegree(), 'outDegree test failed for node 1 with 1 arc'); $this->assertEquals(0, $node[2]->outDegree(), 'outDegree test failed for node 2 with 1 arc'); $node[0]->connectTo($node[2]); $this->assertEquals(2, $node[0]->inDegree(), 'inDegree test failed for node 0 with 2 arcs'); $this->assertEquals(1, $node[1]->inDegree(), 'inDegree test failed for node 1 with 2 arcs'); $this->assertEquals(1, $node[2]->inDegree(), 'inDegree test failed for node 2 with 2 arcs'); $this->assertEquals(2, $node[0]->outDegree(), 'outDegree test failed for node 0 with 2 arcs'); $this->assertEquals(1, $node[1]->outDegree(), 'outDegree test failed for node 1 with 2 arcs'); $this->assertEquals(1, $node[2]->outDegree(), 'outDegree test failed for node 2 with 2 arcs'); } } ?> PK�����u]����/��test/Structures_Graph/tests/AcyclicTestTest.phpnu�[��������<?php require_once dirname(__FILE__) . '/helper.inc'; require_once 'Structures/Graph/Manipulator/AcyclicTest.php'; class AcyclicTestTest extends PHPUnit_Framework_TestCase { public function testIsAcyclicFalse() { $graph = new Structures_Graph(); $node1 = new Structures_Graph_Node(); $graph->addNode($node1); $node2 = new Structures_Graph_Node(); $graph->addNode($node2); $node1->connectTo($node2); $node3 = new Structures_Graph_Node(); $graph->addNode($node3); $node2->connectTo($node3); $node3->connectTo($node1); $this->assertFalse( Structures_Graph_Manipulator_AcyclicTest::isAcyclic($graph), 'Graph is cyclic' ); } public function testIsAcyclicTrue() { $graph = new Structures_Graph(); $node1 = new Structures_Graph_Node(); $graph->addNode($node1); $node2 = new Structures_Graph_Node(); $graph->addNode($node2); $node1->connectTo($node2); $node3 = new Structures_Graph_Node(); $graph->addNode($node3); $node2->connectTo($node3); $this->assertTrue( Structures_Graph_Manipulator_AcyclicTest::isAcyclic($graph), 'Graph is acyclic' ); } } ?> PK�����u]lp=i��i��&��test/Structures_Graph/tests/helper.incnu�[��������<?php if ('/opt/alt/php56/usr/share/pear' == '@'.'php_dir'.'@') { // This package hasn't been installed. // Adjust path to ensure includes find files in working directory. set_include_path(dirname(dirname(__FILE__)) . PATH_SEPARATOR . dirname(__FILE__) . PATH_SEPARATOR . get_include_path()); } require_once 'Structures/Graph.php'; PK�����u]6:U��U��5��test/Structures_Graph/tests/TopologicalSorterTest.phpnu�[��������<?php require_once dirname(__FILE__) . '/helper.inc'; require_once 'Structures/Graph/Manipulator/TopologicalSorter.php'; class TopologicalSorterTest extends PHPUnit_Framework_TestCase { public function testSort() { $graph = new Structures_Graph(); $name1 = 'node1'; $node1 = new Structures_Graph_Node(); $node1->setData($name1); $graph->addNode($node1); $name11 = 'node11'; $node11 = new Structures_Graph_Node(); $node11->setData($name11); $graph->addNode($node11); $node1->connectTo($node11); $name12 = 'node12'; $node12 = new Structures_Graph_Node(); $node12->setData($name12); $graph->addNode($node12); $node1->connectTo($node12); $name121 = 'node121'; $node121 = new Structures_Graph_Node(); $node121->setData($name121); $graph->addNode($node121); $node12->connectTo($node121); $name2 = 'node2'; $node2 = new Structures_Graph_Node(); $node2->setData($name2); $graph->addNode($node2); $name21 = 'node21'; $node21 = new Structures_Graph_Node(); $node21->setData($name21); $graph->addNode($node21); $node2->connectTo($node21); $nodes = Structures_Graph_Manipulator_TopologicalSorter::sort($graph); $this->assertCount(2, $nodes[0]); $this->assertEquals('node1', $nodes[0][0]->getData()); $this->assertEquals('node2', $nodes[0][1]->getData()); $this->assertCount(3, $nodes[1]); $this->assertEquals('node11', $nodes[1][0]->getData()); $this->assertEquals('node12', $nodes[1][1]->getData()); $this->assertEquals('node21', $nodes[1][2]->getData()); $this->assertCount(1, $nodes[2]); $this->assertEquals('node121', $nodes[2][0]->getData()); } } ?> PK�����u]Za��a����.filemapnu�[��������a:5:{s:3:"php";a:104:{s:15:"Archive/Tar.php";s:11:"archive_tar";s:18:"Console/Getopt.php";s:14:"console_getopt";s:12:"OS/Guess.php";s:4:"pear";s:27:"PEAR/ChannelFile/Parser.php";s:4:"pear";s:21:"PEAR/Command/Auth.xml";s:4:"pear";s:21:"PEAR/Command/Auth.php";s:4:"pear";s:22:"PEAR/Command/Build.xml";s:4:"pear";s:22:"PEAR/Command/Build.php";s:4:"pear";s:25:"PEAR/Command/Channels.xml";s:4:"pear";s:25:"PEAR/Command/Channels.php";s:4:"pear";s:23:"PEAR/Command/Common.php";s:4:"pear";s:23:"PEAR/Command/Config.xml";s:4:"pear";s:23:"PEAR/Command/Config.php";s:4:"pear";s:24:"PEAR/Command/Install.xml";s:4:"pear";s:24:"PEAR/Command/Install.php";s:4:"pear";s:23:"PEAR/Command/Mirror.xml";s:4:"pear";s:23:"PEAR/Command/Mirror.php";s:4:"pear";s:24:"PEAR/Command/Package.xml";s:4:"pear";s:24:"PEAR/Command/Package.php";s:4:"pear";s:23:"PEAR/Command/Pickle.xml";s:4:"pear";s:23:"PEAR/Command/Pickle.php";s:4:"pear";s:25:"PEAR/Command/Registry.xml";s:4:"pear";s:25:"PEAR/Command/Registry.php";s:4:"pear";s:23:"PEAR/Command/Remote.xml";s:4:"pear";s:23:"PEAR/Command/Remote.php";s:4:"pear";s:21:"PEAR/Command/Test.xml";s:4:"pear";s:21:"PEAR/Command/Test.php";s:4:"pear";s:27:"PEAR/Downloader/Package.php";s:4:"pear";s:21:"PEAR/Frontend/CLI.php";s:4:"pear";s:30:"PEAR/Installer/Role/Common.php";s:4:"pear";s:27:"PEAR/Installer/Role/Cfg.xml";s:4:"pear";s:27:"PEAR/Installer/Role/Cfg.php";s:4:"pear";s:28:"PEAR/Installer/Role/Data.xml";s:4:"pear";s:28:"PEAR/Installer/Role/Data.php";s:4:"pear";s:27:"PEAR/Installer/Role/Doc.xml";s:4:"pear";s:27:"PEAR/Installer/Role/Doc.php";s:4:"pear";s:27:"PEAR/Installer/Role/Ext.xml";s:4:"pear";s:27:"PEAR/Installer/Role/Ext.php";s:4:"pear";s:27:"PEAR/Installer/Role/Man.xml";s:4:"pear";s:27:"PEAR/Installer/Role/Man.php";s:4:"pear";s:27:"PEAR/Installer/Role/Php.xml";s:4:"pear";s:27:"PEAR/Installer/Role/Php.php";s:4:"pear";s:30:"PEAR/Installer/Role/Script.xml";s:4:"pear";s:30:"PEAR/Installer/Role/Script.php";s:4:"pear";s:27:"PEAR/Installer/Role/Src.xml";s:4:"pear";s:27:"PEAR/Installer/Role/Src.php";s:4:"pear";s:28:"PEAR/Installer/Role/Test.xml";s:4:"pear";s:28:"PEAR/Installer/Role/Test.php";s:4:"pear";s:27:"PEAR/Installer/Role/Www.xml";s:4:"pear";s:27:"PEAR/Installer/Role/Www.php";s:4:"pear";s:23:"PEAR/Installer/Role.php";s:4:"pear";s:33:"PEAR/PackageFile/Generator/v1.php";s:4:"pear";s:33:"PEAR/PackageFile/Generator/v2.php";s:4:"pear";s:30:"PEAR/PackageFile/Parser/v1.php";s:4:"pear";s:30:"PEAR/PackageFile/Parser/v2.php";s:4:"pear";s:26:"PEAR/PackageFile/v2/rw.php";s:4:"pear";s:33:"PEAR/PackageFile/v2/Validator.php";s:4:"pear";s:23:"PEAR/PackageFile/v1.php";s:4:"pear";s:23:"PEAR/PackageFile/v2.php";s:4:"pear";s:16:"PEAR/REST/10.php";s:4:"pear";s:16:"PEAR/REST/11.php";s:4:"pear";s:16:"PEAR/REST/13.php";s:4:"pear";s:34:"PEAR/Task/Postinstallscript/rw.php";s:4:"pear";s:24:"PEAR/Task/Replace/rw.php";s:4:"pear";s:24:"PEAR/Task/Unixeol/rw.php";s:4:"pear";s:27:"PEAR/Task/Windowseol/rw.php";s:4:"pear";s:20:"PEAR/Task/Common.php";s:4:"pear";s:31:"PEAR/Task/Postinstallscript.php";s:4:"pear";s:21:"PEAR/Task/Replace.php";s:4:"pear";s:21:"PEAR/Task/Unixeol.php";s:4:"pear";s:24:"PEAR/Task/Windowseol.php";s:4:"pear";s:23:"PEAR/Validator/PECL.php";s:4:"pear";s:16:"PEAR/Builder.php";s:4:"pear";s:20:"PEAR/ChannelFile.php";s:4:"pear";s:16:"PEAR/Command.php";s:4:"pear";s:15:"PEAR/Common.php";s:4:"pear";s:15:"PEAR/Config.php";s:4:"pear";s:21:"PEAR/DependencyDB.php";s:4:"pear";s:20:"PEAR/Dependency2.php";s:4:"pear";s:19:"PEAR/Downloader.php";s:4:"pear";s:19:"PEAR/ErrorStack.php";s:4:"pear";s:18:"PEAR/Exception.php";s:4:"pear";s:17:"PEAR/Frontend.php";s:4:"pear";s:18:"PEAR/Installer.php";s:4:"pear";s:20:"PEAR/PackageFile.php";s:4:"pear";s:17:"PEAR/Packager.php";s:4:"pear";s:14:"PEAR/Proxy.php";s:4:"pear";s:17:"PEAR/Registry.php";s:4:"pear";s:13:"PEAR/REST.php";s:4:"pear";s:16:"PEAR/RunTest.php";s:4:"pear";s:17:"PEAR/Validate.php";s:4:"pear";s:18:"PEAR/XMLParser.php";s:4:"pear";s:19:"scripts/pearcmd.php";s:4:"pear";s:19:"scripts/peclcmd.php";s:4:"pear";s:8:"PEAR.php";s:4:"pear";s:10:"System.php";s:4:"pear";s:44:"Structures/Graph/Manipulator/AcyclicTest.php";s:16:"structures_graph";s:50:"Structures/Graph/Manipulator/TopologicalSorter.php";s:16:"structures_graph";s:25:"Structures/Graph/Node.php";s:16:"structures_graph";s:20:"Structures/Graph.php";s:16:"structures_graph";s:11:"XML/RPC.php";s:7:"xml_rpc";s:16:"XML/RPC/Dump.php";s:7:"xml_rpc";s:18:"XML/RPC/Server.php";s:7:"xml_rpc";s:12:"XML/Util.php";s:8:"xml_util";}s:3:"doc";a:8:{s:32:"archive_tar/docs/Archive_Tar.txt";s:11:"archive_tar";s:12:"pear/LICENSE";s:4:"pear";s:12:"pear/INSTALL";s:4:"pear";s:15:"pear/README.rst";s:4:"pear";s:69:"structures_graph/docs/tutorials/Structures_Graph/Structures_Graph.pkg";s:16:"structures_graph";s:24:"structures_graph/LICENSE";s:16:"structures_graph";s:29:"xml_util/examples/example.php";s:8:"xml_util";s:30:"xml_util/examples/example2.php";s:8:"xml_util";}s:4:"test";a:40:{s:36:"console_getopt/tests/001-getopt.phpt";s:14:"console_getopt";s:34:"console_getopt/tests/bug10557.phpt";s:14:"console_getopt";s:34:"console_getopt/tests/bug11068.phpt";s:14:"console_getopt";s:34:"console_getopt/tests/bug13140.phpt";s:14:"console_getopt";s:35:"structures_graph/tests/AllTests.php";s:16:"structures_graph";s:41:"structures_graph/tests/BasicGraphTest.php";s:16:"structures_graph";s:48:"structures_graph/tests/TopologicalSorterTest.php";s:16:"structures_graph";s:42:"structures_graph/tests/AcyclicTestTest.php";s:16:"structures_graph";s:33:"structures_graph/tests/helper.inc";s:16:"structures_graph";s:32:"xml_rpc/tests/actual-request.php";s:7:"xml_rpc";s:24:"xml_rpc/tests/allgot.inc";s:7:"xml_rpc";s:36:"xml_rpc/tests/empty-value-struct.php";s:7:"xml_rpc";s:29:"xml_rpc/tests/empty-value.php";s:7:"xml_rpc";s:24:"xml_rpc/tests/encode.php";s:7:"xml_rpc";s:29:"xml_rpc/tests/extra-lines.php";s:7:"xml_rpc";s:27:"xml_rpc/tests/protoport.php";s:7:"xml_rpc";s:27:"xml_rpc/tests/test_Dump.php";s:7:"xml_rpc";s:23:"xml_rpc/tests/types.php";s:7:"xml_rpc";s:36:"xml_util/tests/AbstractUnitTests.php";s:8:"xml_util";s:34:"xml_util/tests/ApiVersionTests.php";s:8:"xml_util";s:42:"xml_util/tests/AttributesToStringTests.php";s:8:"xml_util";s:41:"xml_util/tests/CollapseEmptyTagsTests.php";s:8:"xml_util";s:42:"xml_util/tests/CreateCDataSectionTests.php";s:8:"xml_util";s:37:"xml_util/tests/CreateCommentTests.php";s:8:"xml_util";s:40:"xml_util/tests/CreateEndElementTests.php";s:8:"xml_util";s:42:"xml_util/tests/CreateStartElementTests.php";s:8:"xml_util";s:33:"xml_util/tests/CreateTagTests.php";s:8:"xml_util";s:42:"xml_util/tests/CreateTagFromArrayTests.php";s:8:"xml_util";s:45:"xml_util/tests/GetDocTypeDeclarationTests.php";s:8:"xml_util";s:41:"xml_util/tests/GetXmlDeclarationTests.php";s:8:"xml_util";s:35:"xml_util/tests/IsValidNameTests.php";s:8:"xml_util";s:34:"xml_util/tests/RaiseErrorTests.php";s:8:"xml_util";s:39:"xml_util/tests/ReplaceEntitiesTests.php";s:8:"xml_util";s:39:"xml_util/tests/ReverseEntitiesTests.php";s:8:"xml_util";s:42:"xml_util/tests/SplitQualifiedNameTests.php";s:8:"xml_util";s:31:"xml_util/tests/Bug4950Tests.php";s:8:"xml_util";s:31:"xml_util/tests/Bug5392Tests.php";s:8:"xml_util";s:32:"xml_util/tests/Bug18343Tests.php";s:8:"xml_util";s:32:"xml_util/tests/Bug21177Tests.php";s:8:"xml_util";s:32:"xml_util/tests/Bug21184Tests.php";s:8:"xml_util";}s:6:"script";a:3:{s:15:"scripts/pear.sh";s:4:"pear";s:18:"scripts/peardev.sh";s:4:"pear";s:15:"scripts/pecl.sh";s:4:"pear";}s:4:"data";a:2:{s:16:"pear/package.dtd";s:4:"pear";s:18:"pear/template.spec";s:4:"pear";}}PK�����u]Sh��h����File/MARC/List.phpnu�[��������<?php /* vim: set expandtab shiftwidth=4 tabstop=4 softtabstop=4 foldmethod=marker: */ /** * Parser for MARC records * * This package is based on the PHP MARC package, originally called "php-marc", * that is part of the Emilda Project (http://www.emilda.org). Christoffer * Landtman generously agreed to make the "php-marc" code available under the * GNU LGPL so it could be used as the basis of this PEAR package. * * PHP version 5 * * LICENSE: This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * @category File_Formats * @package File_MARC * @author Christoffer Landtman <landtman@realnode.com> * @author Dan Scott <dscott@laurentian.ca> * @copyright 2003-2008 Oy Realnode Ab, Dan Scott * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 * @version CVS: $Id$ * @link http://pear.php.net/package/File_MARC */ // {{{ class File_MARC_List extends SplDoublyLinkedList /** * The File_MARC_List class extends the SplDoublyLinkedList class * to override the key() method in a meaningful way for foreach() iterators. * * For the list of {@link File_MARC_Field} objects in a {@link File_MARC_Record} * object, the key() method returns the tag name of the field. * * For the list of {@link File_MARC_Subfield} objects in a {@link * File_MARC_Data_Field} object, the key() method returns the code of * the subfield. * * <code> * // Iterate through the fields in a record with key=>value iteration * foreach ($record->getFields() as $tag=>$value) { * print "$tag: "; * if ($value instanceof File_MARC_Control_Field) { * print $value->getData(); * } * else { * // Iterate through the subfields in this data field * foreach ($value->getSubfields() as $code=>$subdata) { * print "_$code"; * } * } * print "\n"; * } * </code> * * @category File_Formats * @package File_MARC * @author Dan Scott <dscott@laurentian.ca> * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 * @link http://pear.php.net/package/File_MARC */ class File_MARC_List extends SplDoublyLinkedList { // {{{ properties /** * Position of the subfield * @var int */ protected $position; // }}} // {{{ key() /** * Returns the tag for a {@link File_MARC_Field} object, or the code * for a {@link File_MARC_Subfield} object. * * This method enables you to use a foreach iterator to retrieve * the tag or code as the key for the iterator. * * @return string returns the tag or code */ function key() { if ($this->current() instanceof File_MARC_Field) { return $this->current()->getTag(); } elseif ($this->current() instanceof File_MARC_Subfield) { return $this->current()->getCode(); } return false; } // }}} // {{{ function insertNode() /** * Inserts a node into the linked list, based on a reference node that * already exists in the list. * * @param mixed $new_node New node to add to the list * @param mixed $existing_node Reference position node * @param bool $before Insert new node before or after the existing node * * @return bool Success or failure **/ public function insertNode($new_node, $existing_node, $before = false) { $pos = 0; $exist_pos = $existing_node->getPosition(); $this->rewind(); // Now add the node according to the requested mode switch ($before) { case true: $this->add($exist_pos, $new_node); break; // after case false: if ($this->offsetExists($exist_pos + 1)) { $this->add($exist_pos + 1, $new_node); } else { $this->appendNode($new_node); return true; } break; } // Fix positions $this->rewind(); while ($n = $this->current()) { $n->setPosition($pos); $this->next(); $pos++; } return true; } // }}} // {{{ function appendNode() /** * Adds a node onto the linked list. * * @param mixed $new_node New node to add to the list * * @return void **/ public function appendNode($new_node) { $pos = $this->count(); $new_node->setPosition($pos); $this->push($new_node); } // }}} // {{{ function prependNode() /** * Adds a node to the start of the linked list. * * @param mixed $new_node New node to add to the list * * @return void **/ public function prependNode($new_node) { $this->insertNode($new_node, $this->bottom(), true); } // }}} // {{{ function deleteNode() /** * Deletes a node from the linked list. * * @param mixed $node Node to delete from the list * * @return void **/ public function deleteNode($node) { $target_pos = $node->getPosition(); $this->rewind(); $pos = 0; // Omit target node and adjust pos of remainder $done = false; try { while ($n = $this->current()) { if ($pos == $target_pos && !$done) { $done = true; $this->next(); $this->offsetUnset($pos); } elseif ($pos >= $target_pos) { $n->setPosition($pos); $pos++; $this->next(); } else { $pos++; $this->next(); } } } catch (Exception $e) { // no-op - shift() throws an exception, sigh } } // }}} // {{{ setPosition() /** * Sets position of the subfield * * @param string $pos new position of the subfield * * @return void */ function setPosition($pos) { $this->position = $pos; } // }}} // {{{ getPosition() /** * Return position of the subfield * * @return int data */ function getPosition() { return $this->position; } // }}} } // }}} PK�����u]+������File/MARC/Field.phpnu�[��������<?php /* vim: set expandtab shiftwidth=4 tabstop=4 softtabstop=4 foldmethod=marker: */ /** * Parser for MARC records * * This package is based on the PHP MARC package, originally called "php-marc", * that is part of the Emilda Project (http://www.emilda.org). Christoffer * Landtman generously agreed to make the "php-marc" code available under the * GNU LGPL so it could be used as the basis of this PEAR package. * * PHP version 5 * * LICENSE: This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * @category File_Formats * @package File_MARC * @author Christoffer Landtman <landtman@realnode.com> * @author Dan Scott <dscott@laurentian.ca> * @copyright 2003-2008 Oy Realnode Ab, Dan Scott * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 * @version CVS: $Id$ * @link http://pear.php.net/package/File_MARC */ require_once 'File/MARC/List.php'; // {{{ class File_MARC_Field extends File_MARC_List /** * The File_MARC_Field class is expected to be extended to reflect the * requirements of control and data fields. * * Every MARC field contains a tag name. * * @category File_Formats * @package File_MARC * @author Christoffer Landtman <landtman@realnode.com> * @author Dan Scott <dscott@laurentian.ca> * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 * @link http://pear.php.net/package/File_MARC */ class File_MARC_Field extends File_MARC_List { // {{{ properties /** * The tag name of the Field * @var string */ protected $tag; // }}} // {{{ Constructor: function __construct() /** * File_MARC_Field constructor * * Create a new {@link File_MARC_Field} object from passed arguments. We * define placeholders for the arguments required by child classes. * * @param string $tag tag * @param string $subfields placeholder for subfields or control data * @param string $ind1 placeholder for first indicator * @param string $ind2 placeholder for second indicator */ function __construct($tag, $subfields = null, $ind1 = null, $ind2 = null) { $this->tag = $tag; // Check if valid tag if (!preg_match("/^[0-9A-Za-z]{3}$/", $tag)) { $errorMessage = File_MARC_Exception::formatError(File_MARC_Exception::$messages[File_MARC_Exception::ERROR_INVALID_TAG], array("tag" => $tag)); throw new File_MARC_Exception($errorMessage, File_MARC_Exception::ERROR_INVALID_TAG); } } // }}} // {{{ Destructor: function __destruct() /** * Destroys the data field */ function __destruct() { $this->tag = null; } // }}} // {{{ getTag() /** * Returns the tag for this {@link File_MARC_Field} object * * @return string returns the tag number of the field */ function getTag() { return (string)$this->tag; } // }}} // {{{ setTag() /** * Sets the tag for this {@link File_MARC_Field} object * * @param string $tag new value for the tag * * @return string returns the tag number of the field */ function setTag($tag) { $this->tag = $tag; return $this->getTag(); } // }}} // {{{ isEmpty() /** * Is empty * * Checks if the field is empty. * * @return bool Returns true if the field is empty, otherwise false */ function isEmpty() { if ($this->getTag()) { return false; } // It is empty return true; } // }}} // {{{ isControlField() /** * Is control field * * Checks if the field is a control field. * * @return bool Returns true if the field is a control field, otherwise false */ function isControlField() { if (get_class($this) == 'File_MARC_Control_Field') { return true; } return false; } // }}} // {{{ isDataField() /** * Is data field * * Checks if the field is a data field. * * @return bool Returns true if the field is a data field, otherwise false */ function isDataField() { if (get_class($this) == 'File_MARC_Data_Field') { return true; } return false; } // }}} /** * ========== OUTPUT METHODS ========== */ // {{{ __toString() /** * Return Field formatted * * Return Field as a formatted string. * * @return string Formatted output of Field */ function __toString() { return (string)$this->getTag(); } // }}} // {{{ toRaw() /** * Return field in raw MARC format (stub) * * Return the field formatted in raw MARC for saving into MARC files. This * stub method is extended by the child classes. * * @return bool Raw MARC */ function toRaw() { return false; } // }}} // {{{ formatField() /** * Pretty print a MARC_Field object without tags, indicators, etc. * * @param array $exclude Subfields to exclude from formatted output * * @return string Returns the formatted field data */ function formatField($exclude = array('2')) { if ($this->isControlField()) { return $this->getData(); } else { $out = ''; foreach ($this->getSubfields() as $subfield) { if (substr($this->getTag(), 0, 1) == '6' and (in_array($subfield->getCode(), array('v','x','y','z')))) { $out .= ' -- ' . $subfield->getData(); } elseif (!in_array($subfield->getCode(), $exclude)) { $out .= ' ' . $subfield->getData(); } } return trim($out); } } // }}} } // }}} PK�����u]Ɍ59�9���File/MARC/Lint.phpnu�[��������<?php /* vim: set expandtab shiftwidth=4 tabstop=4 softtabstop=4 foldmethod=marker: */ /** * Lint for MARC records * * This module is adapted from the MARC::Lint CPAN module for Perl, maintained by * Bryan Baldus <eijabb@cpan.org> and available at http://search.cpan.org/~eijabb/ * * Current MARC::Lint version used as basis for this module: 1.52 * * PHP version 5 * * LICENSE: This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * @category File_Formats * @package File_MARC * @author Demian Katz <demian.katz@villanova.edu> * @author Dan Scott <dscott@laurentian.ca> * @copyright 2003-2019 Oy Realnode Ab, Dan Scott * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 * @version CVS: $Id: Record.php 308146 2011-02-08 20:36:20Z dbs $ * @link http://pear.php.net/package/File_MARC */ require_once 'File/MARC/Lint/CodeData.php'; require_once 'Validate/ISPN.php'; // {{{ class File_MARC_Lint /** * Class for testing validity of MARC records against MARC21 standard. * * @category File_Formats * @package File_MARC * @author Demian Katz <demian.katz@villanova.edu> * @author Dan Scott <dscott@laurentian.ca> * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 * @link http://pear.php.net/package/File_MARC */ class File_MARC_Lint { // {{{ properties /** * Rules used for testing records * @var array */ protected $rules; /** * A File_MARC_Lint_CodeData object for validating codes * @var File_MARC_Lint_CodeData */ protected $data; /** * A Validate_ISPN object for validating ISBN numbers * @var Validate_ISPN */ protected $validateIspn; /** * Warnings generated during analysis * @var array */ protected $warnings = array(); // }}} // {{{ Constructor: function __construct() /** * Start function * * Set up rules for testing MARC records. * * @return true */ public function __construct() { $this->parseRules(); $this->data = new File_MARC_Lint_CodeData(); $this->validateIspn = new Validate_ISPN(); } // }}} // {{{ getWarnings() /** * Check the provided MARC record and return an array of warning messages. * * @param File_MARC_Record $marc Record to check * * @return array */ public function checkRecord($marc) { // Reset warnings: $this->warnings = array(); // Fail if we didn't get a valid object: if (!is_a($marc, 'File_MARC_Record')) { $this->warn('Must pass a File_MARC_Record object to checkRecord'); } else { $this->checkDuplicate1xx($marc); $this->checkMissing245($marc); $this->standardFieldChecks($marc); } return $this->warnings; } // }}} // {{{ warn() /** * Add a warning. * * @param string $warning Warning to add * * @return void */ protected function warn($warning) { $this->warnings[] = $warning; } // }}} // {{{ checkDuplicate1xx() /** * Check for multiple 1xx fields. * * @param File_MARC_Record $marc Record to check * * @return void */ protected function checkDuplicate1xx($marc) { $result = $marc->getFields('1[0-9][0-9]', true); $count = count($result); if ($count > 1) { $this->warn( "1XX: Only one 1XX tag is allowed, but I found $count of them." ); } } // }}} // {{{ checkMissing245() /** * Check for missing 245 field. * * @param File_MARC_Record $marc Record to check * * @return void */ protected function checkMissing245($marc) { $result = $marc->getFields('245'); if (count($result) == 0) { $this->warn('245: No 245 tag.'); } } // }}} // {{{ standardFieldChecks() /** * Check all fields against the standard rules encoded in the class. * * @param File_MARC_Record $marc Record to check * * @return void */ protected function standardFieldChecks($marc) { $fieldsSeen = array(); foreach ($marc->getFields() as $current) { $tagNo = $current->getTag(); // if 880 field, inherit rules from tagno in subfield _6 if ($tagNo == 880) { if ($sub6 = $current->getSubfield(6)) { $tagNo = substr($sub6->getData(), 0, 3); $tagrules = isset($this->rules[$tagNo]) ? $this->rules[$tagNo] : null; // 880 is repeatable, but its linked field may not be if (isset($tagrules['repeatable']) && $tagrules['repeatable'] == 'NR' && isset($fieldsSeen['880.'.$tagNo]) ) { $this->warn("$tagNo: Field is not repeatable."); } $fieldsSeen['880.'.$tagNo] = isset($fieldsSeen['880.'.$tagNo]) ? $fieldsSeen['880.'.$tagNo] + 1 : 1; } else { $this->warn("880: No subfield 6."); $tagRules = null; } } else { // Default case -- not an 880 field: $tagrules = isset($this->rules[$tagNo]) ? $this->rules[$tagNo] : null; if (isset($tagrules['repeatable']) && $tagrules['repeatable'] == 'NR' && isset($fieldsSeen[$tagNo]) ) { $this->warn("$tagNo: Field is not repeatable."); } $fieldsSeen[$tagNo] = isset($fieldsSeen[$tagNo]) ? $fieldsSeen[$tagNo] + 1 : 1; } // Treat data fields differently from control fields: if (intval(ltrim($tagNo, '0')) >= 10) { if (!empty($tagrules)) { $this->checkIndicators($tagNo, $current, $tagrules); $this->checkSubfields($tagNo, $current, $tagrules); } } else { // Control field: if (strstr($current->toRaw(), chr(hexdec('1F')))) { $this->warn( "$tagNo: Subfields are not allowed in fields lower than 010" ); } } // Check to see if a checkxxx() function exists, and call it on the // field if it does $method = 'check' . $tagNo; if (method_exists($this, $method)) { $this->$method($current); } } } // }}} // {{{ checkIndicators() /** * Check the indicators for the provided field. * * @param string $tagNo Tag number being checked * @param File_MARC_Field $field Field to check * @param array $rules Rules to use for checking * * @return void */ protected function checkIndicators($tagNo, $field, $rules) { for ($i = 1; $i <= 2; $i++) { $ind = $field->getIndicator($i); if ($ind === false || $ind == ' ') { $ind = 'b'; } if (!strstr($rules['ind' . $i]['values'], $ind)) { // Make indicator blank value human-readable for message: if ($ind == 'b') { $ind = 'blank'; } $this->warn( "$tagNo: Indicator $i must be " . $rules['ind' . $i]['hr_values'] . " but it's \"$ind\"" ); } } } // }}} // {{{ checkSubfields() /** * Check the subfields for the provided field. * * @param string $tagNo Tag number being checked * @param File_MARC_Field $field Field to check * @param array $rules Rules to use for checking * * @return void */ protected function checkSubfields($tagNo, $field, $rules) { $subSeen = array(); foreach ($field->getSubfields() as $current) { $code = $current->getCode(); $data = $current->getData(); $subrules = isset($rules['sub' . $code]) ? $rules['sub' . $code] : null; if (empty($subrules)) { $this->warn("$tagNo: Subfield _$code is not allowed."); } elseif ($subrules['repeatable'] == 'NR' && isset($subSeen[$code])) { $this->warn("$tagNo: Subfield _$code is not repeatable."); } if (preg_match('/\r|\t|\n/', $data)) { $this->warn( "$tagNo: Subfield _$code has an invalid control character" ); } $subSeen[$code] = isset($subSeen[$code]) ? $subSeen[$code]++ : 1; } } // }}} // {{{ check020() /** * Looks at 020$a and reports errors if the check digit is wrong. * Looks at 020$z and validates number if hyphens are present. * * @param File_MARC_Field $field Field to check * * @return void */ protected function check020($field) { foreach ($field->getSubfields() as $current) { $data = $current->getData(); // remove any hyphens $isbn = str_replace('-', '', $data); // remove nondigits $isbn = preg_replace('/^\D*(\d{9,12}[X\d])\b.*$/', '$1', $isbn); if ($current->getCode() == 'a') { if ((substr($data, 0, strlen($isbn)) != $isbn)) { $this->warn("020: Subfield a may have invalid characters."); } // report error if no space precedes a qualifier in subfield a if (preg_match('/\(/', $data) && !preg_match('/[X0-9] \(/', $data)) { $this->warn( "020: Subfield a qualifier must be preceded by space, $data." ); } // report error if unable to find 10-13 digit string of digits in // subfield 'a' if (!preg_match('/(?:^\d{10}$)|(?:^\d{13}$)|(?:^\d{9}X$)/', $isbn)) { $this->warn( "020: Subfield a has the wrong number of digits, $data." ); } else { if (strlen($isbn) == 10) { if (!$this->validateIspn->isbn10($isbn)) { $this->warn("020: Subfield a has bad checksum, $data."); } } else if (strlen($isbn) == 13) { if (!$this->validateIspn->isbn13($isbn)) { $this->warn( "020: Subfield a has bad checksum (13 digit), $data." ); } } } } else if ($current->getCode() == 'z') { // look for valid isbn in 020$z if (preg_match('/^ISBN/', $data) || preg_match('/^\d*\-\d+/', $data) ) { // ################################################## // ## Turned on for now--Comment to unimplement #### // ################################################## if ((strlen($isbn) == 10) && ($this->validateIspn->isbn10($isbn) == 1) ) { $this->warn("020: Subfield z is numerically valid."); } } } } } // }}} // {{{ check041() /** * Warns if subfields are not evenly divisible by 3 unless second indicator is 7 * (future implementation would ensure that each subfield is exactly 3 characters * unless ind2 is 7--since subfields are now repeatable. This is not implemented * here due to the large number of records needing to be corrected.). Validates * against the MARC Code List for Languages (<http://www.loc.gov/marc/>). * * @param File_MARC_Field $field Field to check * * @return void */ protected function check041($field) { // warn if length of each subfield is not divisible by 3 unless ind2 is 7 if ($field->getIndicator(2) != '7') { foreach ($field->getSubfields() as $sub) { $code = $sub->getCode(); $data = $sub->getData(); if (strlen($data) % 3 != 0) { $this->warn( "041: Subfield _$code must be evenly divisible by 3 or " . "exactly three characters if ind2 is not 7, ($data)." ); } else { for ($i = 0; $i < strlen($data); $i += 3) { $chk = substr($data, $i, 3); if (!in_array($chk, $this->data->languageCodes)) { $obs = $this->data->obsoleteLanguageCodes; if (in_array($chk, $obs)) { $this->warn( "041: Subfield _$code, $data, may be obsolete." ); } else { $this->warn( "041: Subfield _$code, $data ($chk)," . " is not valid." ); } } } } } } } // }}} // {{{ check043() /** * Warns if each subfield a is not exactly 7 characters. Validates each code * against the MARC code list for Geographic Areas (<http://www.loc.gov/marc/>). * * @param File_MARC_Field $field Field to check * * @return void */ protected function check043($field) { foreach ($field->getSubfields('a') as $suba) { // warn if length of subfield a is not exactly 7 $data = $suba->getData(); if (strlen($data) != 7) { $this->warn("043: Subfield _a must be exactly 7 characters, $data"); } else if (!in_array($data, $this->data->geogAreaCodes)) { if (in_array($data, $this->data->obsoleteGeogAreaCodes)) { $this->warn("043: Subfield _a, $data, may be obsolete."); } else { $this->warn("043: Subfield _a, $data, is not valid."); } } } } // }}} // {{{ check245() /** * -Makes sure $a exists (and is first subfield). * -Warns if last character of field is not a period * --Follows LCRI 1.0C, Nov. 2003 rather than MARC21 rule * -Verifies that $c is preceded by / (space-/) * -Verifies that initials in $c are not spaced * -Verifies that $b is preceded by :;= (space-colon, space-semicolon, * space-equals) * -Verifies that $h is not preceded by space unless it is dash-space * -Verifies that data of $h is enclosed in square brackets * -Verifies that $n is preceded by . (period) * --As part of that, looks for no-space period, or dash-space-period * (for replaced elipses) * -Verifies that $p is preceded by , (no-space-comma) when following $n and * . (period) when following other subfields. * -Performs rudimentary article check of 245 2nd indicator vs. 1st word of * 245$a (for manual verification). * * Article checking is done by internal checkArticle method, which should work * for 130, 240, 245, 440, 630, 730, and 830. * * @param File_MARC_Field $field Field to check * * @return void */ protected function check245($field) { if (count($field->getSubfields('a')) == 0) { $this->warn("245: Must have a subfield _a."); } // Convert subfields to array and set flags indicating which subfields are // present while we're at it. $tmp = $field->getSubfields(); $hasSubfields = $subfields = array(); foreach ($tmp as $current) { $subfields[] = $current; $hasSubfields[$current->getCode()] = true; } // 245 must end in period (may want to make this less restrictive by allowing // trailing spaces) // do 2 checks--for final punctuation (MARC21 rule), and for period // (LCRI 1.0C, Nov. 2003) $lastChar = substr($subfields[count($subfields)-1]->getData(), -1); if (!in_array($lastChar, array('.', '?', '!'))) { $this->warn("245: Must end with . (period)."); } else if ($lastChar != '.') { $this->warn( "245: MARC21 allows ? or ! as final punctuation but LCRI 1.0C, Nov." . " 2003 (LCPS 1.7.1 for RDA records), requires period." ); } // Check for first subfield // subfield a should be first subfield (or 2nd if subfield '6' is present) if (isset($hasSubfields['6'])) { // make sure there are at least 2 subfields if (count($subfields) < 2) { $this->warn("245: May have too few subfields."); } else { $first = $subfields[0]->getCode(); $second = $subfields[1]->getCode(); if ($first != '6') { $this->warn("245: First subfield must be _6, but it is $first"); } if ($second != 'a') { $this->warn( "245: First subfield after subfield _6 must be _a, but it " . "is _$second" ); } } } else { // 1st subfield must be 'a' $first = $subfields[0]->getCode(); if ($first != 'a') { $this->warn("245: First subfield must be _a, but it is _$first"); } } // End check for first subfield // subfield c, if present, must be preceded by / // also look for space between initials if (isset($hasSubfields['c'])) { foreach ($subfields as $i => $current) { // 245 subfield c must be preceded by / (space-/) if ($current->getCode() == 'c') { if ($i > 0 && !preg_match('/\s\/$/', $subfields[$i-1]->getData()) ) { $this->warn("245: Subfield _c must be preceded by /"); } // 245 subfield c initials should not have space if (preg_match('/\b\w\. \b\w\./', $current->getData())) { $this->warn( "245: Subfield _c initials should not have a space." ); } break; } } } // each subfield b, if present, should be preceded by :;= (colon, semicolon, // or equals sign) if (isset($hasSubfields['b'])) { // 245 subfield b should be preceded by space-:;= (colon, semicolon, or // equals sign) foreach ($subfields as $i => $current) { if ($current->getCode() == 'b' && $i > 0 && !preg_match('/ [:;=]$/', $subfields[$i-1]->getData()) ) { $this->warn( "245: Subfield _b should be preceded by space-colon, " . "space-semicolon, or space-equals sign." ); } } } // each subfield h, if present, should be preceded by non-space if (isset($hasSubfields['h'])) { // 245 subfield h should not be preceded by space foreach ($subfields as $i => $current) { // report error if subfield 'h' is preceded by space (unless // dash-space) if ($current->getCode() == 'h') { $prev = $subfields[$i-1]->getData(); if ($i > 0 && !preg_match('/(\S$)|(\-\- $)/', $prev)) { $this->warn( "245: Subfield _h should not be preceded by space." ); } // report error if subfield 'h' does not start with open square // bracket with a matching close bracket; could have check // against list of valid values here $data = $current->getData(); if (!preg_match('/^\[\w*\s*\w*\]/', $data)) { $this->warn( "245: Subfield _h must have matching square brackets," . " $data." ); } } } } // each subfield n, if present, must be preceded by . (period) if (isset($hasSubfields['n'])) { // 245 subfield n must be preceded by . (period) foreach ($subfields as $i => $current) { // report error if subfield 'n' is not preceded by non-space-period // or dash-space-period if ($current->getCode() == 'n' && $i > 0) { $prev = $subfields[$i-1]->getData(); if (!preg_match('/(\S\.$)|(\-\- \.$)/', $prev)) { $this->warn( "245: Subfield _n must be preceded by . (period)." ); } } } } // each subfield p, if present, must be preceded by a , (no-space-comma) // if it follows subfield n, or by . (no-space-period or // dash-space-period) following other subfields if (isset($hasSubfields['p'])) { // 245 subfield p must be preceded by . (period) or , (comma) foreach ($subfields as $i => $current) { if ($current->getCode() == 'p' && $i > 0) { $prev = $subfields[$i-1]; // case for subfield 'n' being field before this one (allows // dash-space-comma) if ($prev->getCode() == 'n' && !preg_match('/(\S,$)|(\-\- ,$)/', $prev->getData()) ) { $this->warn( "245: Subfield _p must be preceded by , (comma) " . "when it follows subfield _n." ); } else if ($prev->getCode() != 'n' && !preg_match('/(\S\.$)|(\-\- \.$)/', $prev->getData()) ) { $this->warn( "245: Subfield _p must be preceded by . (period)" . " when it follows a subfield other than _n." ); } } } } // check for invalid 2nd indicator $this->checkArticle($field); } // }}} // {{{ checkArticle() /** * Check of articles is based on code from Ian Hamilton. This version is more * limited in that it focuses on English, Spanish, French, Italian and German * articles. Certain possible articles have been removed if they are valid * English non-articles. This version also disregards 008_language/041 codes * and just uses the list of articles to provide warnings/suggestions. * * source for articles = <http://www.loc.gov/marc/bibliographic/bdapp-e.html> * * Should work with fields 130, 240, 245, 440, 630, 730, and 830. Reports error * if another field is passed in. * * @param File_MARC_Field $field Field to check * * @return void */ protected function checkArticle($field) { // add articles here as needed // Some omitted due to similarity with valid words (e.g. the German 'die'). static $article = array( 'a' => 'eng glg hun por', 'an' => 'eng', 'das' => 'ger', 'dem' => 'ger', 'der' => 'ger', 'ein' => 'ger', 'eine' => 'ger', 'einem' => 'ger', 'einen' => 'ger', 'einer' => 'ger', 'eines' => 'ger', 'el' => 'spa', 'en' => 'cat dan nor swe', 'gl' => 'ita', 'gli' => 'ita', 'il' => 'ita mlt', 'l' => 'cat fre ita mlt', 'la' => 'cat fre ita spa', 'las' => 'spa', 'le' => 'fre ita', 'les' => 'cat fre', 'lo' => 'ita spa', 'los' => 'spa', 'os' => 'por', 'the' => 'eng', 'um' => 'por', 'uma' => 'por', 'un' => 'cat spa fre ita', 'una' => 'cat spa ita', 'une' => 'fre', 'uno' => 'ita', ); // add exceptions here as needed // may want to make keys lowercase static $exceptions = array( 'A & E', 'A & ', 'A-', 'A+', 'A is ', 'A isn\'t ', 'A l\'', 'A la ', 'A posteriori', 'A priori', 'A to ', 'El Nino', 'El Salvador', 'L is ', 'L-', 'La Salle', 'Las Vegas', 'Lo cual', 'Lo mein', 'Lo que', 'Los Alamos', 'Los Angeles', ); // get tagno to determine which indicator to check and for reporting $tagNo = $field->getTag(); // retrieve tagno from subfield 6 if 880 field if ($tagNo == '880' && ($sub6 = $field->getSubfield('6'))) { $tagNo = substr($sub6->getData(), 0, 3); } // $ind holds nonfiling character indicator value $ind = ''; // $first_or_second holds which indicator is for nonfiling char value $first_or_second = ''; if (in_array($tagNo, array(130, 630, 730))) { $ind = $field->getIndicator(1); $first_or_second = '1st'; } else if (in_array($tagNo, array(240, 245, 440, 830))) { $ind = $field->getIndicator(2); $first_or_second = '2nd'; } else { $this->warn( 'Internal error: ' . $tagNo . " is not a valid field for article checking\n" ); return; } if (!is_numeric($ind)) { $this->warn($tagNo . ": Non-filing indicator is non-numeric"); return; } // get subfield 'a' of the title field $titleField = $field->getSubfield('a'); $title = $titleField ? $titleField->getData() : ''; // warn about out-of-range skip indicators (note: this feature is an // addition to the PHP code; it is not ported directly from MARC::Lint). if ($ind > strlen($title)) { $this->warn($tagNo . ": Non-filing indicator is out of range"); return; } $char1_notalphanum = 0; // check for apostrophe, quote, bracket, or parenthesis, before first word // remove if found and add to non-word counter while (preg_match('/^["\'\[\(*]/', $title)) { $char1_notalphanum++; $title = preg_replace('/^["\'\[\(*]/', '', $title); } // split title into first word + rest on space, parens, bracket, apostrophe, // quote, or hyphen preg_match('/^([^ \(\)\[\]\'"\-]+)([ \(\)\[\]\'"\-])?(.*)/i', $title, $hits); $firstword = isset($hits[1]) ? $hits[1] : ''; $separator = isset($hits[2]) ? $hits[2] : ''; $etc = isset($hits[3]) ? $hits[3] : ''; // get length of first word plus the number of chars removed above plus one // for the separator $nonfilingchars = strlen($firstword) + $char1_notalphanum + 1; // check to see if first word is an exception $isan_exception = false; foreach ($exceptions as $current) { if (substr($title, 0, strlen($current)) == $current) { $isan_exception = true; break; } } // lowercase chars of $firstword for comparison with article list $firstword = strtolower($firstword); // see if first word is in the list of articles and not an exception $isan_article = !$isan_exception && isset($article[$firstword]); // if article then $nonfilingchars should match $ind if ($isan_article) { // account for quotes, apostrophes, parens, or brackets before 2nd word if (strlen($separator) && preg_match('/^[ \(\)\[\]\'"\-]+/', $etc)) { while (preg_match('/^[ "\'\[\]\(\)*]/', $etc)) { $nonfilingchars++; $etc = preg_replace('/^[ "\'\[\]\(\)*]/', '', $etc); } } if ($nonfilingchars != $ind) { $this->warn( $tagNo . ": First word, $firstword, may be an article, check " . "$first_or_second indicator ($ind)." ); } } else { // not an article so warn if $ind is not 0 if ($ind != '0') { $this->warn( $tagNo . ": First word, $firstword, does not appear to be an " . "article, check $first_or_second indicator ($ind)." ); } } } // }}} // {{{ parseRules() /** * Support method for constructor to load MARC rules. * * @return void */ protected function parseRules() { // Break apart the rule data on line breaks: $lines = explode("\n", $this->getRawRules()); // Each group of data is split by a blank line -- process one group // at a time: $currentGroup = array(); foreach ($lines as $currentLine) { if (empty($currentLine) && !empty($currentGroup)) { $this->processRuleGroup($currentGroup); $currentGroup = array(); } else { $currentGroup[] = preg_replace("/\s+/", " ", $currentLine); } } // Still have unprocessed data after the loop? Handle it now: if (!empty($currentGroup)) { $this->processRuleGroup($currentGroup); } } // }}} // {{{ processRuleGroup() /** * Support method for parseRules() -- process one group of lines representing * a single tag. * * @param array $rules Rule lines to process * * @return void */ protected function processRuleGroup($rules) { // The first line is guaranteed to exist and gives us some basic info: list($tag, $repeatable, $description) = explode(' ', $rules[0]); $this->rules[$tag] = array( 'repeatable' => $repeatable, 'desc' => $description ); // We may or may not have additional details: for ($i = 1; $i < count($rules); $i++) { list($key, $value, $lineDesc) = explode(' ', $rules[$i] . ' '); if (substr($key, 0, 3) == 'ind') { // Expand ranges: $value = str_replace('0-9', '0123456789', $value); $this->rules[$tag][$key] = array( 'values' => $value, 'hr_values' => $this->getHumanReadableIndicatorValues($value), 'desc'=> $lineDesc ); } else { if (strlen($key) <= 1) { $this->rules[$tag]['sub' . $key] = array( 'repeatable' => $value, 'desc' => $lineDesc ); } elseif (strstr($key, '-')) { list($startKey, $endKey) = explode('-', $key); for ($key = $startKey; $key <= $endKey; $key++) { $this->rules[$tag]['sub' . $key] = array( 'repeatable' => $value, 'desc' => $lineDesc ); } } } } } // }}} // {{{ getHumanReadableIndicatorValues() /** * Turn a set of indicator rules into a human-readable list. * * @param string $rules Indicator rules * * @return string */ protected function getHumanReadableIndicatorValues($rules) { // No processing needed for blank rule: if ($rules == 'blank') { return $rules; } // Create string: $string = ''; $length = strlen($rules); for ($i = 0; $i < $length; $i++) { $current = substr($rules, $i, 1); if ($current == 'b') { $current = 'blank'; } $string .= $current; if ($length - $i == 2) { $string .= ' or '; } else if ($length - $i > 2) { $string .= ', '; } } return $string; } // }}} // {{{ getRawRules() /** * Support method for parseRules() -- get the raw rules from MARC::Lint. * * @return string */ protected function getRawRules() { // When updating rules, don't forget to escape the dollar signs in the text! // It would be simpler to change from HEREDOC to NOWDOC syntax, but that // would raise the requirements to PHP 5.3. // @codingStandardsIgnoreStart return <<<RULES 001 NR CONTROL NUMBER ind1 blank Undefined ind2 blank Undefined NR Undefined 002 NR LOCALLY DEFINED (UNOFFICIAL) ind1 blank Undefined ind2 blank Undefined NR Undefined 003 NR CONTROL NUMBER IDENTIFIER ind1 blank Undefined ind2 blank Undefined NR Undefined 005 NR DATE AND TIME OF LATEST TRANSACTION ind1 blank Undefined ind2 blank Undefined NR Undefined 006 R FIXED-LENGTH DATA ELEMENTS--ADDITIONAL MATERIAL CHARACTERISTICS--GENERAL INFORMATION ind1 blank Undefined ind2 blank Undefined R Undefined 007 R PHYSICAL DESCRIPTION FIXED FIELD--GENERAL INFORMATION ind1 blank Undefined ind2 blank Undefined R Undefined 008 NR FIXED-LENGTH DATA ELEMENTS--GENERAL INFORMATION ind1 blank Undefined ind2 blank Undefined NR Undefined 010 NR LIBRARY OF CONGRESS CONTROL NUMBER ind1 blank Undefined ind2 blank Undefined a NR LC control number b R NUCMC control number z R Canceled/invalid LC control number 8 R Field link and sequence number 013 R PATENT CONTROL INFORMATION ind1 blank Undefined ind2 blank Undefined a NR Number b NR Country c NR Type of number d R Date e R Status f R Party to document 6 NR Linkage 8 R Field link and sequence number 015 R NATIONAL BIBLIOGRAPHY NUMBER ind1 blank Undefined ind2 blank Undefined a R National bibliography number q R Qualifying information z R Canceled/Invalid national bibliography number 2 NR Source 6 NR Linkage 8 R Field link and sequence number 016 R NATIONAL BIBLIOGRAPHIC AGENCY CONTROL NUMBER ind1 b7 National bibliographic agency ind2 blank Undefined a NR Record control number z R Canceled or invalid record control number 2 NR Source 8 R Field link and sequence number 017 R COPYRIGHT OR LEGAL DEPOSIT NUMBER ind1 blank Undefined ind2 b8 Undefined a R Copyright or legal deposit number b NR Assigning agency d NR Date i NR Display text z R Canceled/invalid copyright or legal deposit number 2 NR Source 6 NR Linkage 8 R Field link and sequence number 018 NR COPYRIGHT ARTICLE-FEE CODE ind1 blank Undefined ind2 blank Undefined a NR Copyright article-fee code 6 NR Linkage 8 R Field link and sequence number 020 R INTERNATIONAL STANDARD BOOK NUMBER ind1 blank Undefined ind2 blank Undefined a NR International Standard Book Number c NR Terms of availability q R Qualifying information z R Canceled/invalid ISBN 6 NR Linkage 8 R Field link and sequence number 022 R INTERNATIONAL STANDARD SERIAL NUMBER ind1 b01 Level of international interest ind2 blank Undefined a NR International Standard Serial Number l NR ISSN-L m R Canceled ISSN-L y R Incorrect ISSN z R Canceled ISSN 2 NR Source 6 NR Linkage 8 R Field link and sequence number 024 R OTHER STANDARD IDENTIFIER ind1 0123478 Type of standard number or code ind2 b01 Difference indicator a NR Standard number or code c NR Terms of availability d NR Additional codes following the standard number or code q R Qualifying information z R Canceled/invalid standard number or code 2 NR Source of number or code 6 NR Linkage 8 R Field link and sequence number 025 R OVERSEAS ACQUISITION NUMBER ind1 blank Undefined ind2 blank Undefined a R Overseas acquisition number 8 R Field link and sequence number 026 R FINGERPRINT IDENTIFIER ind1 blank Undefined ind2 blank Undefined a R First and second groups of characters b R Third and fourth groups of characters c NR Date d R Number of volume or part e NR Unparsed fingerprint 2 NR Source 5 R Institution to which field applies 6 NR Linkage 8 R Field link and sequence number 027 R STANDARD TECHNICAL REPORT NUMBER ind1 blank Undefined ind2 blank Undefined a NR Standard technical report number q R Qualifying information z R Canceled/invalid number 6 NR Linkage 8 R Field link and sequence number 028 R PUBLISHER NUMBER OR DISTRIBUTOR NUMBER ind1 0123456 Type of publisher number ind2 0123 Note/added entry controller a NR Publisher or distributor number b NR Source q R Qualifying information 6 NR Linkage 8 R Field link and sequence number 030 R CODEN DESIGNATION ind1 blank Undefined ind2 blank Undefined a NR CODEN z R Canceled/invalid CODEN 6 NR Linkage 8 R Field link and sequence number 031 R MUSICAL INCIPITS INFORMATION ind1 blank Undefined ind2 blank Undefined a NR Number of work b NR Number of movement c NR Number of excerpt d R Caption or heading e NR Role g NR Clef m NR Voice/instrument n NR Key signature o NR Time signature p NR Musical notation q R General note r NR Key or mode s R Coded validity note t R Text incipit u R Uniform Resource Identifier y R Link text z R Public note 2 NR System code 6 NR Linkage 8 R Field link and sequence number 032 R POSTAL REGISTRATION NUMBER ind1 blank Undefined ind2 blank Undefined a NR Postal registration number b NR Source (agency assigning number) 6 NR Linkage 8 R Field link and sequence number 033 R DATE/TIME AND PLACE OF AN EVENT ind1 b012 Type of date in subfield \$a ind2 b012 Type of event a R Formatted date/time b R Geographic classification area code c R Geographic classification subarea code p R Place of event 0 R Record control number 2 R Source of term 3 NR Materials specified 6 NR Linkage 8 R Field link and sequence number 034 R CODED CARTOGRAPHIC MATHEMATICAL DATA ind1 013 Type of scale ind2 b01 Type of ring a NR Category of scale b R Constant ratio linear horizontal scale c R Constant ratio linear vertical scale d NR Coordinates--westernmost longitude e NR Coordinates--easternmost longitude f NR Coordinates--northernmost latitude g NR Coordinates--southernmost latitude h R Angular scale j NR Declination--northern limit k NR Declination--southern limit m NR Right ascension--eastern limit n NR Right ascension--western limit p NR Equinox r NR Distance from earth s R G-ring latitude t R G-ring longitude x NR Beginning date y NR Ending date z NR Name of extraterrestrial body 0 R Authority record control number or standard number 2 NR Source 3 NR Materials specified 6 NR Linkage 8 R Field link and sequence number 035 R SYSTEM CONTROL NUMBER ind1 blank Undefined ind2 blank Undefined a NR System control number z R Canceled/invalid control number 6 NR Linkage 8 R Field link and sequence number 036 NR ORIGINAL STUDY NUMBER FOR COMPUTER DATA FILES ind1 blank Undefined ind2 blank Undefined a NR Original study number b NR Source (agency assigning number) 6 NR Linkage 8 R Field link and sequence number 037 R SOURCE OF ACQUISITION ind1 b23 Source of acquisition sequence ind2 blank Undefined a NR Stock number b NR Source of stock number/acquisition c R Terms of availability f R Form of issue g R Additional format characteristics n R Note 3 NR Materials specified 5 R Institution to which field applies 6 NR Linkage 8 R Field link and sequence number 038 NR RECORD CONTENT LICENSOR ind1 blank Undefined ind2 blank Undefined a NR Record content licensor 6 NR Linkage 8 R Field link and sequence number 040 NR CATALOGING SOURCE ind1 blank Undefined ind2 blank Undefined a NR Original cataloging agency b NR Language of cataloging c NR Transcribing agency d R Modifying agency e R Description conventions 6 NR Linkage 8 R Field link and sequence number 041 R LANGUAGE CODE ind1 b01 Translation indication ind2 b7 Source of code a R Language code of text/sound track or separate title b R Language code of summary or abstract d R Language code of sung or spoken text e R Language code of librettos f R Language code of table of contents g R Language code of accompanying material other than librettos h R Language code of original j R Language code of subtitles or captions k R Language code of intermediate translations m R Language code of original accompanying materials other than librettos n R Language code of original libretto 2 NR Source of code 6 NR Linkage 8 R Field link and sequence number 042 NR AUTHENTICATION CODE ind1 blank Undefined ind2 blank Undefined a R Authentication code 043 NR GEOGRAPHIC AREA CODE ind1 blank Undefined ind2 blank Undefined a R Geographic area code b R Local GAC code c R ISO code 0 R Authority record control number or standard number 2 R Source of local code 6 NR Linkage 8 R Field link and sequence number 044 NR COUNTRY OF PUBLISHING/PRODUCING ENTITY CODE ind1 blank Undefined ind2 blank Undefined a R MARC country code b R Local subentity code c R ISO country code 2 R Source of local subentity code 6 NR Linkage 8 R Field link and sequence number 045 NR TIME PERIOD OF CONTENT ind1 b012 Type of time period in subfield \$b or \$c ind2 blank Undefined a R Time period code b R Formatted 9999 B.C. through C.E. time period c R Formatted pre-9999 B.C. time period 6 NR Linkage 8 R Field link and sequence number 046 R SPECIAL CODED DATES ind1 blank Undefined ind2 blank Undefined a NR Type of date code b NR Date 1 (B.C.E. date) c NR Date 1 (C.E. date) d NR Date 2 (B.C.E. date) e NR Date 2 (C.E. date) j NR Date resource modified k NR Beginning or single date created l NR Ending date created m NR Beginning of date valid n NR End of date valid o NR Single or starting date for aggregated content p NR Ending date for aggregated content 2 NR Source of date 6 NR Linkage 8 R Field link and sequence number 047 R FORM OF MUSICAL COMPOSITION CODE ind1 blank Undefined ind2 b7 Source of code a R Form of musical composition code 2 NR Source of code 8 R Field link and sequence number 048 R NUMBER OF MUSICAL INSTRUMENTS OR VOICES CODE ind1 blank Undefined ind2 b7 Source specified in subfield \$2 a R Performer or ensemble b R Soloist 2 NR Source of code 8 R Field link and sequence number 050 R LIBRARY OF CONGRESS CALL NUMBER ind1 b01 Existence in LC collection ind2 04 Source of call number a R Classification number b NR Item number 0 R Authority record control number or standard number 3 NR Materials specified 6 NR Linkage 8 R Field link and sequence number 051 R LIBRARY OF CONGRESS COPY, ISSUE, OFFPRINT STATEMENT ind1 blank Undefined ind2 blank Undefined a NR Classification number b NR Item number c NR Copy information 8 R Field link and sequence number 052 R GEOGRAPHIC CLASSIFICATION ind1 b17 Code source ind2 blank Undefined a NR Geographic classification area code b R Geographic classification subarea code d R Populated place name 0 R Authority record control number or standard number 2 NR Code source 6 NR Linkage 8 R Field link and sequence number 055 R CLASSIFICATION NUMBERS ASSIGNED IN CANADA ind1 b01 Existence in LAC collection ind2 0123456789 Type, completeness, source of class/call number a NR Classification number b NR Item number 0 R Authority record control number or standard number 2 NR Source of call/class number 8 R Field link and sequence number 060 R NATIONAL LIBRARY OF MEDICINE CALL NUMBER ind1 b01 Existence in NLM collection ind2 04 Source of call number a R Classification number b NR Item number 0 R Authority record control number or standard number 8 R Field link and sequence number 061 R NATIONAL LIBRARY OF MEDICINE COPY STATEMENT ind1 blank Undefined ind2 blank Undefined a R Classification number b NR Item number c NR Copy information 8 R Field link and sequence number 066 NR CHARACTER SETS PRESENT ind1 blank Undefined ind2 blank Undefined a NR Primary G0 character set b NR Primary G1 character set c R Alternate G0 or G1 character set 070 R NATIONAL AGRICULTURAL LIBRARY CALL NUMBER ind1 b01 Existence in NAL collection ind2 blank Undefined a R Classification number b NR Item number 0 R Authority record control number or standard number 8 R Field link and sequence number 071 R NATIONAL AGRICULTURAL LIBRARY COPY STATEMENT ind1 blank Undefined ind2 blank Undefined a R Classification number b NR Item number c NR Copy information 8 R Field link and sequence number 072 R SUBJECT CATEGORY CODE ind1 blank Undefined ind2 07 Source specified in subfield \$2 a NR Subject category code x R Subject category code subdivision 2 NR Source 6 NR Linkage 8 R Field link and sequence number 074 R GPO ITEM NUMBER ind1 blank Undefined ind2 blank Undefined a NR GPO item number z R Canceled/invalid GPO item number 8 R Field link and sequence number 080 R UNIVERSAL DECIMAL CLASSIFICATION NUMBER ind1 01 Type of edition ind2 blank Undefined a NR Universal Decimal Classification number b NR Item number x R Common auxiliary subdivision 0 R Authority record control number or standard number 2 NR Edition identifier 6 NR Linkage 8 R Field link and sequence number 082 R DEWEY DECIMAL CLASSIFICATION NUMBER ind1 017 Type of edition ind2 b04 Source of classification number a R Classification number b NR Item number m NR Standard or optional designation q NR Assigning agency 2 NR Edition number 6 NR Linkage 8 R Field link and sequence number 083 R ADDITIONAL DEWEY DECIMAL CLASSIFICATION NUMBER ind1 017 Type of edition ind2 blank Undefined a R Classification number c R Classification number--Ending number of span m NR Standard or optional designation q NR Assigning agency y R Table sequence number for internal subarrangement or add table z R Table identification 2 NR Edition number 6 NR Linkage 8 R Field link and sequence number 084 R OTHER CLASSIFICATION NUMBER ind1 blank Undefined ind2 blank Undefined a R Classification number b NR Item number q NR Assigning agency 0 R Authority record control number or standard number 2 NR Source of number 6 NR Linkage 8 R Field link and sequence number 085 R SYNTHESIZED CLASSIFICATION NUMBER COMPONENTS ind1 blank Undefined ind2 blank Undefined a R Number where instructions are found-single number or beginning number of span b R Base number c R Classification number-ending number of span f R Facet designator r R Root number s R Digits added from classification number in schedule or external table t R Digits added from internal subarrangement or add table u R Number being analyzed v R Number in internal subarrangement or add table where instructions are found w R Table identification-Internal subarrangement or add table y R Table sequence number for internal subarrangement or add table z R Table identification 0 R Authority record control number or standard number 6 NR Linkage 8 R Field link and sequence number 086 R GOVERNMENT DOCUMENT CLASSIFICATION NUMBER ind1 b01 Number source ind2 blank Undefined a NR Classification number z R Canceled/invalid classification number 0 R Authority record control number or standard number 2 NR Number source 6 NR Linkage 8 R Field link and sequence number 088 R REPORT NUMBER ind1 blank Undefined ind2 blank Undefined a NR Report number z R Canceled/invalid report number 6 NR Linkage 8 R Field link and sequence number 100 NR MAIN ENTRY--PERSONAL NAME ind1 013 Type of personal name entry element ind2 blank Undefined a NR Personal name b NR Numeration c R Titles and other words associated with a name d NR Dates associated with a name e R Relator term f NR Date of a work g R Miscellaneous information j R Attribution qualifier k R Form subheading l NR Language of a work n R Number of part/section of a work p R Name of part/section of a work q NR Fuller form of name t NR Title of a work u NR Affiliation 0 R Authority record control number 4 R Relationship 6 NR Linkage 8 R Field link and sequence number 110 NR MAIN ENTRY--CORPORATE NAME ind1 012 Type of corporate name entry element ind2 blank Undefined a NR Corporate name or jurisdiction name as entry element b R Subordinate unit c R Location of meeting d R Date of meeting or treaty signing e R Relator term f NR Date of a work g R Miscellaneous information k R Form subheading l NR Language of a work n R Number of part/section/meeting p R Name of part/section of a work t NR Title of a work u NR Affiliation 0 R Authority record control number 4 R Relationship 6 NR Linkage 8 R Field link and sequence number 111 NR MAIN ENTRY--MEETING NAME ind1 012 Type of meeting name entry element ind2 blank Undefined a NR Meeting name or jurisdiction name as entry element c R Location of meeting d NR Date of meeting e R Subordinate unit f NR Date of a work g R Miscellaneous information j R Relator term k R Form subheading l NR Language of a work n R Number of part/section/meeting p R Name of part/section of a work q NR Name of meeting following jurisdiction name entry element t NR Title of a work u NR Affiliation 0 R Authority record control number 4 R Relationship 6 NR Linkage 8 R Field link and sequence number 130 NR MAIN ENTRY--UNIFORM TITLE ind1 0-9 Nonfiling characters ind2 blank Undefined a NR Uniform title d R Date of treaty signing f NR Date of a work g R Miscellaneous information h NR Medium k R Form subheading l NR Language of a work m R Medium of performance for music n R Number of part/section of a work o NR Arranged statement for music p R Name of part/section of a work r NR Key for music s NR Version t NR Title of a work 0 R Authority record control number 6 NR Linkage 8 R Field link and sequence number 210 R ABBREVIATED TITLE ind1 01 Title added entry ind2 b0 Type a NR Abbreviated title b NR Qualifying information 2 R Source 6 NR Linkage 8 R Field link and sequence number 222 R KEY TITLE ind1 blank Specifies whether variant title and/or added entry is required ind2 0-9 Nonfiling characters a NR Key title b NR Qualifying information 6 NR Linkage 8 R Field link and sequence number 240 NR UNIFORM TITLE ind1 01 Uniform title printed or displayed ind2 0-9 Nonfiling characters a NR Uniform title d R Date of treaty signing f NR Date of a work g R Miscellaneous information h NR Medium k R Form subheading l NR Language of a work m R Medium of performance for music n R Number of part/section of a work o NR Arranged statement for music p R Name of part/section of a work r NR Key for music s NR Version 0 R Authority record control number 6 NR Linkage 8 R Field link and sequence number 242 R TRANSLATION OF TITLE BY CATALOGING AGENCY ind1 01 Title added entry ind2 0-9 Nonfiling characters a NR Title b NR Remainder of title c NR Statement of responsibility, etc. h NR Medium n R Number of part/section of a work p R Name of part/section of a work y NR Language code of translated title 6 NR Linkage 8 R Field link and sequence number 243 NR COLLECTIVE UNIFORM TITLE ind1 01 Uniform title printed or displayed ind2 0-9 Nonfiling characters a NR Uniform title d R Date of treaty signing f NR Date of a work g R Miscellaneous information h NR Medium k R Form subheading l NR Language of a work m R Medium of performance for music n R Number of part/section of a work o NR Arranged statement for music p R Name of part/section of a work r NR Key for music s NR Version 6 NR Linkage 8 R Field link and sequence number 245 NR TITLE STATEMENT ind1 01 Title added entry ind2 0-9 Nonfiling characters a NR Title b NR Remainder of title c NR Statement of responsibility, etc. f NR Inclusive dates g NR Bulk dates h NR Medium k R Form n R Number of part/section of a work p R Name of part/section of a work s NR Version 6 NR Linkage 8 R Field link and sequence number 246 R VARYING FORM OF TITLE ind1 0123 Note/added entry controller ind2 b012345678 Type of title a NR Title proper/short title b NR Remainder of title f NR Date or sequential designation g R Miscellaneous information h NR Medium i NR Display text n R Number of part/section of a work p R Name of part/section of a work 5 NR Institution to which field applies 6 NR Linkage 8 R Field link and sequence number 247 R FORMER TITLE ind1 01 Title added entry ind2 01 Note controller a NR Title b NR Remainder of title f NR Date or sequential designation g R Miscellaneous information h NR Medium n R Number of part/section of a work p R Name of part/section of a work x NR International Standard Serial Number 6 NR Linkage 8 R Field link and sequence number 250 R EDITION STATEMENT ind1 blank Undefined ind2 blank Undefined a NR Edition statement b NR Remainder of edition statement 3 NR Materials specified 6 NR Linkage 8 R Field link and sequence number 254 NR MUSICAL PRESENTATION STATEMENT ind1 blank Undefined ind2 blank Undefined a NR Musical presentation statement 6 NR Linkage 8 R Field link and sequence number 255 R CARTOGRAPHIC MATHEMATICAL DATA ind1 blank Undefined ind2 blank Undefined a NR Statement of scale b NR Statement of projection c NR Statement of coordinates d NR Statement of zone e NR Statement of equinox f NR Outer G-ring coordinate pairs g NR Exclusion G-ring coordinate pairs 6 NR Linkage 8 R Field link and sequence number 256 NR COMPUTER FILE CHARACTERISTICS ind1 blank Undefined ind2 blank Undefined a NR Computer file characteristics 6 NR Linkage 8 R Field link and sequence number 257 R COUNTRY OF PRODUCING ENTITY ind1 blank Undefined ind2 blank Undefined a R Country of producing entity 0 R Authority record control number or standard number 2 NR Source 6 NR Linkage 8 R Field link and sequence number 258 R PHILATELIC ISSUE DATE ind1 blank Undefined ind2 blank Undefined a NR Issuing jurisdiction b NR Denomination 6 NR Linkage 8 R Field link and sequence number 260 R PUBLICATION, DISTRIBUTION, ETC. (IMPRINT) ind1 b23 Sequence of publishing statements ind2 blank Undefined a R Place of publication, distribution, etc. b R Name of publisher, distributor, etc. c R Date of publication, distribution, etc. d NR Plate or publisher's number for music (Pre-AACR 2) e R Place of manufacture f R Manufacturer g R Date of manufacture 3 NR Materials specified 6 NR Linkage 8 R Field link and sequence number 261 NR IMPRINT STATEMENT FOR FILMS (Pre-AACR 1 Revised) ind1 blank Undefined ind2 blank Undefined a R Producing company b R Releasing company (primary distributor) d R Date of production, release, etc. e R Contractual producer f R Place of production, release, etc. 6 NR Linkage 8 R Field link and sequence number 262 NR IMPRINT STATEMENT FOR SOUND RECORDINGS (Pre-AACR 2) ind1 blank Undefined ind2 blank Undefined a NR Place of production, release, etc. b NR Publisher or trade name c NR Date of production, release, etc. k NR Serial identification l NR Matrix and/or take number 6 NR Linkage 8 R Field link and sequence number 263 NR PROJECTED PUBLICATION DATE ind1 blank Undefined ind2 blank Undefined a NR Projected publication date 6 NR Linkage 8 R Field link and sequence number 264 R PRODUCTION, PUBLICATION, DISTRIBUTION, MANUFACTURE, AND COPYRIGHT NOTICE ind1 b23 Sequence of statements ind2 01234 Function of entity a R Place of production, publication, distribution, manufacture b R Name of producer, publisher, distributor, manufacturer c R Date of production, publication, distribution, manufacture, or copyright notice 3 NR Materials specified 6 NR Linkage 8 R Field link and sequence number (R) 270 R ADDRESS ind1 b12 Level ind2 b07 Type of address a R Address b NR City c NR State or province d NR Country e NR Postal code f NR Terms preceding attention name g NR Attention name h NR Attention position i NR Type of address j R Specialized telephone number k R Telephone number l R Fax number m R Electronic mail address n R TDD or TTY number p R Contact person q R Title of contact person r R Hours z R Public note 4 R Relationship 6 NR Linkage 8 R Field link and sequence number 300 R PHYSICAL DESCRIPTION ind1 blank Undefined ind2 blank Undefined a R Extent b NR Other physical details c R Dimensions e NR Accompanying material f R Type of unit g R Size of unit 3 NR Materials specified 6 NR Linkage 8 R Field link and sequence number 306 NR PLAYING TIME ind1 blank Undefined ind2 blank Undefined a R Playing time 6 NR Linkage 8 R Field link and sequence number 307 R HOURS, ETC. ind1 b8 Display constant controller ind2 blank Undefined a NR Hours b NR Additional information 6 NR Linkage 8 R Field link and sequence number 310 NR CURRENT PUBLICATION FREQUENCY ind1 blank Undefined ind2 blank Undefined a NR Current publication frequency b NR Date of current publication frequency 6 NR Linkage 8 R Field link and sequence number 321 R FORMER PUBLICATION FREQUENCY ind1 blank Undefined ind2 blank Undefined a NR Former publication frequency b NR Dates of former publication frequency 6 NR Linkage 8 R Field link and sequence number 336 R CONTENT TYPE ind1 blank Undefined ind2 blank Undefined a R Content type term b R Content type code 0 R Authority record control number or standard number 2 NR Source 3 NR Materials specified 6 NR Linkage 8 R Field link and sequence number 337 R MEDIA TYPE ind1 blank Undefined ind2 blank Undefined a R Media type term b R Media type code 0 R Authority record control number or standard number 2 NR Source 3 NR Materials specified 6 NR Linkage 8 R Field link and sequence number 338 R CARRIER TYPE ind1 blank Undefined ind2 blank Undefined a R Carrier type term b R Carrier type code 0 R Authority record control number or standard number 2 NR Source 3 NR Materials specified 6 NR Linkage 8 R Field link and sequence number 340 R PHYSICAL MEDIUM ind1 blank Undefined ind2 blank Undefined a R Material base and configuration b R Dimensions c R Materials applied to surface d R Information recording technique e R Support f R Production rate/ratio g R Color content h R Location within medium i R Technical specifications of medium j R Generation k R Layout m R Book format n R Font size o R Polarity 0 R Authority record control number or standard number 2 NR Source 3 NR Materials specified 6 NR Linkage 8 R Field link and sequence number 342 R GEOSPATIAL REFERENCE DATA ind1 01 Geospatial reference dimension ind2 012345678 Geospatial reference method a NR Name b NR Coordinate or distance units c NR Latitude resolution d NR Longitude resolution e R Standard parallel or oblique line latitude f R Oblique line longitude g NR Longitude of central meridian or projection center h NR Latitude of projection origin or projection center i NR False easting j NR False northing k NR Scale factor l NR Height of perspective point above surface m NR Azimuthal angle o NR Landsat number and path number p NR Zone identifier q NR Ellipsoid name r NR Semi-major axis s NR Denominator of flattening ratio t NR Vertical resolution u NR Vertical encoding method v NR Local planar, local, or other projection or grid description w NR Local planar or local georeference information 2 NR Reference method used 6 NR Linkage 8 R Field link and sequence number 343 R PLANAR COORDINATE DATA ind1 blank Undefined ind2 blank Undefined a NR Planar coordinate encoding method b NR Planar distance units c NR Abscissa resolution d NR Ordinate resolution e NR Distance resolution f NR Bearing resolution g NR Bearing units h NR Bearing reference direction i NR Bearing reference meridian 6 NR Linkage 8 R Field link and sequence number 344 R SOUND CHARACTERISTICS ind1 blank Undefined ind2 blank Undefined a R Type of recording b R Recording medium c R Playing speed d R Groove characteristic e R Track configuration f R Tape configuration g R Configuration of playback channels h R Special playback characteristics 0 R Authority record control number or standard number 2 NR Source 3 NR Materials specified 6 NR Linkage 8 R Field link and sequence number 345 R PROJECTION CHARACTERISTICS OF MOVING IMAGE ind1 blank Undefined ind2 blank Undefined a R Presentation format b R Projection speed 0 R Authority record control number or standard number 2 NR Source 3 NR Materials specified 6 NR Linkage 8 R Field link and sequence number 346 R VIDEO CHARACTERISTICS ind1 blank Undefined ind2 blank Undefined a R Video format b R Broadcast standard 0 R Authority record control number or standard number 2 NR Source 3 NR Materials specified 6 NR Linkage 8 R Field link and sequence number 347 R DIGITAL FILE CHARACTERISTICS ind1 blank Undefined ind2 blank Undefined a R File type b R Encoding format c R File size d R Resolution e R Regional encoding f R Encoded bitrate 0 R Authority record control number or standard number 2 NR Source 3 NR Materials specified 6 NR Linkage 8 R Field link and sequence number 348 R FORMAT OF NOTATED MUSIC ind1 blank Undefined ind2 blank Undefined a R Format of notated music term b R Format of notated music code 0 R Authority record control number or standard number 2 NR Source of term 3 NR Materials specified 6 NR Linkage 8 R Field link and sequence number 351 R ORGANIZATION AND ARRANGEMENT OF MATERIALS ind1 blank Undefined ind2 blank Undefined a R Organization b R Arrangement c NR Hierarchical level 3 NR Materials specified 6 NR Linkage 8 R Field link and sequence number 352 R DIGITAL GRAPHIC REPRESENTATION ind1 blank Undefined ind2 blank Undefined a NR Direct reference method b R Object type c R Object count d NR Row count e NR Column count f NR Vertical count g NR VPF topology level i NR Indirect reference description q R Format of the digital image 6 NR Linkage 8 R Field link and sequence number 355 R SECURITY CLASSIFICATION CONTROL ind1 0123458 Controlled element ind2 blank Undefined a NR Security classification b R Handling instructions c R External dissemination information d NR Downgrading or declassification event e NR Classification system f NR Country of origin code g NR Downgrading date h NR Declassification date j R Authorization 6 NR Linkage 8 R Field link and sequence number 357 NR ORIGINATOR DISSEMINATION CONTROL ind1 blank Undefined ind2 blank Undefined a NR Originator control term b R Originating agency c R Authorized recipients of material g R Other restrictions 6 NR Linkage 8 R Field link and sequence number 362 R DATES OF PUBLICATION AND/OR SEQUENTIAL DESIGNATION ind1 01 Format of date ind2 blank Undefined a NR Dates of publication and/or sequential designation z NR Source of information 6 NR Linkage 8 R Field link and sequence number 363 R NORMALIZED DATE AND SEQUENTIAL DESIGNATION ind1 b01 Start/End designator ind2 b01 State of issuanceUndefined a NR First level of enumeration b NR Second level of enumeration c NR Third level of enumeration d NR Fourth level of enumeration e NR Fifth level of enumeration f NR Sixth level of enumeration g NR Alternative numbering scheme, first level of enumeration h NR Alternative numbering scheme, second level of enumeration i NR First level of chronology j NR Second level of chronology k NR Third level of chronology l NR Fourth level of chronology m NR Alternative numbering scheme, chronology u NR First level textual designation v NR First level of chronology, issuance x R Nonpublic note z R Public note 6 NR Linkage 8 NR Field link and sequence number 365 R TRADE PRICE ind1 blank Undefined ind2 blank Undefined a NR Price type code b NR Price amount c NR Currency code d NR Unit of pricing e NR Price note f NR Price effective from g NR Price effective until h NR Tax rate 1 i NR Tax rate 2 j NR ISO country code k NR MARC country code m NR Identification of pricing entity 2 NR Source of price type code 6 NR Linkage 8 R Field link and sequence number 366 R TRADE AVAILABILITY INFORMATION ind1 blank Undefined ind2 blank Undefined a NR Publishers' compressed title identification b NR Detailed date of publication c NR Availability status code d NR Expected next availability date e NR Note f NR Publishers' discount category g NR Date made out of print j NR ISO country code k NR MARC country code m NR Identification of agency 2 NR Source of availability status code 6 NR Linkage 8 R Field link and sequence number 370 R ASSOCIATED PLACE ind1 blank Undefined ind2 blank Undefined c R Associated country f R Other associated place g R Place of origin of work or expression i R Relationship information s NR Start period t NR End period u R Uniform Resource Identifier v R Source of information 0 R Authority record control number or standard number 2 NR Source of term 3 NR Materials specified 4 R Relationship 6 NR Linkage 8 R Field link and sequence number 377 R ASSOCIATED LANGUAGE ind1 blank Undefined ind2 b7 Undefined a R Language code 0 R Authority record control number or standard number l R Language term 2 NR Source 6 NR Linkage 8 R Field link and sequence number 380 R FORM OF WORK ind1 blank Undefined ind2 blank Undefined a R Form of work 0 R Record control number 2 NR Source of term 6 NR Linkage 8 R Field link and sequence number 381 R OTHER DISTINGUISHING CHARACTERISTICS OF WORK OR EXPRESSION ind1 blank Undefined ind2 blank Undefined a R Other distinguishing characteristic u R Uniform Resource Identifier v R Source of information 0 R Record control number 2 NR Source of term 6 NR Linkage 8 R Field link and sequence number 382 R MEDIUM OF PERFORMANCE ind1 b01 Undefined ind2 b01 Undefined a R Medium of performance b R Soloist d R Doubling instrument e R Number of ensembles of the same type n R Number of performers of the same medium p R Alternative medium of performance r NR Total number of individuals performing alongside ensembles s NR Total number of performers t NR Total number of ensembles v R Note 0 R Record control number 2 NR Source of term 3 NR Materials specified 6 NR Linkage 8 R Field link and sequence number 383 R NUMERIC DESIGNATION OF MUSICAL WORK ind1 blank Undefined ind2 blank Undefined a R Serial number b R Opus number c R Thematic index number d NR Thematic index code e NR Publisher associated with opus number 2 NR Source 6 NR Linkage 8 R Field link and sequence number 384 NR KEY ind1 b01 Key type ind2 blank Undefined a NR Key 6 NR Linkage 8 R Field link and sequence number 385 R AUDIENCE CHARACTERISTICS ind1 blank Undefined ind2 blank Undefined a R Audience term b R Audience code m NR Demographic group term n NR Demographic group code 0 R Authority record control number or standard number 2 NR Source 3 NR Materials specified 6 NR Linkage 8 R Field link and sequence number 386 R CREATOR/CONTRIBUTOR CHARACTERISTICS ind1 blank Undefined ind2 blank Undefined a R Creator/contributor term b R Creator/contributor code i R Relationship information m NR Demographic group term n NR Demographic group code 0 R Authority record control number or standard number 2 NR Source 3 NR Materials specified 4 R Relationship 6 NR Linkage 8 R Field link and sequence number 388 R TIME PERIOD OF CREATION ind1 b12 Type of time period ind2 blank Undefined a R Time period of creation term (R) 0 R Authority record control number or standard number (R) 2 NR Source of term (NR) 3 NR Materials specified (NR) 6 NR Linkage (NR) 8 R Field link and sequence number (R) 400 R SERIES STATEMENT/ADDED ENTRY--PERSONAL NAME ind1 013 Type of personal name entry element ind2 01 Pronoun represents main entry a NR Personal name b NR Numeration c R Titles and other words associated with a name d NR Dates associated with a name e R Relator term f NR Date of a work g NR Miscellaneous information k R Form subheading l NR Language of a work n R Number of part/section of a work p R Name of part/section of a work t NR Title of a work u NR Affiliation v NR Volume number/sequential designation x NR International Standard Serial Number 4 R Relator code 6 NR Linkage 8 R Field link and sequence number 410 R SERIES STATEMENT/ADDED ENTRY--CORPORATE NAME ind1 012 Type of corporate name entry element ind2 01 Pronoun represents main entry a NR Corporate name or jurisdiction name as entry element b R Subordinate unit c NR Location of meeting d R Date of meeting or treaty signing e R Relator term f NR Date of a work g NR Miscellaneous information k R Form subheading l NR Language of a work n R Number of part/section/meeting p R Name of part/section of a work t NR Title of a work u NR Affiliation v NR Volume number/sequential designation x NR International Standard Serial Number 4 R Relator code 6 NR Linkage 8 R Field link and sequence number 411 R SERIES STATEMENT/ADDED ENTRY--MEETING NAME ind1 012 Type of meeting name entry element ind2 01 Pronoun represents main entry a NR Meeting name or jurisdiction name as entry element c NR Location of meeting d NR Date of meeting e R Subordinate unit f NR Date of a work g NR Miscellaneous information k R Form subheading l NR Language of a work n R Number of part/section/meeting p R Name of part/section of a work q NR Name of meeting following jurisdiction name entry element t NR Title of a work u NR Affiliation v NR Volume number/sequential designation x NR International Standard Serial Number 4 R Relator code 6 NR Linkage 8 R Field link and sequence number 440 R SERIES STATEMENT/ADDED ENTRY--TITLE [OBSOLETE] ind1 blank Undefined ind2 0-9 Nonfiling characters a NR Title n R Number of part/section of a work p R Name of part/section of a work v NR Volume number/sequential designation x NR International Standard Serial Number w R Bibliographic record control number 0 R Authority record control number 6 NR Linkage 8 R Field link and sequence number 490 R SERIES STATEMENT ind1 01 Specifies whether series is traced ind2 blank Undefined a R Series statement l NR Library of Congress call number v R Volume number/sequential designation x R International Standard Serial Number 3 NR Materials specified 6 NR Linkage 8 R Field link and sequence number 500 R GENERAL NOTE ind1 blank Undefined ind2 blank Undefined a NR General note 3 NR Materials specified 5 NR Institution to which field applies 6 NR Linkage 8 R Field link and sequence number 501 R WITH NOTE ind1 blank Undefined ind2 blank Undefined a NR With note 5 NR Institution to which field applies 6 NR Linkage 8 R Field link and sequence number 502 R DISSERTATION NOTE ind1 blank Undefined ind2 blank Undefined a NR Dissertation note b NR Degree type c NR Name of granting institution d NR Year of degree granted g R Miscellaneous information o R Dissertation identifier 6 NR Linkage 8 R Field link and sequence number 504 R BIBLIOGRAPHY, ETC. NOTE ind1 blank Undefined ind2 blank Undefined a NR Bibliography, etc. note b NR Number of references 6 NR Linkage 8 R Field link and sequence number 505 R FORMATTED CONTENTS NOTE ind1 0128 Display constant controller ind2 b0 Level of content designation a NR Formatted contents note g R Miscellaneous information r R Statement of responsibility t R Title u R Uniform Resource Identifier 6 NR Linkage 8 R Field link and sequence number 506 R RESTRICTIONS ON ACCESS NOTE ind1 b01 Restriction ind2 blank Undefined a NR Terms governing access b R Jurisdiction c R Physical access provisions d R Authorized users e R Authorization f R Standard terminology for access restiction u R Uniform Resource Identifier 2 NR Source of term 3 NR Materials specified 5 NR Institution to which field applies 6 NR Linkage 8 R Field link and sequence number 507 NR SCALE NOTE FOR GRAPHIC MATERIAL ind1 blank Undefined ind2 blank Undefined a NR Representative fraction of scale note b NR Remainder of scale note 6 NR Linkage 8 R Field link and sequence number 508 R CREATION/PRODUCTION CREDITS NOTE ind1 blank Undefined ind2 blank Undefined a NR Creation/production credits note 6 NR Linkage 8 R Field link and sequence number 510 R CITATION/REFERENCES NOTE ind1 01234 Coverage/location in source ind2 blank Undefined a NR Name of source b NR Coverage of source c NR Location within source u R Uniform Resource Identifier x NR International Standard Serial Number 3 NR Materials specified 6 NR Linkage 8 R Field link and sequence number 511 R PARTICIPANT OR PERFORMER NOTE ind1 01 Display constant controller ind2 blank Undefined a NR Participant or performer note 6 NR Linkage 8 R Field link and sequence number 513 R TYPE OF REPORT AND PERIOD COVERED NOTE ind1 blank Undefined ind2 blank Undefined a NR Type of report b NR Period covered 6 NR Linkage 8 R Field link and sequence number 514 NR DATA QUALITY NOTE ind1 blank Undefined ind2 blank Undefined a NR Attribute accuracy report b R Attribute accuracy value c R Attribute accuracy explanation d NR Logical consistency report e NR Completeness report f NR Horizontal position accuracy report g R Horizontal position accuracy value h R Horizontal position accuracy explanation i NR Vertical positional accuracy report j R Vertical positional accuracy value k R Vertical positional accuracy explanation m NR Cloud cover u R Uniform Resource Identifier z R Display note 6 NR Linkage 8 R Field link and sequence number 515 R NUMBERING PECULIARITIES NOTE ind1 blank Undefined ind2 blank Undefined a NR Numbering peculiarities note 6 NR Linkage 8 R Field link and sequence number 516 R TYPE OF COMPUTER FILE OR DATA NOTE ind1 b8 Display constant controller ind2 blank Undefined a NR Type of computer file or data note 6 NR Linkage 8 R Field link and sequence number 518 R DATE/TIME AND PLACE OF AN EVENT NOTE ind1 blank Undefined ind2 blank Undefined a NR Date/time and place of an event note d R Date of event o R Other event information p R Place of event 0 R Record control number 2 R Source of term 3 NR Materials specified 6 NR Linkage 8 R Field link and sequence number 520 R SUMMARY, ETC. ind1 b012348 Display constant controller ind2 blank Undefined a NR Summary, etc. note b NR Expansion of summary note c NR Assigning agency u R Uniform Resource Identifier 2 NR Source 3 NR Materials specified 6 NR Linkage 8 R Field link and sequence number 521 R TARGET AUDIENCE NOTE ind1 b012348 Display constant controller ind2 blank Undefined a R Target audience note b NR Source 3 NR Materials specified 6 NR Linkage 8 R Field link and sequence number 522 R GEOGRAPHIC COVERAGE NOTE ind1 b8 Display constant controller ind2 blank Undefined a NR Geographic coverage note 6 NR Linkage 8 R Field link and sequence number 524 R PREFERRED CITATION OF DESCRIBED MATERIALS NOTE ind1 b8 Display constant controller ind2 blank Undefined a NR Preferred citation of described materials note 2 NR Source of schema used 3 NR Materials specified 6 NR Linkage 8 R Field link and sequence number 525 R SUPPLEMENT NOTE ind1 blank Undefined ind2 blank Undefined a NR Supplement note 6 NR Linkage 8 R Field link and sequence number 526 R STUDY PROGRAM INFORMATION NOTE ind1 08 Display constant controller ind2 blank Undefined a NR Program name b NR Interest level c NR Reading level d NR Title point value i NR Display text x R Nonpublic note z R Public note 5 NR Institution to which field applies 6 NR Linkage 8 R Field link and sequence number 530 R ADDITIONAL PHYSICAL FORM AVAILABLE NOTE ind1 blank Undefined ind2 blank Undefined a NR Additional physical form available note b NR Availability source c NR Availability conditions d NR Order number u R Uniform Resource Identifier 3 NR Materials specified 6 NR Linkage 8 R Field link and sequence number 533 R REPRODUCTION NOTE ind1 blank Undefined ind2 blank Undefined a NR Type of reproduction b R Place of reproduction c R Agency responsible for reproduction d NR Date of reproduction e NR Physical description of reproduction f R Series statement of reproduction m R Dates and/or sequential designation of issues reproduced n R Note about reproduction 3 NR Materials specified 5 NR Institution to which field applies 6 NR Linkage 7 NR Fixed-length data elements of reproduction 8 R Field link and sequence number 534 R ORIGINAL VERSION NOTE ind1 blank Undefined ind2 blank Undefined a NR Main entry of original b NR Edition statement of original c NR Publication, distribution, etc. of original e NR Physical description, etc. of original f R Series statement of original k R Key title of original l NR Location of original m NR Material specific details n R Note about original o R Other resource identifier p NR Introductory phrase t NR Title statement of original x R International Standard Serial Number z R International Standard Book Number 3 NR Materials specified 6 NR Linkage 8 R Field link and sequence number 535 R LOCATION OF ORIGINALS/DUPLICATES NOTE ind1 12 Additional information about custodian ind2 blank Undefined a NR Custodian b R Postal address c R Country d R Telecommunications address g NR Repository location code 3 NR Materials specified 6 NR Linkage 8 R Field link and sequence number 536 R FUNDING INFORMATION NOTE ind1 blank Undefined ind2 blank Undefined a NR Text of note b R Contract number c R Grant number d R Undifferentiated number e R Program element number f R Project number g R Task number h R Work unit number 6 NR Linkage 8 R Field link and sequence number 538 R SYSTEM DETAILS NOTE ind1 blank Undefined ind2 blank Undefined a NR System details note i NR Display text u R Uniform Resource Identifier 3 NR Materials specified 5 NR Institution to which field applies 6 NR Linkage 8 R Field link and sequence number 540 R TERMS GOVERNING USE AND REPRODUCTION NOTE ind1 blank Undefined ind2 blank Undefined a NR Terms governing use and reproduction b NR Jurisdiction c NR Authorization d NR Authorized users u R Uniform Resource Identifier 3 NR Materials specified 5 NR Institution to which field applies 6 NR Linkage 8 R Field link and sequence number 541 R IMMEDIATE SOURCE OF ACQUISITION NOTE ind1 b01 Undefined ind2 blank Undefined a NR Source of acquisition b NR Address c NR Method of acquisition d NR Date of acquisition e NR Accession number f NR Owner h NR Purchase price n R Extent o R Type of unit 3 NR Materials specified 5 NR Institution to which field applies 6 NR Linkage 8 R Field link and sequence number 542 R INFORMATION RELATING TO COPYRIGHT STATUS ind1 b01 Relationship ind2 blank Undefined a NR Personal creator b NR Personal creator death date c NR Corporate creator d R Copyright holder e R Copyright holder contact information f R Copyright statement g NR Copyright date h R Copyright renewal date i NR Publication date j NR Creation date k R Publisher l NR Copyright status m NR Publication status n R Note o NR Research date q NR Assigning agency r NR Jurisdiction of copyright assessment s NR Source of information u R Uniform Resource Identifier 3 NR Materials specified 6 NR Linkage 8 R Field link and sequence number 544 R LOCATION OF OTHER ARCHIVAL MATERIALS NOTE ind1 b01 Relationship ind2 blank Undefined a R Custodian b R Address c R Country d R Title e R Provenance n R Note 3 NR Materials specified 6 NR Linkage 8 R Field link and sequence number 545 R BIOGRAPHICAL OR HISTORICAL DATA ind1 b01 Type of data ind2 blank Undefined a NR Biographical or historical note b NR Expansion u R Uniform Resource Identifier 6 NR Linkage 8 R Field link and sequence number 546 R LANGUAGE NOTE ind1 blank Undefined ind2 blank Undefined a NR Language note b R Information code or alphabet 3 NR Materials specified 6 NR Linkage 8 R Field link and sequence number 547 R FORMER TITLE COMPLEXITY NOTE ind1 blank Undefined ind2 blank Undefined a NR Former title complexity note 6 NR Linkage 8 R Field link and sequence number 550 R ISSUING BODY NOTE ind1 blank Undefined ind2 blank Undefined a NR Issuing body note 6 NR Linkage 8 R Field link and sequence number 552 R ENTITY AND ATTRIBUTE INFORMATION NOTE ind1 blank Undefined ind2 blank Undefined a NR Entity type label b NR Entity type definition and source c NR Attribute label d NR Attribute definition and source e R Enumerated domain value f R Enumerated domain value definition and source g NR Range domain minimum and maximum h NR Codeset name and source i NR Unrepresentable domain j NR Attribute units of measurement and resolution k NR Beginning date and ending date of attribute values l NR Attribute value accuracy m NR Attribute value accuracy explanation n NR Attribute measurement frequency o R Entity and attribute overview p R Entity and attribute detail citation u R Uniform Resource Identifier z R Display note 6 NR Linkage 8 R Field link and sequence number 555 R CUMULATIVE INDEX/FINDING AIDS NOTE ind1 b08 Display constant controller ind2 blank Undefined a NR Cumulative index/finding aids note b R Availability source c NR Degree of control d NR Bibliographic reference u R Uniform Resource Identifier 3 NR Materials specified 6 NR Linkage 8 R Field link and sequence number 556 R INFORMATION ABOUT DOCUMENTATION NOTE ind1 b8 Display constant controller ind2 blank Undefined a NR Information about documentation note z R International Standard Book Number 6 NR Linkage 8 R Field link and sequence number 561 R OWNERSHIP AND CUSTODIAL HISTORY ind1 b01 Undefined ind2 blank Undefined a NR History u R Uniform Resource Identifier 3 NR Materials specified 5 NR Institution to which field applies 6 NR Linkage 8 R Field link and sequence number 562 R COPY AND VERSION IDENTIFICATION NOTE ind1 blank Undefined ind2 blank Undefined a R Identifying markings b R Copy identification c R Version identification d R Presentation format e R Number of copies 3 NR Materials specified 5 NR Institution to which field applies 6 NR Linkage 8 R Field link and sequence number 563 R BINDING INFORMATION ind1 blank Undefined ind2 blank Undefined a NR Binding note u R Uniform Resource Identifier 3 NR Materials specified 5 NR Institution to which field applies 6 NR Linkage 8 R Field link and sequence number 565 R CASE FILE CHARACTERISTICS NOTE ind1 b08 Display constant controller ind2 blank Undefined a NR Number of cases/variables b R Name of variable c R Unit of analysis d R Universe of data e R Filing scheme or code 3 NR Materials specified 6 NR Linkage 8 R Field link and sequence number 567 R METHODOLOGY NOTE ind1 b8 Display constant controller ind2 blank Undefined a NR Methodology note b R Controlled term 0 R Authority record control number or standard number 2 NR Source of term 6 NR Linkage 8 R Field link and sequence number 580 R LINKING ENTRY COMPLEXITY NOTE ind1 blank Undefined ind2 blank Undefined a NR Linking entry complexity note 6 NR Linkage 8 R Field link and sequence number 581 R PUBLICATIONS ABOUT DESCRIBED MATERIALS NOTE ind1 b8 Display constant controller ind2 blank Undefined a NR Publications about described materials note z R International Standard Book Number 3 NR Materials specified 6 NR Linkage 8 R Field link and sequence number 583 R ACTION NOTE ind1 b01 Undefined ind2 blank Undefined a NR Action b R Action identification c R Time/date of action d R Action interval e R Contingency for action f R Authorization h R Jurisdiction i R Method of action j R Site of action k R Action agent l R Status n R Extent o R Type of unit u R Uniform Resource Identifier x R Nonpublic note z R Public note 2 NR Source of term 3 NR Materials specified 5 NR Institution to which field applies 6 NR Linkage 8 R Field link and sequence number 584 R ACCUMULATION AND FREQUENCY OF USE NOTE ind1 blank Undefined ind2 blank Undefined a R Accumulation b R Frequency of use 3 NR Materials specified 5 NR Institution to which field applies 6 NR Linkage 8 R Field link and sequence number 585 R EXHIBITIONS NOTE ind1 blank Undefined ind2 blank Undefined a NR Exhibitions note 3 NR Materials specified 5 NR Institution to which field applies 6 NR Linkage 8 R Field link and sequence number 586 R AWARDS NOTE ind1 b8 Display constant controller ind2 blank Undefined a NR Awards note 3 NR Materials specified 6 NR Linkage 8 R Field link and sequence number 588 R SOURCE OF DESCRIPTION NOTE ind1 b01 Display constant controller ind2 blank Undefined a NR Source of description note 5 NR Institution to which field applies 6 NR Linkage 8 R Field link and sequence number 600 R SUBJECT ADDED ENTRY--PERSONAL NAME ind1 013 Type of personal name entry element ind2 01234567 Thesaurus a NR Personal name b NR Numeration c R Titles and other words associated with a name d NR Dates associated with a name e R Relator term f NR Date of a work g R Miscellaneous information h NR Medium j R Attribution qualifier k R Form subheading l NR Language of a work m R Medium of performance for music n R Number of part/section of a work o NR Arranged statement for music p R Name of part/section of a work q NR Fuller form of name r NR Key for music s NR Version t NR Title of a work u NR Affiliation v R Form subdivision x R General subdivision y R Chronological subdivision z R Geographic subdivision 0 R Authority record control number 2 NR Source of heading or term 3 NR Materials specified 4 R Relationship 6 NR Linkage 8 R Field link and sequence number 610 R SUBJECT ADDED ENTRY--CORPORATE NAME ind1 012 Type of corporate name entry element ind2 01234567 Thesaurus a NR Corporate name or jurisdiction name as entry element b R Subordinate unit c R Location of meeting d R Date of meeting or treaty signing e R Relator term f NR Date of a work g R Miscellaneous information h NR Medium k R Form subheading l NR Language of a work m R Medium of performance for music n R Number of part/section/meeting o NR Arranged statement for music p R Name of part/section of a work r NR Key for music s NR Version t NR Title of a work u NR Affiliation v R Form subdivision x R General subdivision y R Chronological subdivision z R Geographic subdivision 0 R Authority record control number 2 NR Source of heading or term 3 NR Materials specified 4 R Relationship 6 NR Linkage 8 R Field link and sequence number 611 R SUBJECT ADDED ENTRY--MEETING NAME ind1 012 Type of meeting name entry element ind2 01234567 Thesaurus a NR Meeting name or jurisdiction name as entry element c R Location of meeting d NR Date of meeting e R Subordinate unit f NR Date of a work g R Miscellaneous information h NR Medium j R Relator term k R Form subheading l NR Language of a work n R Number of part/section/meeting p R Name of part/section of a work q NR Name of meeting following jurisdiction name entry element s NR Version t NR Title of a work u NR Affiliation v R Form subdivision x R General subdivision y R Chronological subdivision z R Geographic subdivision 0 R Authority record control number 2 NR Source of heading or term 3 NR Materials specified 4 R Relationship 6 NR Linkage 8 R Field link and sequence number 630 R SUBJECT ADDED ENTRY--UNIFORM TITLE ind1 0-9 Nonfiling characters ind2 01234567 Thesaurus a NR Uniform title d R Date of treaty signing e R Relator term f NR Date of a work g R Miscellaneous information h NR Medium k R Form subheading l NR Language of a work m R Medium of performance for music n R Number of part/section of a work o NR Arranged statement for music p R Name of part/section of a work r NR Key for music s NR Version t NR Title of a work v R Form subdivision x R General subdivision y R Chronological subdivision z R Geographic subdivision 0 R Authority record control number 2 NR Source of heading or term 3 NR Materials specified 4 R Relationship 6 NR Linkage 8 R Field link and sequence number 647 R SUBJECT ADDED ENTRY--NAMED EVENT ind1 blank Undefined ind2 01234567 Thesaurus a NR Named event c R Location of named event d NR Date of named event g R Miscellaneous information v R Form subdivision x R General subdivision y R Chronological subdivision z R Geographic subdivision 0 R Authority record control number or standard number 2 NR Source of heading or term 3 NR Materials specified 6 NR Linkage 8 R Field link and sequence number 648 R SUBJECT ADDED ENTRY--CHRONOLOGICAL TERM ind1 blank Undefined ind2 01234567 Thesaurus a NR Chronological term v R Form subdivision x R General subdivision y R Chronological subdivision z R Geographic subdivision 0 R Authority record control number 2 NR Source of heading or term 3 NR Materials specified 6 NR Linkage 8 R Field link and sequence number 650 R SUBJECT ADDED ENTRY--TOPICAL TERM ind1 b012 Level of subject ind2 01234567 Thesaurus a NR Topical term or geographic name as entry element b NR Topical term following geographic name as entry element c NR Location of event d NR Active dates e NR Relator term v R Form subdivision x R General subdivision y R Chronological subdivision z R Geographic subdivision 0 R Authority record control number 2 NR Source of heading or term 3 NR Materials specified 4 R Relationship 6 NR Linkage 8 R Field link and sequence number 651 R SUBJECT ADDED ENTRY--GEOGRAPHIC NAME ind1 blank Undefined ind2 01234567 Thesaurus a NR Geographic name e R Relator term v R Form subdivision x R General subdivision y R Chronological subdivision z R Geographic subdivision 0 R Authority record control number 2 NR Source of heading or term 3 NR Materials specified 4 R Relationship 6 NR Linkage 8 R Field link and sequence number 653 R INDEX TERM--UNCONTROLLED ind1 b012 Level of index term ind2 b0123456 Type of term or name a R Uncontrolled term 6 NR Linkage 8 R Field link and sequence number 654 R SUBJECT ADDED ENTRY--FACETED TOPICAL TERMS ind1 b012 Level of subject ind2 blank Undefined a R Focus term b R Non-focus term c R Facet/hierarchy designation e R Relator term v R Form subdivision y R Chronological subdivision z R Geographic subdivision 0 R Authority record control number 2 NR Source of heading or term 3 NR Materials specified 4 R Relationship 6 NR Linkage 8 R Field link and sequence number 655 R INDEX TERM--GENRE/FORM ind1 b0 Type of heading ind2 01234567 Thesaurus a NR Genre/form data or focus term b R Non-focus term c R Facet/hierarchy designation v R Form subdivision x R General subdivision y R Chronological subdivision z R Geographic subdivision 0 R Authority record control number 2 NR Source of term 3 NR Materials specified 5 NR Institution to which field applies 6 NR Linkage 8 R Field link and sequence number 656 R INDEX TERM--OCCUPATION ind1 blank Undefined ind2 7 Source of term a NR Occupation k NR Form v R Form subdivision x R General subdivision y R Chronological subdivision z R Geographic subdivision 0 R Authority record control number 2 NR Source of term 3 NR Materials specified 6 NR Linkage 8 R Field link and sequence number 657 R INDEX TERM--FUNCTION ind1 blank Undefined ind2 7 Source of term a NR Function v R Form subdivision x R General subdivision y R Chronological subdivision z R Geographic subdivision 0 R Authority record control number 2 NR Source of term 3 NR Materials specified 6 NR Linkage 8 R Field link and sequence number 658 R INDEX TERM--CURRICULUM OBJECTIVE ind1 blank Undefined ind2 blank Undefined a NR Main curriculum objective b R Subordinate curriculum objective c NR Curriculum code d NR Correlation factor 2 NR Source of term or code 6 NR Linkage 8 R Field link and sequence number 662 R SUBJECT ADDED ENTRY--HIERARCHICAL PLACE NAME ind1 blank Undefined ind2 blank Undefined a R Country or larger entity b NR First-order political jurisdiction c R Intermediate political jurisdiction d NR City e R Relator term f R City subsection g R Other nonjurisdictional geographic region and feature h R Extraterrestrial area 0 R Authority record control number 2 NR Source of heading or term 4 R Relationship 6 NR Linkage 8 R Field link and sequence number 700 R ADDED ENTRY--PERSONAL NAME ind1 013 Type of personal name entry element ind2 b2 Type of added entry a NR Personal name b NR Numeration c R Titles and other words associated with a name d NR Dates associated with a name e R Relator term f NR Date of a work g R Miscellaneous information h NR Medium i R Relationship information j R Attribution qualifier k R Form subheading l NR Language of a work m R Medium of performance for music n R Number of part/section of a work o NR Arranged statement for music p R Name of part/section of a work q NR Fuller form of name r NR Key for music s NR Version t NR Title of a work u NR Affiliation x NR International Standard Serial Number 0 R Authority record control number 3 NR Materials specified 4 R Relationship 5 NR Institution to which field applies 6 NR Linkage 8 R Field link and sequence number 710 R ADDED ENTRY--CORPORATE NAME ind1 012 Type of corporate name entry element ind2 b2 Type of added entry a NR Corporate name or jurisdiction name as entry element b R Subordinate unit c R Location of meeting d R Date of meeting or treaty signing e R Relator term f NR Date of a work g R Miscellaneous information h NR Medium i R Relationship information k R Form subheading l NR Language of a work m R Medium of performance for music n R Number of part/section/meeting o NR Arranged statement for music p R Name of part/section of a work r NR Key for music s NR Version t NR Title of a work u NR Affiliation x NR International Standard Serial Number 0 R Authority record control number 3 NR Materials specified 4 R Relationship 5 NR Institution to which field applies 6 NR Linkage 8 R Field link and sequence number 711 R ADDED ENTRY--MEETING NAME ind1 012 Type of meeting name entry element ind2 b2 Type of added entry a NR Meeting name or jurisdiction name as entry element c R Location of meeting d NR Date of meeting e R Subordinate unit f NR Date of a work g R Miscellaneous information h NR Medium i R Relationship information j R Relator term k R Form subheading l NR Language of a work n R Number of part/section/meeting p R Name of part/section of a work q NR Name of meeting following jurisdiction name entry element s NR Version t NR Title of a work u NR Affiliation x NR International Standard Serial Number 0 R Authority record control number 3 NR Materials specified 4 R Relationship 5 NR Institution to which field applies 6 NR Linkage 8 R Field link and sequence number 720 R ADDED ENTRY--UNCONTROLLED NAME ind1 b12 Type of name ind2 blank Undefined a NR Name e R Relator term 4 R Relationship 6 NR Linkage 8 R Field link and sequence number 730 R ADDED ENTRY--UNIFORM TITLE ind1 0-9 Nonfiling characters ind2 b2 Type of added entry a NR Uniform title d R Date of treaty signing f NR Date of a work g R Miscellaneous information h NR Medium i R Relationship information k R Form subheading l NR Language of a work m R Medium of performance for music n R Number of part/section of a work o NR Arranged statement for music p R Name of part/section of a work r NR Key for music s NR Version t NR Title of a work x NR International Standard Serial Number 0 R Authority record control number 3 NR Materials specified 5 NR Institution to which field applies 6 NR Linkage 8 R Field link and sequence number 740 R ADDED ENTRY--UNCONTROLLED RELATED/ANALYTICAL TITLE ind1 0-9 Nonfiling characters ind2 b2 Type of added entry a NR Uncontrolled related/analytical title h NR Medium n R Number of part/section of a work p R Name of part/section of a work 5 NR Institution to which field applies 6 NR Linkage 8 R Field link and sequence number 751 R ADDED ENTRY--GEOGRAPHIC NAME ind1 blank Undefined ind2 blank Undefined a NR Geographic name e R Relator term 0 R Authority record control number 2 NR Source of heading or term 3 NR Materials specified 4 R Relationship 6 NR Linkage 8 R Field link and sequence number 752 R ADDED ENTRY--HIERARCHICAL PLACE NAME ind1 blank Undefined ind2 blank Undefined a NR Country or larger entity b NR First-order political jurisdiction c NR Intermediate political jurisdiction d NR City e R Relator term f R City subsection g R Other nonjurisdictional geographic region and feature h R Extraterrestrial area 0 R Authority record control number 2 NR Source of heading or term 4 R Relationship 6 NR Linkage 8 R Field link and sequence number 753 R SYSTEM DETAILS ACCESS TO COMPUTER FILES ind1 blank Undefined ind2 blank Undefined a NR Make and model of machine b NR Programming language c NR Operating system 0 R Authority record control number or standard number 2 NR Source of term 6 NR Linkage 8 R Field link and sequence number 754 R ADDED ENTRY--TAXONOMIC IDENTIFICATION ind1 blank Undefined ind2 blank Undefined a R Taxonomic name c R Taxonomic category d R Common or alternative name x R Non-public note z R Public note 0 R Authority record control number 2 NR Source of taxonomic identification 6 NR Linkage 8 R Field link and sequence number 760 R MAIN SERIES ENTRY ind1 01 Note controller ind2 b8 Display constant controller a NR Main entry heading b NR Edition c NR Qualifying information d NR Place, publisher, and date of publication g R Related parts h NR Physical description i R Relationship information m NR Material-specific details n R Note o R Other item identifier s NR Uniform title t NR Title w R Record control number x NR International Standard Serial Number y NR CODEN designation 4 R Relationship 6 NR Linkage 7 NR Control subfield 8 R Field link and sequence number 762 R SUBSERIES ENTRY ind1 01 Note controller ind2 b8 Display constant controller a NR Main entry heading b NR Edition c NR Qualifying information d NR Place, publisher, and date of publication g R Related parts h NR Physical description i R Relationship information m NR Material-specific details n R Note o R Other item identifier s NR Uniform title t NR Title w R Record control number x NR International Standard Serial Number y NR CODEN designation 4 R Relationship 6 NR Linkage 7 NR Control subfield 8 R Field link and sequence number 765 R ORIGINAL LANGUAGE ENTRY ind1 01 Note controller ind2 b8 Display constant controller a NR Main entry heading b NR Edition c NR Qualifying information d NR Place, publisher, and date of publication g R Related parts h NR Physical description i R Relationship information k R Series data for related item m NR Material-specific details n R Note o R Other item identifier r R Report number s NR Uniform title t NR Title u NR Standard Technical Report Number w R Record control number x NR International Standard Serial Number y NR CODEN designation z R International Standard Book Number 4 R Relationship 6 NR Linkage 7 NR Control subfield 8 R Field link and sequence number 767 R TRANSLATION ENTRY ind1 01 Note controller ind2 b8 Display constant controller a NR Main entry heading b NR Edition c NR Qualifying information d NR Place, publisher, and date of publication g R Related parts h NR Physical description i R Relationship information k R Series data for related item m NR Material-specific details n R Note o R Other item identifier r R Report number s NR Uniform title t NR Title u NR Standard Technical Report Number w R Record control number x NR International Standard Serial Number y NR CODEN designation z R International Standard Book Number 4 R Relationship 6 NR Linkage 7 NR Control subfield 8 R Field link and sequence number 770 R SUPPLEMENT/SPECIAL ISSUE ENTRY ind1 01 Note controller ind2 b8 Display constant controller a NR Main entry heading b NR Edition c NR Qualifying information d NR Place, publisher, and date of publication g R Related parts h NR Physical description i R Relationship information k R Series data for related item m NR Material-specific details n R Note o R Other item identifier r R Report number s NR Uniform title t NR Title u NR Standard Technical Report Number w R Record control number x NR International Standard Serial Number y NR CODEN designation z R International Standard Book Number 4 R Relationship 6 NR Linkage 7 NR Control subfield 8 R Field link and sequence number 772 R SUPPLEMENT PARENT ENTRY ind1 01 Note controller ind2 b08 Display constant controller a NR Main entry heading b NR Edition c NR Qualifying information d NR Place, publisher, and date of publication g R Related parts h NR Physical description i R Relationship information k R Series data for related item m NR Material-specific details n R Note o R Other item identifier r R Report number s NR Uniform title t NR Title u NR Standard Technical Report Number w R Record control number x NR International Standard Serial Number y NR CODEN designation z R International Stan dard Book Number 4 R Relationship 6 NR Linkage 7 NR Control subfield 8 R Field link and sequence number 773 R HOST ITEM ENTRY ind1 01 Note controller ind2 b8 Display constant controller a NR Main entry heading b NR Edition d NR Place, publisher, and date of publication g R Related parts h NR Physical description i R Relationship information k R Series data for related item m NR Material-specific details n R Note o R Other item identifier p NR Abbreviated title q NR Enumeration and first page r R Report number s NR Uniform title t NR Title u NR Standard Technical Report Number w R Record control number x NR International Standard Serial Number y NR CODEN designation z R International Standard Book Number 3 NR Materials specified 4 R Relationship 6 NR Linkage 7 NR Control subfield 8 R Field link and sequence number 774 R CONSTITUENT UNIT ENTRY ind1 01 Note controller ind2 b8 Display constant controller a NR Main entry heading b NR Edition c NR Qualifying information d NR Place, publisher, and date of publication g R Related parts h NR Physical description i R Relationship information k R Series data for related item m NR Material-specific details n R Note o R Other item identifier r R Report number s NR Uniform title t NR Title u NR Standard Technical Report Number w R Record control number x NR International Standard Serial Number y NR CODEN designation z R International Standard Book Number 4 R Relationship 6 NR Linkage 7 NR Control subfield 8 R Field link and sequence number 775 R OTHER EDITION ENTRY ind1 01 Note controller ind2 b8 Display constant controller a NR Main entry heading b NR Edition c NR Qualifying information d NR Place, publisher, and date of publication e NR Language code f NR Country code g R Related parts h NR Physical description i R Relationship information k R Series data for related item m NR Material-specific details n R Note o R Other item identifier r R Report number s NR Uniform title t NR Title u NR Standard Technical Report Number w R Record control number x NR International Standard Serial Number y NR CODEN designation z R International Standard Book Number 4 R Relationship 6 NR Linkage 7 NR Control subfield 8 R Field link and sequence number 776 R ADDITIONAL PHYSICAL FORM ENTRY ind1 01 Note controller ind2 b8 Display constant controller a NR Main entry heading b NR Edition c NR Qualifying information d NR Place, publisher, and date of publication g R Related parts h NR Physical description i R Relationship information k R Series data for related item m NR Material-specific details n R Note o R Other item identifier r R Report number s NR Uniform title t NR Title u NR Standard Technical Report Number w R Record control number x NR International Standard Serial Number y NR CODEN designation z R International Standard Book Number 4 R Relationship 6 NR Linkage 7 NR Control subfield 8 R Field link and sequence number 777 R ISSUED WITH ENTRY ind1 01 Note controller ind2 b8 Display constant controller a NR Main entry heading b NR Edition c NR Qualifying information d NR Place, publisher, and date of publication g R Related parts h NR Physical description i R Relationship information k R Series data for related item m NR Material-specific details n R Note o R Other item identifier s NR Uniform title t NR Title w R Record control number x NR International Standard Serial Number y NR CODEN designation 4 R Relationship 6 NR Linkage 7 NR Control subfield 8 R Field link and sequence number 780 R PRECEDING ENTRY ind1 01 Note controller ind2 01234567 Type of relationship a NR Main entry heading b NR Edition c NR Qualifying information d NR Place, publisher, and date of publication g R Related parts h NR Physical description i R Relationship information k R Series data for related item m NR Material-specific details n R Note o R Other item identifier r R Report number s NR Uniform title t NR Title u NR Standard Technical Report Number w R Record control number x NR International Standard Serial Number y NR CODEN designation z R International Standard Book Number 4 R Relationship 6 NR Linkage 7 NR Control subfield 8 R Field link and sequence number 785 R SUCCEEDING ENTRY ind1 01 Note controller ind2 012345678 Type of relationship a NR Main entry heading b NR Edition c NR Qualifying information d NR Place, publisher, and date of publication g R Related parts h NR Physical description i R Relationship information k R Series data for related item m NR Material-specific details n R Note o R Other item identifier r R Report number s NR Uniform title t NR Title u NR Standa rd Technical Report Number w R Record control number x NR International Standard Serial Number y NR CODEN designation z R International Standard Book Number 4 R Relationship 6 NR Linkage 7 NR Control subfield 8 R Field link and sequence number 786 R DATA SOURCE ENTRY ind1 01 Note controller ind2 b8 Display constant controller a NR Main entry heading b NR Edition c NR Qualifying information d NR Place, publisher, and date of publication g R Related parts h NR Physical description i R Relationship information j NR Period of content k R Series data for related item m NR Material-specific details n R Note o R Other item identifier p NR Abbreviated title r R Report number s NR Uniform title t NR Title u NR Standard Technical Report Number v NR Source Contribution w R Record control number x NR International Standard Serial Number y NR CODEN designation z R International Standard Book Number 4 R Relationship 6 NR Linkage 7 NR Control subfield 8 R Field link and sequence number 787 R OTHER RELATIONSHIP ENTRY ind1 01 Note controller ind2 b8 Display constant controller a NR Main entry heading b NR Edition c NR Qualifying information d NR Place, publisher, and date of publication g R Related parts h NR Physical description i R Relationship information k R Series data for related item m NR Material-specific details n R Note o R Other item identifier r R Report number s NR Uniform title t NR Title u NR Standard Technical Report Number w R Record control number x NR International Standard Serial Number y NR CODEN designation z R International Standard Book Number 4 R Relationship 6 NR Linkage 7 NR Control subfield 8 R Field link and sequence number 800 R SERIES ADDED ENTRY--PERSONAL NAME ind1 013 Type of personal name entry element ind2 blank Undefined a NR Personal name b NR Numeration c R Titles and other words associated with a name d NR Dates associated with a name e R Relator term f NR Date of a work g R Miscellaneous information h NR Medium j R Attribution qualifier k R Form subheading l NR Language of a work m R Medium of performance for music n R Number of part/section of a work o NR Arranged statement for music p R Name of part/section of a work q NR Fuller form of name r NR Key for music s NR Version t NR Title of a work u NR Affiliation v NR Volume/sequential designation w R Bibliographic record control number x NR International Standard Serial Number 0 R Authority record control number 3 NR Materials specified 4 R Relationship 5 R Institution to which field applies 6 NR Linkage 7 NR Control subfield 8 R Field link and sequence number 810 R SERIES ADDED ENTRY--CORPORATE NAME ind1 012 Type of corporate name entry element ind2 blank Undefined a NR Corporate name or jurisdiction name as entry element b R Subordinate unit c R Location of meeting d R Date of meeting or treaty signing e R Relator term f NR Date of a work g R Miscellaneous information h NR Medium k R Form subheading l NR Language of a work m R Medium of performance for music n R Number of part/section/meeting o NR Arranged statement for music p R Name of part/section of a work r NR Key for music s NR Version t NR Title of a work u NR Affiliation v NR Volume/sequential designation w R Bibliographic record control number x NR International Standard Serial Number 0 R Authority record control number 3 NR Materials specified 4 R Relationship 5 R Institution to which field applies 6 NR Linkage 7 NR Control subfield 8 R Field link and sequence number 811 R SERIES ADDED ENTRY--MEETING NAME ind1 012 Type of meeting name entry element ind2 blank Undefined a NR Meeting name or jurisdiction name as entry element c R Location of meeting d NR Date of meeting e R Subordinate unit f NR Date of a work g R Miscellaneous information h NR Medium j R Relator term k R Form subheading l NR Language of a work n R Number of part/section/meeting p R Name of part/section of a work q NR Name of meeting following jurisdiction name entry element s NR Version t NR Title of a work u NR Affiliation v NR Volume/sequential designation w R Bibliographic record control number x NR International Standard Serial Number 0 R Authority record control number 3 NR Materials specified 4 R Relationship 5 R Institution to which field applies 6 NR Linkage 7 NR Control subfield 8 R Field link and sequence number 830 R SERIES ADDED ENTRY--UNIFORM TITLE ind1 blank Undefined ind2 0-9 Nonfiling characters a NR Uniform title d R Date of treaty signing f NR Date of a work g R Miscellaneous information h NR Medium k R Form subheading l NR Language of a work m R Medium of performance for music n R Number of part/section of a work o NR Arranged statement for music p R Name of part/section of a work r NR Key for music s NR Version t NR Title of a work v NR Volume/sequential designation w R Bibliographic record control number x NR International Standard Serial Number 0 R Authority record control number 3 NR Materials specified 5 R Institution to which field applies 6 NR Linkage 7 NR Control subfield 8 R Field link and sequence number 841 NR HOLDINGS CODED DATA VALUES 842 NR TEXTUAL PHYSICAL FORM DESIGNATOR 843 R REPRODUCTION NOTE 844 NR NAME OF UNIT 845 R TERMS GOVERNING USE AND REPRODUCTION NOTE 850 R HOLDING INSTITUTION ind1 blank Undefined ind2 blank Undefined a R Holding institution 8 R Field link and sequence number 852 R LOCATION ind1 b012345678 Shelving scheme ind2 b012 Shelving order a NR Location b R Sublocation or collection c R Shelving location d R Former shelving location e R Address f R Coded location qualifier g R Non-coded location qualifier h NR Classification part i R Item part j NR Shelving control number k R Call number prefix l NR Shelving form of title m R Call number suffix n NR Country code p NR Piece designation q NR Piece physical condition s R Copyright article-fee code t NR Copy number u R Uniform Resource Identifier x R Nonpublic note z R Public note 2 NR Source of classification or shelving scheme 3 NR Materials specified 6 NR Linkage 8 NR Sequence number 853 R CAPTIONS AND PATTERN--BASIC BIBLIOGRAPHIC UNIT 854 R CAPTIONS AND PATTERN--SUPPLEMENTARY MATERIAL 855 R CAPTIONS AND PATTERN--INDEXES 856 R ELECTRONIC LOCATION AND ACCESS ind1 b012347 Access method ind2 b0128 Relationship a R Host name b R Access number c R Compression information d R Path f R Electronic name h NR Processor of request i R Instruction j NR Bits per second k NR Password l NR Logon m R Contact for access assistance n NR Name of location of host o NR Operating system p NR Port q NR Electronic format type r NR Settings s R File size t R Terminal emulation u R Uniform Resource Identifier v R Hours access method available w R Record control number x R Nonpublic note y R Link text z R Public note 2 NR Access method 3 NR Materials specified 6 NR Linkage 8 R Field link and sequence number 863 R ENUMERATION AND CHRONOLOGY--BASIC BIBLIOGRAPHIC UNIT 864 R ENUMERATION AND CHRONOLOGY--SUPPLEMENTARY MATERIAL 865 R ENUMERATION AND CHRONOLOGY--INDEXES 866 R TEXTUAL HOLDINGS--BASIC BIBLIOGRAPHIC UNIT 867 R TEXTUAL HOLDINGS--SUPPLEMENTARY MATERIAL 868 R TEXTUAL HOLDINGS--INDEXES 876 R ITEM INFORMATION--BASIC BIBLIOGRAPHIC UNIT 877 R ITEM INFORMATION--SUPPLEMENTARY MATERIAL 878 R ITEM INFORMATION--INDEXES 880 R ALTERNATE GRAPHIC REPRESENTATION ind1 Same as associated field ind2 Same as associated field 6 NR Linkage 882 NR REPLACEMENT RECORD INFORMATION ind1 blank Undefined ind2 blank Undefined a R Replacement title i R Explanatory text w R Replacement bibliographic record control number 6 NR Linkage 8 R Field link and sequence number 883 R MACHINE-GENERATED METADATA PROVENANCE ind1 b01 Type of field ind2 blank Undefined a NR Generation process c NR Confidence value d NR Generation date q NR Generation agency x NR Validity end date u NR Uniform Resource Identifier w R Bibliographic record control number 0 R Authority record control number or standard number 8 R Field link and sequence number 884 R DESCRIPTION CONVERSION INFORMATION ind1 blank Undefined ind2 blank Undefined a NR Conversion process g NR Conversion date k NR Identifier of source metadata q NR Conversion agency u R Uniform Resource Identifier 885 R MATCHING INFORMATION ind1 blank Undefined ind2 blank Undefined a NR Matching information b NR Status of matching and its checking c NR Confidence value d NR Generation date w R Record control number x R Nonpublic note z R Public note 0 R Authority record control number or standard number 2 NR Source 5 R Institution to which field applies 886 R FOREIGN MARC INFORMATION FIELD ind1 012 Type of field ind2 blank Undefined a NR Tag of the foreign MARC field b NR Content of the foreign MARC field c-z NR Foreign MARC subfield 0-1 NR Foreign MARC subfield 2 NR Source of data 4 NR Source of data 3-9 NR Source of data 887 R NON-MARC INFORMATION FIELD ind1 blank Undefined ind2 blank Undefined a NR Content of non-MARC field 2 NR Source of data RULES; // @codingStandardsIgnoreEnd } // }}} } // }}} PK�����u]RA;��A;����File/MARC/Data_Field.phpnu�[��������<?php /* vim: set expandtab shiftwidth=4 tabstop=4 softtabstop=4 foldmethod=marker: */ /** * Parser for MARC records * * This package is based on the PHP MARC package, originally called "php-marc", * that is part of the Emilda Project (http://www.emilda.org). Christoffer * Landtman generously agreed to make the "php-marc" code available under the * GNU LGPL so it could be used as the basis of this PEAR package. * * PHP version 5 * * LICENSE: This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * @category File_Formats * @package File_MARC * @author Christoffer Landtman <landtman@realnode.com> * @author Dan Scott <dscott@laurentian.ca> * @copyright 2003-2008 Oy Realnode Ab, Dan Scott * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 * @version CVS: $Id$ * @link http://pear.php.net/package/File_MARC */ // {{{ class File_MARC_Data_Field extends File_MARC_Field /** * The File_MARC_Data_Field class represents a single field in a MARC record. * * A MARC data field consists of a tag name, two indicators which may be null, * and zero or more subfields represented by {@link File_MARC_Subfield} objects. * Subfields are held within a linked list structure. * * @category File_Formats * @package File_MARC * @author Christoffer Landtman <landtman@realnode.com> * @author Dan Scott <dscott@laurentian.ca> * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 * @link http://pear.php.net/package/File_MARC */ class File_MARC_Data_Field extends File_MARC_Field { // {{{ properties /** * Value of the first indicator * @var string */ protected $ind1; /** * Value of the second indicator * @var string */ protected $ind2; /** * Linked list of subfields * @var File_MARC_List */ protected $subfields; // }}} // {{{ Constructor: function __construct() /** * {@link File_MARC_Data_Field} constructor * * Create a new {@link File_MARC_Data_Field} object. The only required * parameter is a tag. This enables programs to build up new fields * programmatically. * * <code> * // Example: Create a new data field * * // We can optionally create an array of subfields first * $subfields[] = new File_MARC_Subfield('a', 'Scott, Daniel.'); * * // Create the new 100 field complete with a _a subfield and an indicator * $new_field = new File_MARC_Data_Field('100', $subfields, 0, null); * </code> * * @param string $tag tag * @param array $subfields array of {@link File_MARC_Subfield} objects * @param string $ind1 first indicator * @param string $ind2 second indicator */ function __construct($tag, array $subfields = null, $ind1 = null, $ind2 = null) { $this->subfields = new File_MARC_List(); parent::__construct($tag); $this->ind1 = $this->_validateIndicator($ind1); $this->ind2 = $this->_validateIndicator($ind2); // we'll let users add subfields after if they so desire if ($subfields) { $this->addSubfields($subfields); } } // }}} // {{{ Destructor: function __destruct() /** * Destroys the data field */ function __destruct() { $this->subfields = null; $this->ind1 = null; $this->ind2 = null; parent::__destruct(); } // }}} // {{{ Explicit destructor: function delete() /** * Destroys the data field * * @return true */ function delete() { $this->__destruct(); } // }}} // {{{ protected function _validateIndicator() /** * Validates an indicator field * * Validates the value passed in for an indicator. This routine ensures * that an indicator is a single character. If the indicator value is null, * then this method returns a single character. * * If the indicator value contains more than a single character, this * throws an exception. * * @param string $indicator Value of the indicator to be validated * * @return string Returns the indicator, or space if the indicator was null */ private function _validateIndicator($indicator) { if ($indicator == null) { $indicator = ' '; } elseif (strlen($indicator) > 1) { $errorMessage = File_MARC_Exception::formatError(File_MARC_Exception::$messages[File_MARC_Exception::ERROR_INVALID_INDICATOR], array("tag" => $this->getTag(), "indicator" => $indicator)); throw new File_MARC_Exception($errorMessage, File_MARC_Exception::ERROR_INVALID_INDICATOR); } return $indicator; } // }}} // {{{ appendSubfield() /** * Appends subfield to subfield list * * Adds a File_MARC_Subfield object to the end of the existing list * of subfields. * * @param File_MARC_Subfield $new_subfield The subfield to add * * @return File_MARC_Subfield the new File_MARC_Subfield object */ function appendSubfield(File_MARC_Subfield $new_subfield) { /* Append as the last subfield in the field */ $this->subfields->appendNode($new_subfield); } // }}} // {{{ prependSubfield() /** * Prepends subfield to subfield list * * Adds a File_MARC_Subfield object to the start of the existing list * of subfields. * * @param File_MARC_Subfield $new_subfield The subfield to add * * @return File_MARC_Subfield the new File_MARC_Subfield object */ function prependSubfield(File_MARC_Subfield $new_subfield) { $this->subfields->unshift($new_subfield); return $new_subfield; } // }}} // {{{ insertSubfield() /** * Inserts a field in the MARC record relative to an existing field * * Inserts a {@link File_MARC_Subfield} object before or after an existing * subfield. * * @param File_MARC_Subfield $new_field The subfield to add * @param File_MARC_Subfield $existing_field The target subfield * @param bool $before Insert the subfield before the existing subfield if true; after the existing subfield if false * * @return File_MARC_Subfield The new subfield */ function insertSubfield(File_MARC_Subfield $new_field, File_MARC_Subfield $existing_field, $before = false) { $this->subfields->insertNode($new_field, $existing_field, $before); return $new_field; } // }}} // {{{ addSubfields() /** * Adds an array of subfields to a {@link File_MARC_Data_Field} object * * Appends subfields to existing subfields in the order in which * they appear in the array. For finer grained control of the subfield * order, use {@link appendSubfield()}, {@link prependSubfield()}, * or {@link insertSubfield()} to add each subfield individually. * * @param array $subfields array of {@link File_MARC_Subfield} objects * * @return int returns the number of subfields that were added */ function addSubfields(array $subfields) { /* * Just in case someone passes in a single File_MARC_Subfield * instead of an array */ if ($subfields instanceof File_MARC_Subfield) { $this->appendSubfield($subfields); return 1; } // Add subfields $cnt = 0; foreach ($subfields as $subfield) { $this->appendSubfield($subfield); $cnt++; } return $cnt; } // }}} // {{{ deleteSubfield() /** * Delete a subfield from the field. * * @param File_MARC_Subfield $subfield The subfield to delete * * @return void */ function deleteSubfield(File_MARC_Subfield $subfield) { $this->subfields->deleteNode($subfield); } // }}} // {{{ getIndicator() /** * Get the value of an indicator * * @param int $ind number of the indicator (1 or 2) * * @return string returns indicator value if it exists, otherwise false */ function getIndicator($ind) { if ($ind == 1) { return (string)$this->ind1; } elseif ($ind == 2) { return (string)$this->ind2; } else { $errorMessage = File_MARC_Exception::formatError(File_MARC_Exception::$messages[File_MARC_Exception::ERROR_INVALID_INDICATOR_REQUEST], array("indicator" => $indicator)); throw new File_MARC_Exception($errorMessage, File_MARC_Exception::ERROR_INVALID_INDICATOR_REQUEST); } return false; } // }}} // {{{ setIndicator() /** * Set the value of an indicator * * @param int $ind number of the indicator (1 or 2) * @param string $value value of the indicator * * @return string returns indicator value if it exists, otherwise false */ function setIndicator($ind, $value) { switch ($ind) { case 1: $this->ind1 = $this->_validateIndicator($value); break; case 2: $this->ind2 = $this->_validateIndicator($value); break; default: $errorMessage = File_MARC_Exception::formatError(File_MARC_Exception::$messages[File_MARC_Exception::ERROR_INVALID_INDICATOR_REQUEST], array("indicator" => $ind)); throw new File_MARC_Exception($errorMessage, File_MARC_Exception::ERROR_INVALID_INDICATOR_REQUEST); return false; } return $this->getIndicator($ind); } // }}} // {{{ getSubfield() /** * Returns the first subfield that matches a requested code. * * @param string $code subfield code for which the * {@link File_MARC_Subfield} is retrieved * @param bool $pcre if true, then match as a regular expression * * @return File_MARC_Subfield returns the first subfield that matches * $code, or false if no codes match $code */ function getSubfield($code = null, $pcre = null) { // iterate merrily through the subfields looking for the requested code foreach ($this->subfields as $sf) { if (($pcre && preg_match("/$code/", $sf->getCode())) || (!$pcre && $code == $sf->getCode()) ) { return $sf; } } // No matches were found return false; } // }}} // {{{ getSubfields() /** * Returns an array of subfields that match a requested code, * or a {@link File_MARC_List} that contains all of the subfields * if the requested code is null. * * @param string $code subfield code for which the * {@link File_MARC_Subfield} is retrieved * @param bool $pcre if true, then match as a regular expression * * @return File_MARC_List|array returns a linked list of all subfields * if $code is null, an array of {@link File_MARC_Subfield} objects if * one or more subfields match, or an empty array if no codes match $code */ function getSubfields($code = null, $pcre = null) { $results = array(); // return all subfields if no specific subfields were requested if ($code === null) { $results = $this->subfields; return $results; } // iterate merrily through the subfields looking for the requested code foreach ($this->subfields as $sf) { if (($pcre && preg_match("/$code/", $sf->getCode())) || (!$pcre && $code == $sf->getCode()) ) { $results[] = $sf; } } return $results; } // }}} // {{{ isEmpty() /** * Checks if the field is empty. * * Checks if the field is empty. If the field has at least one subfield * with data, it is not empty. * * @return bool Returns true if the field is empty, otherwise false */ function isEmpty() { // If $this->subfields is null, we must have deleted it if (!$this->subfields) { return true; } // Iterate through the subfields looking for some data foreach ($this->subfields as $subfield) { // Check if subfield has data if (!$subfield->isEmpty()) { return false; } } // It is empty return true; } // }}} /** * ========== OUTPUT METHODS ========== */ // {{{ __toString() /** * Return Field formatted * * Return Field as a formatted string. * * @return string Formatted output of Field */ function __toString() { // Variables $lines = array(); // Process tag and indicators $pre = sprintf("%3s %1s%1s", $this->tag, $this->ind1, $this->ind2); // Process subfields foreach ($this->subfields as $subfield) { $lines[] = sprintf("%6s _%1s%s", $pre, $subfield->getCode(), $subfield->getData()); $pre = ""; } return join("\n", $lines); } // }}} // {{{ toRaw() /** * Return Field in Raw MARC * * Return the Field formatted in Raw MARC for saving into MARC files * * @return string Raw MARC */ function toRaw() { $subfields = array(); foreach ($this->subfields as $subfield) { if (!$subfield->isEmpty()) { $subfields[] = $subfield->toRaw(); } } return (string)$this->ind1.$this->ind2.implode("", $subfields).File_MARC::END_OF_FIELD; } // }}} // {{{ getContents() /** * Return fields data content as joined string * * Return all the fields data content as a joined string * * @param string $joinChar A string used to join the data conntent. * Default is an empty string * * @return string Joined string */ function getContents($joinChar = '') { $contents = array(); foreach($this->subfields as $subfield) { $contents[] = $subfield->getData(); } return implode($joinChar, $contents); } // }}} } // }}} PK�����u]7*c������File/MARC/Subfield.phpnu�[��������<?php /* vim: set expandtab shiftwidth=4 tabstop=4 softtabstop=4 foldmethod=marker: */ /** * Parser for MARC records * * This package is based on the PHP MARC package, originally called "php-marc", * that is part of the Emilda Project (http://www.emilda.org). Christoffer * Landtman generously agreed to make the "php-marc" code available under the * GNU LGPL so it could be used as the basis of this PEAR package. * * PHP version 5 * * LICENSE: This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * @category File_Formats * @package File_MARC * @author Christoffer Landtman <landtman@realnode.com> * @author Dan Scott <dscott@laurentian.ca> * @copyright 2003-2008 Oy Realnode Ab, Dan Scott * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 * @version CVS: $Id$ * @link http://pear.php.net/package/File_MARC */ // {{{ class File_MARC_Subfield /** * The File_MARC_Subfield class represents a single subfield in a MARC * record field. * * Represents a subfield within a MARC field and implements all management * functions related to a single subfield. This class also implements * the possibility of duplicate subfields within a single field, for example * 650 _z Test1 _z Test2. * * @category File_Formats * @package File_MARC * @author Christoffer Landtman <landtman@realnode.com> * @author Dan Scott <dscott@laurentian.ca> * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 * @link http://pear.php.net/package/File_MARC */ class File_MARC_Subfield { // {{{ properties /** * Subfield code, e.g. _a, _b * @var string */ protected $code; /** * Data contained by the subfield * @var string */ protected $data; /** * Position of the subfield * @var int */ protected $position; // }}} // {{{ Constructor: function __construct() /** * File_MARC_Subfield constructor * * Create a new subfield to represent the code and data * * @param string $code Subfield code * @param string $data Subfield data */ function __construct($code, $data) { $this->code = $code; $this->data = $data; } // }}} // {{{ Destructor: function __destruct() /** * Destroys the subfield */ function __destruct() { $this->code = null; $this->data = null; $this->position = null; } // }}} // {{{ Explicit destructor: function delete() /** * Destroys the subfield * * @return true */ function delete() { $this->__destruct(); } // }}} // {{{ getCode() /** * Return code of the subfield * * @return string Tag name */ function getCode() { return (string)$this->code; } // }}} // {{{ getData() /** * Return data of the subfield * * @return string data */ function getData() { return (string)$this->data; } // }}} // {{{ getPosition() /** * Return position of the subfield * * @return int data */ function getPosition() { return $this->position; } // }}} // {{{ __toString() /** * Return string representation of subfield * * @return string String representation */ public function __toString() { $pretty = '[' . $this->getCode() . ']: ' . $this->getData(); return $pretty; } // }}} // {{{ toRaw() /** * Return the USMARC representation of the subfield * * @return string USMARC representation */ function toRaw() { $result = File_MARC::SUBFIELD_INDICATOR.$this->code.$this->data; return (string)$result; } // }}} // {{{ setCode() /** * Sets code of the subfield * * @param string $code new code for the subfield * * @return string code */ function setCode($code) { if ($code) { // could check more stringently; m/[a-Z]/ or the likes $this->code = $code; } else { // code must be _something_; raise error return false; } return true; } // }}} // {{{ setData() /** * Sets data of the subfield * * @param string $data new data for the subfield * * @return string data */ function setData($data) { $this->data = $data; return true; } // }}} // {{{ setPosition() /** * Sets position of the subfield * * @param string $pos new position of the subfield * * @return void */ function setPosition($pos) { $this->position = $pos; } // }}} // {{{ isEmpty() /** * Checks whether the subfield is empty or not * * @return bool True or false */ function isEmpty() { // There is data if (strlen($this->data)) { return false; } // There is no data return true; } // }}} } // }}} PK�����u]IC(A��(A����File/MARC/Lint/CodeData.phpnu�[��������<?php /* vim: set expandtab shiftwidth=4 tabstop=4 softtabstop=4 foldmethod=marker: */ /** * Code Data to support Lint for MARC records * * This module is adapted from the MARC::Lint::CodeData CPAN module for Perl, * maintained by Bryan Baldus <eijabb@cpan.org> and available for download at * http://search.cpan.org/~eijabb/ * * Current MARC::Lint::CodeData version used as basis for this module: 1.37 * * PHP version 5 * * LICENSE: This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * @category File_Formats * @package File_MARC * @author Demian Katz <demian.katz@villanova.edu> * @author Dan Scott <dscott@laurentian.ca> * @copyright 2003-2019 Oy Realnode Ab, Dan Scott * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 * @version CVS: $Id: Record.php 308146 2011-02-08 20:36:20Z dbs $ * @link http://pear.php.net/package/File_MARC */ // {{{ class File_MARC_Lint /** * Contains codes from the MARC code lists for Geographic Areas, Languages, and * Countries. * * Code data is used for validating fields 008, 040, 041, and 043. * * Also, sources for subfield 2 in 600-651 and 655. * * Note: According to the official MARC documentation, Sears is not a valid 655 * term. The code data below treats it as valid, in anticipation of a change in * the official documentation. * * @category File_Formats * @package File_MARC * @author Demian Katz <demian.katz@villanova.edu> * @author Dan Scott <dscott@laurentian.ca> * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 * @link http://pear.php.net/package/File_MARC */ class File_MARC_Lint_CodeData { // {{{ properties /** * Valid Geographic Area Codes * @var array */ public $geogAreaCodes; /** * Obsolete Geographic Area Codes * @var array */ public $obsoleteGeogAreaCodes; /** * Valid Language Codes * @var array */ public $languageCodes; /** * Obsolete Language Codes * @var array */ public $obsoleteLanguageCodes; /** * Valid Country Codes * @var array */ public $countryCodes; /** * Obsolete Country Codes * @var array */ public $obsoleteCountryCodes; /** * Valid sources for fields 600-651 * @var array */ public $sources600_651; /** * Obsolete sources for fields 600-651 * @var array */ public $obsoleteSources600_651; /** * Valid sources for field 655 * @var array */ public $sources655; /** * Obsolete sources for field 655 * @var array */ public $obsoleteSources655; // }}} // {{{ Constructor: function __construct() /** * Start function * * Initialize code arrays. * * @return true */ public function __construct() { // @codingStandardsIgnoreStart // fill the valid Geographic Area Codes array $this->geogAreaCodes = explode("\t", "a------ a-af--- a-ai--- a-aj--- a-ba--- a-bg--- a-bn--- a-br--- a-bt--- a-bx--- a-cb--- a-cc--- a-cc-an a-cc-ch a-cc-cq a-cc-fu a-cc-ha a-cc-he a-cc-hh a-cc-hk a-cc-ho a-cc-hp a-cc-hu a-cc-im a-cc-ka a-cc-kc a-cc-ki a-cc-kn a-cc-kr a-cc-ku a-cc-kw a-cc-lp a-cc-mh a-cc-nn a-cc-pe a-cc-sh a-cc-sm a-cc-sp a-cc-ss a-cc-su a-cc-sz a-cc-ti a-cc-tn a-cc-ts a-cc-yu a-ccg-- a-cck-- a-ccp-- a-ccs-- a-ccy-- a-ce--- a-ch--- a-cy--- a-em--- a-gs--- a-ii--- a-io--- a-iq--- a-ir--- a-is--- a-ja--- a-jo--- a-kg--- a-kn--- a-ko--- a-kr--- a-ku--- a-kz--- a-le--- a-ls--- a-mk--- a-mp--- a-my--- a-np--- a-nw--- a-ph--- a-pk--- a-pp--- a-qa--- a-si--- a-su--- a-sy--- a-ta--- a-th--- a-tk--- a-ts--- a-tu--- a-uz--- a-vt--- a-ye--- aa----- ab----- ac----- ae----- af----- ag----- ah----- ai----- ak----- am----- an----- ao----- aopf--- aoxp--- ap----- ar----- as----- at----- au----- aw----- awba--- awgz--- ay----- az----- b------ c------ cc----- cl----- d------ dd----- e------ e-aa--- e-an--- e-au--- e-be--- e-bn--- e-bu--- e-bw--- e-ci--- e-cs--- e-dk--- e-er--- e-fi--- e-fr--- e-ge--- e-gi--- e-gr--- e-gw--- e-gx--- e-hu--- e-ic--- e-ie--- e-it--- e-kv--- e-lh--- e-li--- e-lu--- e-lv--- e-mc--- e-mm--- e-mo--- e-mv--- e-ne--- e-no--- e-pl--- e-po--- e-rb--- e-rm--- e-ru--- e-sm--- e-sp--- e-sw--- e-sz--- e-uk--- e-uk-en e-uk-ni e-uk-st e-uk-ui e-uk-wl e-un--- e-ur--- e-urc-- e-ure-- e-urf-- e-urk-- e-urn-- e-urp-- e-urr-- e-urs-- e-uru-- e-urw-- e-vc--- e-xn--- e-xo--- e-xr--- e-xv--- e-yu--- ea----- eb----- ec----- ed----- ee----- el----- en----- eo----- ep----- er----- es----- ev----- ew----- f------ f-ae--- f-ao--- f-bd--- f-bs--- f-cd--- f-cf--- f-cg--- f-cm--- f-cx--- f-dm--- f-ea--- f-eg--- f-et--- f-ft--- f-gh--- f-gm--- f-go--- f-gv--- f-iv--- f-ke--- f-lb--- f-lo--- f-ly--- f-mg--- f-ml--- f-mr--- f-mu--- f-mw--- f-mz--- f-ng--- f-nr--- f-pg--- f-rh--- f-rw--- f-sa--- f-sd--- f-sf--- f-sg--- f-sh--- f-sj--- f-sl--- f-so--- f-sq--- f-ss--- f-sx--- f-tg--- f-ti--- f-tz--- f-ua--- f-ug--- f-uv--- f-za--- fa----- fb----- fc----- fd----- fe----- ff----- fg----- fh----- fi----- fl----- fn----- fq----- fr----- fs----- fu----- fv----- fw----- fz----- h------ i------ i-bi--- i-cq--- i-fs--- i-hm--- i-mf--- i-my--- i-re--- i-se--- i-xa--- i-xb--- i-xc--- i-xo--- l------ ln----- lnaz--- lnbm--- lnca--- lncv--- lnfa--- lnjn--- lnma--- lnsb--- ls----- lsai--- lsbv--- lsfk--- lstd--- lsxj--- lsxs--- m------ ma----- mb----- me----- mm----- mr----- n------ n-cn--- n-cn-ab n-cn-bc n-cn-mb n-cn-nf n-cn-nk n-cn-ns n-cn-nt n-cn-nu n-cn-on n-cn-pi n-cn-qu n-cn-sn n-cn-yk n-cnh-- n-cnm-- n-cnp-- n-gl--- n-mx--- n-us--- n-us-ak n-us-al n-us-ar n-us-az n-us-ca n-us-co n-us-ct n-us-dc n-us-de n-us-fl n-us-ga n-us-hi n-us-ia n-us-id n-us-il n-us-in n-us-ks n-us-ky n-us-la n-us-ma n-us-md n-us-me n-us-mi n-us-mn n-us-mo n-us-ms n-us-mt n-us-nb n-us-nc n-us-nd n-us-nh n-us-nj n-us-nm n-us-nv n-us-ny n-us-oh n-us-ok n-us-or n-us-pa n-us-ri n-us-sc n-us-sd n-us-tn n-us-tx n-us-ut n-us-va n-us-vt n-us-wa n-us-wi n-us-wv n-us-wy n-usa-- n-usc-- n-use-- n-usl-- n-usm-- n-usn-- n-uso-- n-usp-- n-usr-- n-uss-- n-ust-- n-usu-- n-xl--- nc----- ncbh--- nccr--- nccz--- nces--- ncgt--- ncho--- ncnq--- ncpn--- nl----- nm----- np----- nr----- nw----- nwaq--- nwaw--- nwbb--- nwbf--- nwbn--- nwcj--- nwco--- nwcu--- nwdq--- nwdr--- nweu--- nwgd--- nwgp--- nwhi--- nwht--- nwjm--- nwla--- nwli--- nwmj--- nwmq--- nwna--- nwpr--- nwsc--- nwsd--- nwsn--- nwst--- nwsv--- nwtc--- nwtr--- nwuc--- nwvb--- nwvi--- nwwi--- nwxa--- nwxi--- nwxk--- nwxm--- p------ pn----- po----- poas--- pobp--- poci--- pocw--- poea--- pofj--- pofp--- pogg--- pogu--- poji--- pokb--- poki--- poln--- pome--- pomi--- ponl--- ponn--- ponu--- popc--- popl--- pops--- posh--- potl--- poto--- pott--- potv--- poup--- powf--- powk--- pows--- poxd--- poxe--- poxf--- poxh--- ps----- q------ r------ s------ s-ag--- s-bl--- s-bo--- s-ck--- s-cl--- s-ec--- s-fg--- s-gy--- s-pe--- s-py--- s-sr--- s-uy--- s-ve--- sa----- sn----- sp----- t------ u------ u-ac--- u-at--- u-at-ac u-at-ne u-at-no u-at-qn u-at-sa u-at-tm u-at-vi u-at-we u-atc-- u-ate-- u-atn-- u-cs--- u-nz--- w------ x------ xa----- xb----- xc----- xd----- zd----- zju---- zma---- zme---- zmo---- zne---- zo----- zpl---- zs----- zsa---- zsu---- zur---- zve----"); // fill the obsolete Geographic Area Codes array $this->obsoleteGeogAreaCodes = explode("\t", "t-ay--- e-ur-ai e-ur-aj nwbc--- e-ur-bw f-by--- pocp--- e-url-- cr----- v------ e-ur-er et----- e-ur-gs pogn--- nwga--- nwgs--- a-hk--- ei----- f-if--- awiy--- awiw--- awiu--- e-ur-kz e-ur-kg e-ur-lv e-ur-li a-mh--- cm----- e-ur-mv n-usw-- a-ok--- a-pt--- e-ur-ru pory--- nwsb--- posc--- a-sk--- posn--- e-uro-- e-ur-ta e-ur-tk e-ur-un e-ur-uz a-vn--- a-vs--- nwvr--- e-urv-- a-ys---"); // fill the valid Language Codes array $this->languageCodes = explode("\t", " aar abk ace ach ada ady afa afh afr ain aka akk alb ale alg alt amh ang anp apa ara arc arg arm arn arp art arw asm ast ath aus ava ave awa aym aze bad bai bak bal bam ban baq bas bat bej bel bem ben ber bho bih bik bin bis bla bnt bos bra bre btk bua bug bul bur byn cad cai car cat cau ceb cel cha chb che chg chi chk chm chn cho chp chr chu chv chy cmc cop cor cos cpe cpf cpp cre crh crp csb cus cze dak dan dar day del den dgr din div doi dra dsb dua dum dut dyu dzo efi egy eka elx eng enm epo est ewe ewo fan fao fat fij fil fin fiu fon fre frm fro frr frs fry ful fur gaa gay gba gem geo ger gez gil gla gle glg glv gmh goh gon gor got grb grc gre grn gsw guj gwi hai hat hau haw heb her hil him hin hit hmn hmo hrv hsb hun hup iba ibo ice ido iii ijo iku ile ilo ina inc ind ine inh ipk ira iro ita jav jbo jpn jpr jrb kaa kab kac kal kam kan kar kas kau kaw kaz kbd kha khi khm kho kik kin kir kmb kok kom kon kor kos kpe krc krl kro kru kua kum kur kut lad lah lam lao lat lav lez lim lin lit lol loz ltz lua lub lug lui lun luo lus mac mad mag mah mai mak mal man mao map mar mas may mdf mdr men mga mic min mis mkh mlg mlt mnc mni mno moh mon mos mul mun mus mwl mwr myn myv nah nai nap nau nav nbl nde ndo nds nep new nia nic niu nno nob nog non nor nqo nso nub nwc nya nym nyn nyo nzi oci oji ori orm osa oss ota oto paa pag pal pam pan pap pau peo per phi phn pli pol pon por pra pro pus que raj rap rar roa roh rom rum run rup rus sad sag sah sai sal sam san sas sat scn sco sel sem sga sgn shn sid sin sio sit sla slo slv sma sme smi smj smn smo sms sna snd snk sog som son sot spa srd srn srp srr ssa ssw suk sun sus sux swa swe syc syr tah tai tam tat tel tem ter tet tgk tgl tha tib tig tir tiv tkl tlh tli tmh tog ton tpi tsi tsn tso tuk tum tup tur tut tvl twi tyv udm uga uig ukr umb und urd uzb vai ven vie vol vot wak wal war was wel wen wln wol xal xho yao yap yid yor ypk zap zbl zen zha znd zul zun zxx zza"); // fill the obsolete Language Codes array $this->obsoleteLanguageCodes = explode("\t", "ajm esk esp eth far fri gag gua int iri cam kus mla max mol lan gal lap sao gae scc scr sho snh sso swz tag taj tar tru tsw"); // fill the valid Country Codes array $this->countryCodes = explode("\t", "aa abc aca ae af ag ai aj aku alu am an ao aq aru as at au aw ay azu ba bb bcc bd be bf bg bh bi bl bm bn bo bp br bs bt bu bv bw bx ca cau cb cc cd ce cf cg ch ci cj ck cl cm co cou cq cr ctu cu cv cw cx cy dcu deu dk dm dq dr ea ec eg em enk er es et fa fg fi fj fk flu fm fp fr fs ft gau gb gd gh gi gl gm go gp gr gs gt gu gv gw gy gz hiu hm ho ht hu iau ic idu ie ii ilu inu io iq ir is it iv iy ja ji jm jo ke kg kn ko ksu ku kv kyu kz lau lb le lh li lo ls lu lv ly mau mbc mc mdu meu mf mg miu mj mk ml mm mnu mo mou mp mq mr msu mtu mu mv mw mx my mz na nbu ncu ndu ne nfc ng nhu nik nju nkc nl nmu nn no np nq nr nsc ntc nu nuc nvu nw nx nyu nz ohu oku onc oru ot pau pc pe pf pg ph pic pk pl pn po pp pr pw py qa qea quc rb re rh riu rm ru rw sa sc scu sd sdu se sf sg sh si sj sl sm sn snc so sp sq sr ss st stk su sw sx sy sz ta tc tg th ti tk tl tma tnu to tr ts tu tv txu tz ua uc ug uik un up utu uv uy uz vau vb vc ve vi vm vp vra vtu wau wea wf wiu wj wk wlk ws wvu wyu xa xb xc xd xe xf xga xh xj xk xl xm xn xna xo xoa xp xr xra xs xv xx xxc xxk xxu ye ykc za "); // fill the obsolete Country Codes array $this->obsoleteCountryCodes = explode("\t", "ai air ac ajr bwr cn cz cp ln cs err gsr ge gn hk iw iu jn kzr kgr lvr lir mh mvr nm pt rur ry xi sk xxr sb sv tar tt tkr unr uk ui us uzr vn vs wb ys yu "); // the codes cash, lcsh, lcshac, mesh, nal, and rvm are covered by 2nd // indicators in 600-655 // they are only used when indicators are not available $this->sources600_651 = explode("\t", "aass aat abne aedoml afo afset agrifors agrovoc agrovocf agrovocs aiatsisl aiatsisp aiatsiss aktp albt allars apaist armac asft ashlnl asrcrfcd asrcseo asrctoa asth ated atg atla aucsh bare barn bhb bella bet bhammf bhashe bib1814 bibalex biccbmc bicssc bidex bisacsh bisacmt bisacrt bjornson blcpss blmlsh blnpn bokbas bt btr cabt cash cbk cck ccsa cct ccte cctf cdcng ceeus chirosh cht ciesiniv cilla collett conorsi csahssa csalsct csapa csh csht cstud czenas czmesh dacs dbn dcs ddcri ddcrit ddcut dissao dit dltlt dltt drama dtict ebfem eclas eet eflch eks embiaecid embne emnmus ept erfemn ericd est eum eurovocen eurovocfr eurovocsl fast fes finmesh fire fmesh fnhl francis fssh galestne gccst gcipmedia gcipplatform gem gemet georeft gnd gnis gst gtt hamsun hapi hkcan helecon henn hlasstg hoidokki hrvmesh huc humord iaat ibsen ica icpsr idas idsbb idszbz idszbzes idszbzna idszbzzg idszbzzh idszbzzk iescs iest ilot ilpt inist inspect ipat ipsp isis itglit itoamc itrt jhpb jhpk jlabsh juho jupo jurivoc kaa kaba kao kassu kauno kaunokki kdm khib kito kitu kkts koko kssbar kta kto ktpt ktta kubikat kula kulo kupu lacnaf lapponica larpcal lcac lcdgt lcmpt lcsh lcshac lcstt lctgm lemac lemb liito liv lnmmbr local ltcsh lua maaq maotao mar masa mech mero mesh mipfesd mmm mpirdes msc msh mtirdes musa muso muzeukc muzeukn muzvukci naf nal nalnaf nasat nbdbt nbiemnfag ncjt ndlsh netc ndllsh nicem nimacsc nlgaf nlgkk nlgsh nlmnaf no-ubo-mr noraf noram norbok normesh noubomn noubojur nsbncf nskps ntcpsc ntcsd ntids ntissc nzggn nznb odlt ogst onet opms ordnok pascal pepp peri pha pkk pleiades pmbok pmcsg pmont pmt poliscit popinte precis prvt psychit puho quiding qlsp qrma qrmak qtglit raam ram rasuqam renib reo rero rerovoc rma rpe rswk rswkaf rugeo rurkp rvm rvmgd samisk sanb sao sbiao sbt scbi scgdst scisshl scot sears sfit sgc sgce shbe she shsples sigle sipri sk skon slem smda snt socio solstad sosa spines ssg sthus stw swd swemesh taika tasmas taxhs tbit tbjvp tekord tero tesa tesbhaecid test tgn tha thema thesoz thia tho thub tips tisa tlka tlsh toit trfarn trfbmb trfgr trfoba trfzb trt trtsa tsht tsr ttka ttll tucua udc ukslc ulan umitrist unbisn unbist unescot usaidt valo vcaadu vffyl vmj waqaf watrest wgst wot wpicsh ysa yso"); $this->obsoleteSources600_651 = explode("\t", "cash lcsh lcshac mesh nal nobomn noubojor reroa rvm"); $this->sources655 = explode("\t", "aat afset aiatsisl aiatsisp aiatsiss aktp alett amg asrcrfcd asrcseo asrctoa asth aucsh barn barngf bib1814 bibalex biccbmc bidex bgtchm bisacsh bisacmt bisacrt bjornson bt cash chirosh cct cdcng cjh collett conorsi csht czenas dacs dcs dct ddcut eet eflch embne emnmus ept erfemn ericd estc eurovocen eurovocsl fast fbg fgtpcm finmesh fire ftamc galestne gatbeg gem gmd gmgpc gnd gsafd gst gtlm hamsun hapi hkcan hoidokki ica ilot isbdcontent isbdmedia itglit itrt jhpb jhpk kkts lacnaf lcgft lcmpt lcsh lcshac lcstt lctgm lemac lobt local maaq mar marccategory marcform marcgt marcsmd mech mesh migfg mim msh muzeukc muzeukn muzeukv muzvukci nal nalnaf nbdbgf nbiemnfag ndlsh netc ngl nimafc nlgaf nlgkk nlgsh nlmnaf nmc no-ubo-mr noraf noram nsbncf ntids nzcoh nzggn nznb onet opms ordnok pkk pmcsg pmt proysen quiding qlsp qrmak qtglit raam radfg rasuqam rbbin rbgenr rbmscv rbpap rbpri rbprov rbpub rbtyp rdabf rdabs rdacarrier rdaco rdacontent rdacpc rdact rdafnm rdafs rdaft rdagen rdagrp rdagw rdalay rdamat rdamedia rdamt rdapf rdapm rdapo rdarm rdarr rdaspc rdatc rdatr rdavf reo rerovoc reveal rma rswk rswkaf rugeo rvm rvmgf sao saogf scbi sears sgc sgce sgp sipri skon snt socio spines ssg stw swd swemesh tbit thema tesa tgfbne thesoz tho thub toit tsht tucua ukslc ulan vgmsgg vgmsng vmj waqaf"); $this->obsoleteSources655 = explode("\t", "cash ftamc lcsh lcshac marccarrier marccontent marcmedia mesh nal reroa rvm"); // @codingStandardsIgnoreEnd } // }}} } // }}} PK�����u]9g4xU��xU����File/MARC/Record.phpnu�[��������<?php /* vim: set expandtab shiftwidth=4 tabstop=4 softtabstop=4 foldmethod=marker: */ /** * Parser for MARC records * * This package is based on the PHP MARC package, originally called "php-marc", * that is part of the Emilda Project (http://www.emilda.org). Christoffer * Landtman generously agreed to make the "php-marc" code available under the * GNU LGPL so it could be used as the basis of this PEAR package. * * PHP version 5 * * LICENSE: This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * @category File_Formats * @package File_MARC * @author Christoffer Landtman <landtman@realnode.com> * @author Dan Scott <dscott@laurentian.ca> * @copyright 2003-2008 Oy Realnode Ab, Dan Scott * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 * @version CVS: $Id$ * @link http://pear.php.net/package/File_MARC */ // {{{ class File_MARC_Record /** * Represents a single MARC record * * A MARC record contains a leader and zero or more fields held within a * linked list structure. Fields are represented by {@link File_MARC_Data_Field} * objects. * * @category File_Formats * @package File_MARC * @author Christoffer Landtman <landtman@realnode.com> * @author Dan Scott <dscott@laurentian.ca> * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 * @link http://pear.php.net/package/File_MARC */ class File_MARC_Record { // {{{ properties /** * Contains a linked list of {@link File_MARC_Data_Field} objects for * this record * @var File_MARC_List */ protected $fields; /** * Record leader * @var string */ protected $leader; /** * Non-fatal warnings generated during parsing * @var array */ protected $warnings; /** * XMLWriter for writing collections * * @var XMLWriter */ protected $marcxml; /** * MARC instance for access to the XML header/footer methods * We need this so that we can properly wrap a collection of MARC records. * * @var File_MARC */ protected $marc; // }}} // {{{ Constructor: function __construct() /** * Start function * * Set all variables to defaults to create new File_MARC_Record object * * @param File_MARC $marc MARC record from File_MARC or File_MARCXML * * @return true */ function __construct($marc = null) { $this->fields = new File_MARC_List(); $this->setLeader(str_repeat(' ', 24)); if (!$marc) { $marc = new File_MARC(null, File_MARC::SOURCE_STRING); // oh the hack } $this->marc = $marc; $this->marcxml = $marc->getXMLWriter(); } // }}} // {{{ Destructor: function __destruct() /** * Destroys the data field */ function __destruct() { $this->fields = null; $this->warnings = null; } // }}} // {{{ getLeader() /** * Get MARC leader * * Returns the leader for the MARC record. No validation * on the specified leader is performed. * * @return string returns the leader */ function getLeader() { return (string)$this->leader; } // }}} // {{{ setLeader() /** * Set MARC record leader * * Sets the leader for the MARC record. No validation * on the specified leader is performed. * * @param string $leader Leader * * @return string returns the leader */ function setLeader($leader) { $this->leader = $leader; return $this->leader; } // }}} // {{{ appendField() /** * Appends field to MARC record * * Adds a {@link File_MARC_Control_Field} or {@link File_MARC_Data_Field} * object to the end of the existing list of fields. * * @param File_MARC_Field $new_field The field to add * * @return File_MARC_Field The field that was added */ function appendField(File_MARC_Field $new_field) { /* Append as the last field in the record */ $this->fields->appendNode($new_field); return $new_field; } // }}} // {{{ prependField() /** * Prepends field to MARC record * * Adds a {@link File_MARC_Control_Field} or {@link File_MARC_Data_Field} * object to the start of to the existing list of fields. * * @param File_MARC_Field $new_field The field to add * * @return File_MARC_Field The field that was added */ function prependField(File_MARC_Field $new_field) { $this->fields->prependNode($new_field); return $new_field; } // }}} // {{{ insertField() /** * Inserts a field in the MARC record relative to an existing field * * Inserts a {@link File_MARC_Control_Field} or {@link File_MARC_Data_Field} * object before or after a specified existing field. * * <code> * // Example: Insert a new field before the first 650 field * * // Create the new field * $subfields[] = new File_MARC_Subfield('a', 'Scott, Daniel.'); * $new_field = new File_MARC_Data_Field('100', $subfields, 0, null); * * // Retrieve the target field for our insertion point * $subject = $record->getFields('650'); * * // Insert the new field * if (is_array($subject)) { * $record->insertField($new_field, $subject[0], true); * } * elseif ($subject) { * $record->insertField($new_field, $subject, true); * } * </code> * * @param File_MARC_Field $new_field The field to add * @param File_MARC_Field $existing_field The target field * @param bool $before Insert the new field before the existing field if true, after the existing field if false * * @return File_MARC_Field The field that was added */ function insertField(File_MARC_Field $new_field, File_MARC_Field $existing_field, $before = false) { $this->fields->insertNode($new_field, $existing_field, $before); return $new_field; } // }}} // {{{ _buildDirectory() /** * Build record directory * * Generate the directory of the record according to the current contents * of the record. * * @return array Array ($fields, $directory, $total, $base_address) */ private function _buildDirectory() { // Vars $fields = array(); $directory = array(); $data_end = 0; foreach ($this->fields as $field) { // No empty fields allowed if (!$field->isEmpty()) { // Get data in raw format $str = $field->toRaw(); $fields[] = $str; // Create directory entry $len = strlen($str); $direntry = sprintf("%03s%04d%05d", $field->getTag(), $len, $data_end); $directory[] = $direntry; $data_end += $len; } } /** * Rules from MARC::Record::USMARC */ $base_address = File_MARC::LEADER_LEN + // better be 24 (count($directory) * File_MARC::DIRECTORY_ENTRY_LEN) + // all the directory entries 1; // end-of-field marker $total = $base_address + // stuff before first field $data_end + // Length of the fields 1; // End-of-record marker return array($fields, $directory, $total, $base_address); } // }}} // {{{ setLeaderLengths() /** * Set MARC record leader lengths * * Set the Leader lengths of the record according to defaults specified in * {@link http://www.loc.gov/marc/bibliographic/ecbdldrd.html} * * @param int $record_length Record length * @param int $base_address Base address of data * * @return bool Success or failure */ function setLeaderLengths($record_length, $base_address) { if (!is_int($record_length)) { return false; } if (!is_int($base_address)) { return false; } // Set record length $this->setLeader(substr_replace($this->getLeader(), sprintf("%05d", $record_length), 0, 5)); $this->setLeader(substr_replace($this->getLeader(), sprintf("%05d", $base_address), File_MARC::DIRECTORY_ENTRY_LEN, 5)); $this->setLeader(substr_replace($this->getLeader(), '22', 10, 2)); $this->setLeader(substr_replace($this->getLeader(), '4500', 20, 4)); if (strlen($this->getLeader()) > File_MARC::LEADER_LEN) { // Avoid incoming leaders that are mangled to be overly long $this->setLeader(substr($this->getLeader(), 0, File_MARC::LEADER_LEN)); $this->addWarning("Input leader was too long; truncated to " . File_MARC::LEADER_LEN . " characters"); } return true; } // }}} // {{{ getField() /** * Return the first {@link File_MARC_Data_Field} or * {@link File_MARC_Control_Field} object that matches the specified tag * name. Returns false if no match is found. * * @param string $spec tag name * @param bool $pcre if true, then match as a regular expression * * @return {@link File_MARC_Data_Field}|{@link File_MARC_Control_Field} first field that matches the requested tag name */ function getField($spec = null, $pcre = null) { foreach ($this->fields as $field) { if (($pcre && preg_match("/$spec/", $field->getTag())) || (!$pcre && $spec == $field->getTag()) ) { return $field; } } return false; } // }}} // {{{ getFields() /** * Return an array or {@link File_MARC_List} containing all * {@link File_MARC_Data_Field} or {@link File_MARC_Control_Field} objects * that match the specified tag name. If the tag name is omitted all * fields are returned. * * @param string $spec tag name * @param bool $pcre if true, then match as a regular expression * * @return File_MARC_List|array {@link File_MARC_Data_Field} or * {@link File_MARC_Control_Field} objects that match the requested tag name */ function getFields($spec = null, $pcre = null) { if (!$spec) { return $this->fields; } // Okay, we're actually looking for something specific $matches = array(); foreach ($this->fields as $field) { if (($pcre && preg_match("/$spec/", $field->getTag())) || (!$pcre && $spec == $field->getTag()) ) { $matches[] = $field; } } return $matches; } // }}} // {{{ deleteFields() /** * Delete all occurrences of a field matching a tag name from the record. * * @param string $tag tag for the fields to be deleted * @param bool $pcre if true, then match as a regular expression * * @return int number of fields that were deleted */ function deleteFields($tag, $pcre = null) { $cnt = 0; foreach ($this->getFields() as $field) { if (($pcre && preg_match("/$tag/", $field->getTag())) || (!$pcre && $tag == $field->getTag()) ) { $field->delete(); $cnt++; } } return $cnt; } // }}} // {{{ addWarning() /** * Add a warning to the MARC record that something non-fatal occurred during * parsing. * * @param string $warning warning message * * @return true */ public function addWarning($warning) { $this->warnings[] = $warning; } // }}} // {{{ getWarnings() /** * Return the array of warnings from the MARC record. * * @return array warning messages */ public function getWarnings() { return $this->warnings; } // }}} // {{{ output methods /** * ========== OUTPUT METHODS ========== */ // {{{ toRaw() /** * Return the record in raw MARC format. * * If you have modified an existing MARC record or created a new MARC * record, use this method to save the record for use in other programs * that accept the MARC format -- for example, your integrated library * system. * * <code> * // Example: Modify a record and save the output to a file * $record->deleteFields('650'); * * // Now that the record has no subject fields, save it to disk * fopen($file, '/home/dan/no_subject.mrc', 'w'); * fwrite($file, $record->toRaw()); * fclose($file); * </code> * * @return string Raw MARC data */ function toRaw() { list($fields, $directory, $record_length, $base_address) = $this->_buildDirectory(); $this->setLeaderLengths($record_length, $base_address); /** * Glue together all parts */ return $this->getLeader().implode("", $directory).File_MARC::END_OF_FIELD.implode("", $fields).File_MARC::END_OF_RECORD; } // }}} // {{{ __toString() /** * Return the MARC record in a pretty printed string * * This method produces an easy-to-read textual display of a MARC record. * * The structure is roughly: * <tag> <ind1> <ind2> _<code><data> * _<code><data> * * @return string Formatted representation of MARC record */ function __toString() { // Begin output $formatted = "LDR " . $this->getLeader() . "\n"; foreach ($this->fields as $field) { if (!$field->isEmpty()) { $formatted .= $field->__toString() . "\n"; } } return $formatted; } // }}} // {{{ toJSON() /** * Return the MARC record in JSON format * * This method produces a JSON representation of a MARC record. The input * encoding must be UTF8, otherwise the returned values will be corrupted. * * @return string representation of MARC record in JSON format * * @todo Fix encoding input / output issues (PHP 6.0 required?) */ function toJSON() { $json = new StdClass(); $json->leader = utf8_encode($this->getLeader()); /* Start fields */ $fields = array(); foreach ($this->fields as $field) { if (!$field->isEmpty()) { switch(get_class($field)) { case "File_MARC_Control_Field": $fields[] = array(utf8_encode($field->getTag()) => utf8_encode($field->getData())); break; case "File_MARC_Data_Field": $subs = array(); foreach ($field->getSubfields() as $sf) { $subs[] = array(utf8_encode($sf->getCode()) => utf8_encode($sf->getData())); } $contents = new StdClass(); $contents->ind1 = utf8_encode($field->getIndicator(1)); $contents->ind2 = utf8_encode($field->getIndicator(2)); $contents->subfields = $subs; $fields[] = array(utf8_encode($field->getTag()) => $contents); break; } } } /* End fields and record */ $json->fields = $fields; $json_rec = json_encode($json); // Required because json_encode() does not let us stringify integer keys return preg_replace('/("subfields":)(.*?)\["([^\"]+?)"\]/', '\1\2{"0":"\3"}', $json_rec); } // }}} // {{{ toJSONHash() /** * Return the MARC record in Bill Dueber's MARC-HASH JSON format * * This method produces a JSON representation of a MARC record as defined * at http://robotlibrarian.billdueber.com/new-interest-in-marc-hash-json/ * The input * encoding must be UTF8, otherwise the returned values will * be corrupted. * * @return string representation of MARC record in JSON format * * @todo Fix encoding input / output issues (PHP 6.0 required?) */ function toJSONHash() { $json = new StdClass(); $json->type = "marc-hash"; $json->version = array(1, 0); $json->leader = utf8_encode($this->getLeader()); /* Start fields */ $fields = array(); foreach ($this->fields as $field) { if (!$field->isEmpty()) { switch(get_class($field)) { case "File_MARC_Control_Field": $fields[] = array(utf8_encode($field->getTag()), utf8_encode($field->getData())); break; case "File_MARC_Data_Field": $subs = array(); foreach ($field->getSubfields() as $sf) { $subs[] = array(utf8_encode($sf->getCode()), utf8_encode($sf->getData())); } $contents = array( utf8_encode($field->getTag()), utf8_encode($field->getIndicator(1)), utf8_encode($field->getIndicator(2)), $subs ); $fields[] = $contents; break; } } } /* End fields and record */ $json->fields = $fields; return json_encode($json); } // }}} // {{{ toXML() /** * Return the MARC record in MARCXML format * * This method produces an XML representation of a MARC record that * attempts to adhere to the MARCXML standard documented at * http://www.loc.gov/standards/marcxml/ * * @param string $encoding output encoding for the MARCXML record * @param bool $indent pretty-print the MARCXML record * @param bool $single wrap the <record> element in a <collection> element * * @return string representation of MARC record in MARCXML format * * @todo Fix encoding input / output issues (PHP 6.0 required?) */ function toXML($encoding = "UTF-8", $indent = true, $single = true) { $this->marcxml->setIndent($indent); if ($single) { $this->marcxml->startElement("collection"); $this->marcxml->writeAttribute("xmlns", "http://www.loc.gov/MARC21/slim"); $this->marcxml->startElement("record"); } else { $this->marcxml->startElement("record"); $this->marcxml->writeAttribute("xmlns", "http://www.loc.gov/MARC21/slim"); } // MARCXML schema has some strict requirements // We'll set reasonable defaults to avoid invalid MARCXML $xmlLeader = $this->getLeader(); // Record status if ($xmlLeader[5] == " ") { // Default to "n" (new record) $xmlLeader[5] = "n"; } // Type of record if ($xmlLeader[6] == " ") { // Default to "a" (language material) $xmlLeader[6] = "a"; } $this->marcxml->writeElement("leader", $xmlLeader); foreach ($this->fields as $field) { if (!$field->isEmpty()) { switch(get_class($field)) { case "File_MARC_Control_Field": $this->marcxml->startElement("controlfield"); $this->marcxml->writeAttribute("tag", $field->getTag()); $this->marcxml->text($field->getData()); $this->marcxml->endElement(); // end control field break; case "File_MARC_Data_Field": $this->marcxml->startElement("datafield"); $this->marcxml->writeAttribute("tag", $field->getTag()); $this->marcxml->writeAttribute("ind1", $field->getIndicator(1)); $this->marcxml->writeAttribute("ind2", $field->getIndicator(2)); foreach ($field->getSubfields() as $subfield) { $this->marcxml->startElement("subfield"); $this->marcxml->writeAttribute("code", $subfield->getCode()); $this->marcxml->text($subfield->getData()); $this->marcxml->endElement(); // end subfield } $this->marcxml->endElement(); // end data field break; } } } $this->marcxml->endElement(); // end record if ($single) { $this->marcxml->endElement(); // end collection $this->marcxml->endDocument(); } return $this->marcxml->outputMemory(); } // }}} } // }}} PK�����u](#~������File/MARC/Exception.phpnu�[��������<?php /* vim: set expandtab shiftwidth=4 tabstop=4 softtabstop=4 foldmethod=marker: */ /** * Parser for MARC records * * This package is based on the PHP MARC package, originally called "php-marc", * that is part of the Emilda Project (http://www.emilda.org). Christoffer * Landtman generously agreed to make the "php-marc" code available under the * GNU LGPL so it could be used as the basis of this PEAR package. * * PHP version 5 * * LICENSE: This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * @category File_Formats * @package File_MARC * @author Christoffer Landtman <landtman@realnode.com> * @author Dan Scott <dscott@laurentian.ca> * @copyright 2003-2008 Oy Realnode Ab, Dan Scott * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 * @version CVS: $Id$ * @link http://pear.php.net/package/File_MARC */ // {{{ class File_MARC_Exception extends PEAR_Exception /** * The File_MARC_Exception class enables error-handling * for the File_MARC package. * * @category File_Formats * @package File_MARC * @author Dan Scott <dscott@laurentian.ca> * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 * @link http://pear.php.net/package/File_MARC */ class File_MARC_Exception extends PEAR_Exception { // {{{ Error codes /** * File could not be opened */ const ERROR_INVALID_FILE = -1; /** * User passed an unknown SOURCE_ constant */ const ERROR_INVALID_SOURCE = -2; /** * MARC record ended with an invalid terminator */ const ERROR_INVALID_TERMINATOR = -3; /** * No directory was found for the MARC record */ const ERROR_NO_DIRECTORY = -4; /** * An entry in the MARC directory was not 12 bytes */ const ERROR_INVALID_DIRECTORY_LENGTH = -5; /** * An entry in the MARC directory specified an invalid tag */ const ERROR_INVALID_DIRECTORY_TAG = -6; /** * An entry in the MARC directory specified an invalid tag length */ const ERROR_INVALID_DIRECTORY_TAG_LENGTH = -7; /** * An entry in the MARC directory specified an invalid field offset */ const ERROR_INVALID_DIRECTORY_OFFSET = -8; /** * An entry in the MARC directory runs past the end of the record */ const ERROR_INVALID_DIRECTORY = -9; /** * A field does not end with the expected end-of-field character */ const ERROR_FIELD_EOF = -10; /** * A field has invalid indicators */ const ERROR_INVALID_INDICATORS = -11; /** * A subfield is defined, but has no data */ const ERROR_EMPTY_SUBFIELD = -12; /** * An indicator other than 1 or 2 was requested */ const ERROR_INVALID_INDICATOR_REQUEST = -13; /** * An invalid mode for adding a field was specified */ const ERROR_INSERTFIELD_MODE = -14; /** * An invalid object was passed instead of a File_MARC_Field object */ const ERROR_INVALID_FIELD = -15; /** * An invalid object was passed instead of a File_MARC_Subfield object */ const ERROR_INVALID_SUBFIELD = -16; /** * An invalid mode for adding a subfield was specified */ const ERROR_INSERTSUBFIELD_MODE = -17; /** * The length in the MARC leader does not match the actual record length */ const ERROR_INCORRECT_LENGTH = -18; /** * The length field in the leader was less than five characters long */ const ERROR_MISSING_LENGTH = -19; /** * A five-digit length could not be found in the MARC leader */ const ERROR_NONNUMERIC_LENGTH = -20; /** * Tag does not adhere to MARC standards */ const ERROR_INVALID_TAG = -21; /** * A field has invalid indicators */ const ERROR_INVALID_INDICATOR = -22; // }}} // {{{ error messages public static $messages = array( self::ERROR_EMPTY_SUBFIELD => 'No subfield data found in tag "%tag%"', self::ERROR_FIELD_EOF => 'Field for tag "%tag%" does not end with an end of field character', self::ERROR_INCORRECT_LENGTH => 'Invalid record length: Leader says "%record_length%" bytes; actual record length is "%actual%"', self::ERROR_INSERTFIELD_MODE => 'insertField() mode "%mode%" was not recognized', self::ERROR_INSERTSUBFIELD_MODE => 'insertSubfield() mode "%mode%" was not recognized', self::ERROR_INVALID_DIRECTORY => 'Directory entry for tag "%tag%" runs past the end of the record', self::ERROR_INVALID_DIRECTORY_LENGTH => 'Invalid directory length', self::ERROR_INVALID_DIRECTORY_OFFSET => 'Invalid offset "%offset%" for tag "%tag%" in directory', self::ERROR_INVALID_DIRECTORY_TAG => 'Invalid tag "%tag%" in directory', self::ERROR_INVALID_DIRECTORY_TAG_LENGTH => 'Invalid length "%len%" in directory for tag "%tag%"', self::ERROR_INVALID_FIELD => 'Specified field must be a File_MARC_Data_Field or File_MARC_Control_Field object, but was "%field%"', self::ERROR_INVALID_FILE => 'Invalid input file "%filename%"', self::ERROR_INVALID_INDICATOR_REQUEST => 'Attempt to access indicator "%indicator%" failed; 1 and 2 are the only valid indicators', self::ERROR_INVALID_INDICATORS => 'Invalid indicators "%indicators%" forced to blanks for tag "%tag%"', self::ERROR_INVALID_SOURCE => "Invalid source for MARC records", self::ERROR_INVALID_SUBFIELD => 'Specified field must be a File_MARC_Subfield object, but was "%class%"', self::ERROR_INVALID_TAG => 'Tag "%tag%" is not a valid tag.', self::ERROR_INVALID_TERMINATOR => 'Invalid record terminator', self::ERROR_MISSING_LENGTH => "Couldn't find record length", self::ERROR_NO_DIRECTORY => 'No directory found', self::ERROR_NONNUMERIC_LENGTH => 'Record length "%record_length%" is not numeric', self::ERROR_INVALID_INDICATOR => 'Illegal indicator "%indicator%" in field "%tag%" forced to blank', ); // }}} // {{{ formatError() /** * Replaces placeholder tokens in an error message with actual values. * * This method enables you to internationalize the messages for the * File_MARC class by simply replacing the File_MARC_Exception::$messages * array with translated values for the messages. * * @param string $message Error message containing placeholders * @param array $errorValues Actual values to substitute for placeholders * * @return string Formatted message */ public static function formatError($message, $errorValues) { foreach ($errorValues as $token => $value) { $message = preg_replace("/\%$token\%/", $value, $message); } return $message; } // }}} } // }}} PK�����u]lz`������File/MARC/Control_Field.phpnu�[��������<?php /* vim: set expandtab shiftwidth=4 tabstop=4 softtabstop=4 foldmethod=marker: */ /** * Parser for MARC records * * This package is based on the PHP MARC package, originally called "php-marc", * that is part of the Emilda Project (http://www.emilda.org). Christoffer * Landtman generously agreed to make the "php-marc" code available under the * GNU LGPL so it could be used as the basis of this PEAR package. * * PHP version 5 * * LICENSE: This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * @category File_Formats * @package File_MARC * @author Christoffer Landtman <landtman@realnode.com> * @author Dan Scott <dscott@laurentian.ca> * @copyright 2003-2008 Oy Realnode Ab, Dan Scott * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 * @version CVS: $Id$ * @link http://pear.php.net/package/File_MARC */ // {{{ class File_MARC_Control_Field extends File_MARC_Field /** * The File_MARC_Control_Field class represents a single control field * in a MARC record. * * A MARC control field consists of a tag name and control data. * * @category File_Formats * @package File_MARC * @author Christoffer Landtman <landtman@realnode.com> * @author Dan Scott <dscott@laurentian.ca> * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 * @link http://pear.php.net/package/File_MARC */ class File_MARC_Control_Field extends File_MARC_Field { // {{{ Properties /** * Value of field, if field is a Control field * @var string */ protected $data; // }}} // {{{ Constructor: function __construct() /** * Field init function * * Create a new {@link File_MARC_Control_Field} object from passed arguments * * @param string $tag tag * @param string $data control field data * @param string $ind1 placeholder for class strictness * @param string $ind2 placeholder for class strictness */ function __construct($tag, $data, $ind1 = null, $ind2 = null) { $this->data = $data; parent::__construct($tag); } // }}} // {{{ Destructor: function __destruct() /** * Destroys the control field */ function __destruct() { $this->data = null; parent::__destruct(); } // }}} // {{{ Explicit destructor: function delete() /** * Destroys the control field * * @return true */ function delete() { $this->__destruct(); } // }}} // {{{ getData() /** * Get control field data * * @return string returns data in control field */ function getData() { return (string)$this->data; } // }}} // {{{ isEmpty() /** * Is empty * * Checks if the field contains data * * @return bool Returns true if the field is empty, otherwise false */ function isEmpty() { return ($this->data) ? false : true; } // }}} // {{{ setData() /** * Set control field data * * @param string $data data for the control field * * @return bool returns the new data in the control field */ function setData($data) { $this->data = $data; return $this->getData(); } // }}} // {{{ __toString() /** * Return as a formatted string * * Return the control field as a formatted string for pretty printing * * @return string Formatted output of control Field */ function __toString() { return sprintf("%3s %s", $this->tag, $this->data); } // }}} // {{{ toRaw() /** * Return as raw MARC * * Return the control field formatted in Raw MARC for saving into MARC files * * @return string Raw MARC */ function toRaw() { return (string)$this->data.File_MARC::END_OF_FIELD; } // }}} } // }}} PK�����u]5F '"��"����File/MARCXML.phpnu�[��������<?php /* vim: set expandtab shiftwidth=4 tabstop=4 softtabstop=4 foldmethod=marker: */ /** * Parser for MARC records * * This package is based on the PHP MARC package, originally called "php-marc", * that is part of the Emilda Project (http://www.emilda.org). Christoffer * Landtman generously agreed to make the "php-marc" code available under the * GNU LGPL so it could be used as the basis of this PEAR package. * * PHP version 5 * * LICENSE: This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * @category File_Formats * @package File_MARC * @author Dan Scott <dscott@laurentian.ca> * @copyright 2007-2010 Dan Scott * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 * @version CVS: $Id$ * @link http://pear.php.net/package/File_MARC * @example read.php Retrieve specific fields and subfields from a record * @example subfields.php Create new subfields and add them in specific order * @example marc_yaz.php Pretty print a MARC record retrieved through the PECL yaz extension */ require_once 'PEAR/Exception.php'; require_once 'File/MARCBASE.php'; require_once 'File/MARC.php'; require_once 'File/MARC/Record.php'; require_once 'File/MARC/Field.php'; require_once 'File/MARC/Control_Field.php'; require_once 'File/MARC/Data_Field.php'; require_once 'File/MARC/Subfield.php'; require_once 'File/MARC/Exception.php'; require_once 'File/MARC/List.php'; // {{{ class File_MARCXML /** * The main File_MARCXML class enables you to return File_MARC_Record * objects from an XML stream or string. * * @category File_Formats * @package File_MARC * @author Dan Scott <dscott@laurentian.ca> * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 * @link http://pear.php.net/package/File_MARC */ class File_MARCXML extends File_MARCBASE { // {{{ constants /** * MARC records retrieved from a file */ const SOURCE_FILE = 1; /** * MARC records retrieved from a binary string */ const SOURCE_STRING = 2; // }}} /** * MARC records retrieved from a SimpleXMLElement object */ const SOURCE_SIMPLEXMLELEMENT = 3; // }}} // {{{ properties /** * Source containing raw records * * @var resource */ protected $source; /** * Source type (SOURCE_FILE or SOURCE_STRING) * * @var int */ protected $type; /** * Counter for MARCXML records in a collection * * @var int */ protected $counter; /** * XMLWriter for writing collections * * @var XMLWriter */ protected $xmlwriter; // }}} // {{{ Constructor: function __construct() /** * Read in MARCXML records * * This function reads in files, strings or SimpleXMLElement objects that * contain one or more MARCXML records. * * <code> * <?php * // Retrieve MARC records from a file * $journals = new File_MARC('journals.mrc', SOURCE_FILE); * * // Retrieve MARC records from a string (e.g. Z39 query results) * $monographs = new File_MARC($raw_marc, SOURCE_STRING); * * // Retrieve MARCXML records from a string with a namespace URL * $records = new File_MARCXML($xml_data, File_MARC::SOURCE_STRING,"http://www.loc.gov/MARC21/slim"); * * // Retrieve MARCXML records from a file with a namespace prefix * $records = new File_MARCXML($xml_data, File_MARC::SOURCE_FILE,"marc",true); * ?> * </code> * * @param string|SimpleXMLElement $source Filename, raw MARC string or SimpleXMLElement object * @param int $type Source of the input, either SOURCE_FILE, SOURCE_STRING or SOURCE_SIMPLEXMLELEMENT * @param string $ns URI or prefix of the namespace * @param bool $is_prefix TRUE if $ns is a prefix, FALSE if it's a URI; defaults to FALSE * @param string $record_class Record class, defaults to File_MARC_Record */ function __construct($source, $type = self::SOURCE_FILE, $ns = "", $is_prefix = false, $record_class = null) { parent::__construct($source, $type, $record_class); $this->counter = 0; if ($source instanceof \SimpleXMLElement) { $type = self::SOURCE_SIMPLEXMLELEMENT; } switch ($type) { case self::SOURCE_SIMPLEXMLELEMENT: $this->type = self::SOURCE_SIMPLEXMLELEMENT; $this->source = $source; break; case self::SOURCE_FILE: $this->type = self::SOURCE_FILE; $this->source = simplexml_load_file($source, "SimpleXMLElement", 0, $ns, $is_prefix); break; case self::SOURCE_STRING: $this->type = self::SOURCE_STRING; $this->source = simplexml_load_string($source, "SimpleXMLElement", 0, $ns, $is_prefix); break; default: throw new File_MARC_Exception(File_MARC_Exception::$messages[File_MARC_Exception::ERROR_INVALID_SOURCE], File_MARC_Exception::ERROR_INVALID_SOURCE); } if (!$this->source) { $errorMessage = File_MARC_Exception::formatError(File_MARC_Exception::$messages[File_MARC_Exception::ERROR_INVALID_FILE], array('filename' => $source)); throw new File_MARC_Exception($errorMessage, File_MARC_Exception::ERROR_INVALID_FILE); } } // }}} // {{{ next() /** * Return next {@link File_MARC_Record} object * * Decodes the next MARCXML record and returns the {@link File_MARC_Record} * object. * <code> * <?php * // Retrieve a set of MARCXML records from a file * $journals = new File_MARCXML('journals.xml', SOURCE_FILE); * * // Iterate through the retrieved records * while ($record = $journals->next()) { * print $record; * print "\n"; * } * * ?> * </code> * * @return File_MARC_Record next record, or false if there are * no more records */ function next() { if (isset($this->source->record[$this->counter])) { $record = $this->source->record[$this->counter++]; } elseif ($this->source->getName() == "record" && $this->counter == 0) { $record = $this->source; $this->counter++; } else { return false; } if ($record) { return $this->_decode($record); } else { return false; } } // }}} // {{{ _decode() /** * Decode a given MARCXML record * * @param string $text MARCXML record element * * @return File_MARC_Record Decoded File_MARC_Record object */ private function _decode($text) { $marc = new $this->record_class($this); // Store leader $marc->setLeader($text->leader); // go through all the control fields foreach ($text->controlfield as $controlfield) { $controlfieldattributes = $controlfield->attributes(); $marc->appendField(new File_MARC_Control_Field((string)$controlfieldattributes['tag'], $controlfield)); } // go through all the data fields foreach ($text->datafield as $datafield) { $datafieldattributes = $datafield->attributes(); $subfield_data = array(); foreach ($datafield->subfield as $subfield) { $subfieldattributes = $subfield->attributes(); $subfield_data[] = new File_MARC_Subfield((string)$subfieldattributes['code'], $subfield); } // If the data is invalid, let's just ignore the one field try { $new_field = new File_MARC_Data_Field((string)$datafieldattributes['tag'], $subfield_data, $datafieldattributes['ind1'], $datafieldattributes['ind2']); $marc->appendField($new_field); } catch (Exception $e) { $marc->addWarning($e->getMessage()); } } return $marc; } // }}} } // }}} PK�����u]/f������File/MARCBASE.phpnu�[��������<?php /* vim: set expandtab shiftwidth=4 tabstop=4 softtabstop=4 foldmethod=marker: */ /** * Parser for MARC records * * This package is based on the PHP MARC package, originally called "php-marc", * that is part of the Emilda Project (http://www.emilda.org). Christoffer * Landtman generously agreed to make the "php-marc" code available under the * GNU LGPL so it could be used as the basis of this PEAR package. * * PHP version 5 * * LICENSE: This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * @category File_Formats * @package File_MARC * @author Dan Scott <dscott@laurentian.ca> * @copyright 2007-2010 Dan Scott * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 * @version CVS: $Id: MARCXML.php 301727 2010-07-30 17:30:51Z dbs $ * @link http://pear.php.net/package/File_MARC * @example read.php Retrieve specific fields and subfields from a record * @example subfields.php Create new subfields and add them in specific order * @example marc_yaz.php Pretty print a MARC record retrieved via yaz extension */ require_once 'File/MARC/Record.php'; // {{{ class File_MARCBASE /** * The main File_MARCBASE class provides common methods for File_MARC and * File_MARCXML - primarily for generating MARCXML output. * * @category File_Formats * @package File_MARC * @author Dan Scott <dscott@laurentian.ca> * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 * @link http://pear.php.net/package/File_MARC */ class File_MARCBASE { /** * XMLWriter for writing collections * * @var XMLWriter */ protected $xmlwriter; /** * Record class * * @var string */ protected $record_class; // }}} // {{{ Constructor: function __construct() /** * Read in MARCXML records * * This function reads in files or strings that * contain one or more MARCXML records. * * <code> * <?php * // Retrieve MARC records from a file * $journals = new File_MARC('journals.mrc', SOURCE_FILE); * * // Retrieve MARC records from a string (e.g. Z39 query results) * $monographs = new File_MARC($raw_marc, SOURCE_STRING); * ?> * </code> * * @param string $source Name of the file, or a raw MARC string * @param int $type Source of the input: SOURCE_FILE or SOURCE_STRING * @param string $record_class Record class, defaults to File_MARC_Record */ function __construct($source, $type, $record_class) { $this->xmlwriter = new XMLWriter(); $this->xmlwriter->openMemory(); $this->xmlwriter->startDocument('1.0', 'UTF-8'); $this->record_class = $record_class ?: File_MARC_Record::class; } // }}} // {{{ toXMLHeader() /** * Initializes the MARCXML output of a record or collection of records * * This method produces an XML representation of a MARC record that * attempts to adhere to the MARCXML standard documented at * http://www.loc.gov/standards/marcxml/ * * @return bool true if successful */ function toXMLHeader() { $this->xmlwriter->startElement("collection"); $this->xmlwriter->writeAttribute("xmlns", "http://www.loc.gov/MARC21/slim"); return true; } // }}} // {{{ getXMLWriter() /** * Returns the XMLWriter object * * This method produces an XML representation of a MARC record that * attempts to adhere to the MARCXML standard documented at * http://www.loc.gov/standards/marcxml/ * * @return XMLWriter XMLWriter instance */ function getXMLWriter() { return $this->xmlwriter; } // }}} // {{{ toXMLFooter() /** * Returns the MARCXML collection footer * * This method produces an XML representation of a MARC record that * attempts to adhere to the MARCXML standard documented at * http://www.loc.gov/standards/marcxml/ * * @return string representation of MARC record in MARCXML format */ function toXMLFooter() { $this->xmlwriter->endElement(); // end collection $this->xmlwriter->endDocument(); return $this->xmlwriter->outputMemory(); } // }}} } // }}} PK�����u]Sbw{7��{7�� ��File/MARC.phpnu�[��������<?php /* vim: set expandtab shiftwidth=4 tabstop=4 softtabstop=4 foldmethod=marker: */ /** * Parser for MARC records * * This package is based on the PHP MARC package, originally called "php-marc", * that is part of the Emilda Project (http://www.emilda.org). Christoffer * Landtman generously agreed to make the "php-marc" code available under the * GNU LGPL so it could be used as the basis of this PEAR package. * * PHP version 5 * * LICENSE: This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * @category File_Formats * @package File_MARC * @author Christoffer Landtman <landtman@realnode.com> * @author Dan Scott <dscott@laurentian.ca> * @copyright 2003-2010 Oy Realnode Ab, Dan Scott * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 * @version CVS: $Id$ * @link http://pear.php.net/package/File_MARC * @example read.php Retrieve specific fields and subfields from a record * @example subfields.php Create new subfields and add them in specific order * @example marc_yaz.php Pretty print a MARC record retrieved through the PECL yaz extension */ require_once 'PEAR/Exception.php'; require_once 'File/MARCBASE.php'; require_once 'File/MARC/Record.php'; require_once 'File/MARC/Field.php'; require_once 'File/MARC/Control_Field.php'; require_once 'File/MARC/Data_Field.php'; require_once 'File/MARC/Subfield.php'; require_once 'File/MARC/Exception.php'; require_once 'File/MARC/List.php'; // {{{ class File_MARC /** * The main File_MARC class enables you to return File_MARC_Record * objects from a stream or string. * * @category File_Formats * @package File_MARC * @author Christoffer Landtman <landtman@realnode.com> * @author Dan Scott <dscott@laurentian.ca> * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 * @link http://pear.php.net/package/File_MARC */ class File_MARC extends File_MARCBASE { // {{{ constants /** * MARC records retrieved from a file */ const SOURCE_FILE = 1; /** * MARC records retrieved from a binary string */ const SOURCE_STRING = 2; /** * Hexadecimal value for Subfield indicator */ const SUBFIELD_INDICATOR = "\x1F"; /** * Hexadecimal value for End of Field */ const END_OF_FIELD = "\x1E"; /** * Hexadecimal value for End of Record */ const END_OF_RECORD = "\x1D"; /** * Length of the Directory */ const DIRECTORY_ENTRY_LEN = 12; /** * Length of the Leader */ const LEADER_LEN = 24; /** * Maximum record length */ const MAX_RECORD_LENGTH = 99999; // }}} // {{{ properties /** * Source containing raw records * * @var resource */ protected $source; /** * Source type (SOURCE_FILE or SOURCE_STRING) * * @var int */ protected $type; /** * XMLWriter for writing collections * * @var XMLWriter */ protected $xmlwriter; // }}} // {{{ Constructor: function __construct() /** * Read in MARC records * * This function reads in MARC record files or strings that * contain one or more MARC records. * * <code> * <?php * // Retrieve MARC records from a file * $journals = new File_MARC('journals.mrc', SOURCE_FILE); * * // Retrieve MARC records from a string (e.g. Z39 query results) * $monographs = new File_MARC($raw_marc, SOURCE_STRING); * ?> * </code> * * @param string $source Name of the file, or a raw MARC string * @param int $type Source of the input, either SOURCE_FILE or SOURCE_STRING * @param string $record_class Record class, defaults to File_MARC_Record */ function __construct($source, $type = self::SOURCE_FILE, $record_class = null) { parent::__construct($source, $type, $record_class); switch ($type) { case self::SOURCE_FILE: $this->type = self::SOURCE_FILE; $this->source = fopen($source, 'rb'); if (!$this->source) { $errorMessage = File_MARC_Exception::formatError(File_MARC_Exception::$messages[File_MARC_Exception::ERROR_INVALID_FILE], array('filename' => $source)); throw new File_MARC_Exception($errorMessage, File_MARC_Exception::ERROR_INVALID_FILE); } break; case self::SOURCE_STRING: $this->type = self::SOURCE_STRING; $this->source = explode(File_MARC::END_OF_RECORD, $source); break; default: throw new File_MARC_Exception(File_MARC_Exception::$messages[File_MARC_Exception::ERROR_INVALID_SOURCE], File_MARC_Exception::ERROR_INVALID_SOURCE); } } // }}} // {{{ nextRaw() /** * Return the next raw MARC record * * Returns the next raw MARC record, unless all records already have * been read. * * @return string Either a raw record or false */ function nextRaw() { if ($this->type == self::SOURCE_FILE) { $record = stream_get_line($this->source, File_MARC::MAX_RECORD_LENGTH, File_MARC::END_OF_RECORD); // Remove illegal stuff that sometimes occurs between records $record = preg_replace('/^[\\x0a\\x0d\\x00]+/', "", $record); } elseif ($this->type == self::SOURCE_STRING) { $record = array_shift($this->source); } // Exit if we are at the end of the file if (!$record) { return false; } // Append the end of record we lost during stream_get_line() or explode() $record .= File_MARC::END_OF_RECORD; return $record; } // }}} // {{{ next() /** * Return next {@link File_MARC_Record} object * * Decodes the next raw MARC record and returns the {@link File_MARC_Record} * object. * <code> * <?php * // Retrieve a set of MARC records from a file * $journals = new File_MARC('journals.mrc', SOURCE_FILE); * * // Iterate through the retrieved records * while ($record = $journals->next()) { * print $record; * print "\n"; * } * * ?> * </code> * * @return File_MARC_Record next record, or false if there are * no more records */ function next() { $raw = $this->nextRaw(); if ($raw) { return $this->_decode($raw); } else { return false; } } // }}} // {{{ _decode() /** * Decode a given raw MARC record * * Port of Andy Lesters MARC::File::USMARC->decode() Perl function into PHP. * * @param string $text Raw MARC record * * @return File_MARC_Record Decoded File_MARC_Record object */ private function _decode($text) { $marc = new $this->record_class($this); // fallback on the actual byte length $record_length = strlen($text); $matches = array(); if (preg_match("/^(\d{5})/", $text, $matches)) { // Store record length $record_length = $matches[1]; if ($record_length != strlen($text)) { $marc->addWarning(File_MARC_Exception::formatError(File_MARC_Exception::$messages[File_MARC_Exception::ERROR_INCORRECT_LENGTH], array("record_length" => $record_length, "actual" => strlen($text)))); // Real beats declared byte length $record_length = strlen($text); } } else { $marc->addWarning(File_MARC_Exception::formatError(File_MARC_Exception::$messages[File_MARC_Exception::ERROR_NONNUMERIC_LENGTH], array("record_length" => substr($text, 0, 5)))); } if (substr($text, -1, 1) != File_MARC::END_OF_RECORD) throw new File_MARC_Exception(File_MARC_Exception::$messages[File_MARC_Exception::ERROR_INVALID_TERMINATOR], File_MARC_Exception::ERROR_INVALID_TERMINATOR); // Store leader $marc->setLeader(substr($text, 0, File_MARC::LEADER_LEN)); // bytes 12 - 16 of leader give offset to the body of the record $data_start = 0 + substr($text, 12, 5); // immediately after the leader comes the directory (no separator) $dir = substr($text, File_MARC::LEADER_LEN, $data_start - File_MARC::LEADER_LEN - 1); // -1 to allow for \x1e at end of directory // character after the directory must be \x1e if (substr($text, $data_start-1, 1) != File_MARC::END_OF_FIELD) { $marc->addWarning(File_MARC_Exception::$messages[File_MARC_Exception::ERROR_NO_DIRECTORY]); } // All directory entries 12 bytes long, so length % 12 must be 0 if (strlen($dir) % File_MARC::DIRECTORY_ENTRY_LEN != 0) { $marc->addWarning(File_MARC_Exception::$messages[File_MARC_Exception::ERROR_INVALID_DIRECTORY_LENGTH]); } // go through all the fields $nfields = strlen($dir) / File_MARC::DIRECTORY_ENTRY_LEN; for ($n=0; $n<$nfields; $n++) { // As pack returns to key 1, leave place 0 in list empty list(, $tag) = unpack("A3", substr($dir, $n*File_MARC::DIRECTORY_ENTRY_LEN, File_MARC::DIRECTORY_ENTRY_LEN)); list(, $len) = unpack("A3/A4", substr($dir, $n*File_MARC::DIRECTORY_ENTRY_LEN, File_MARC::DIRECTORY_ENTRY_LEN)); list(, $offset) = unpack("A3/A4/A5", substr($dir, $n*File_MARC::DIRECTORY_ENTRY_LEN, File_MARC::DIRECTORY_ENTRY_LEN)); // Check directory validity if (!preg_match("/^[0-9A-Za-z]{3}$/", $tag)) { $marc->addWarning(File_MARC_Exception::formatError(File_MARC_Exception::$messages[File_MARC_Exception::ERROR_INVALID_DIRECTORY_TAG], array("tag" => $tag))); } if (!preg_match("/^\d{4}$/", $len)) { $marc->addWarning(File_MARC_Exception::formatError(File_MARC_Exception::$messages[File_MARC_Exception::ERROR_INVALID_DIRECTORY_TAG_LENGTH], array("tag" => $tag, "len" => $len))); } if (!preg_match("/^\d{5}$/", $offset)) { $marc->addWarning(File_MARC_Exception::formatError(File_MARC_Exception::$messages[File_MARC_Exception::ERROR_INVALID_DIRECTORY_OFFSET], array("tag" => $tag, "offset" => $offset))); } if ($offset + $len > $record_length) { $marc->addWarning(File_MARC_Exception::formatError(File_MARC_Exception::$messages[File_MARC_Exception::ERROR_INVALID_DIRECTORY], array("tag" => $tag))); } $tag_data = substr($text, $data_start + $offset, $len); if (substr($tag_data, -1, 1) == File_MARC::END_OF_FIELD) { /* get rid of the end-of-tag character */ $tag_data = substr($tag_data, 0, -1); $len--; } else { $marc->addWarning(File_MARC_Exception::formatError(File_MARC_Exception::$messages[File_MARC_Exception::ERROR_FIELD_EOF], array("tag" => $tag))); } if (preg_match("/^\d+$/", $tag) and ($tag < 10)) { $marc->appendField(new File_MARC_Control_Field($tag, $tag_data)); } else { $subfields = explode(File_MARC::SUBFIELD_INDICATOR, $tag_data); $indicators = array_shift($subfields); if (strlen($indicators) != 2) { $errorMessage = File_MARC_Exception::formatError(File_MARC_Exception::$messages[File_MARC_Exception::ERROR_INVALID_INDICATORS], array("tag" => $tag, "indicators" => $indicators)); $marc->addWarning($errorMessage); // Do the best with the indicators we've got if (strlen($indicators) == 1) { $ind1 = $indicators; $ind2 = " "; } else { list($ind1,$ind2) = array(" ", " "); } } else { $ind1 = substr($indicators, 0, 1); $ind2 = substr($indicators, 1, 1); } // Split the subfield data into subfield name and data pairs $subfield_data = array(); foreach ($subfields as $subfield) { if (strlen($subfield) > 0) { $subfield_data[] = new File_MARC_Subfield(substr($subfield, 0, 1), substr($subfield, 1)); } else { $errorMessage = File_MARC_Exception::formatError(File_MARC_Exception::$messages[File_MARC_Exception::ERROR_EMPTY_SUBFIELD], array("tag" => $tag)); $marc->addWarning($errorMessage); } } if (!isset($subfield_data)) { $errorMessage = File_MARC_Exception::formatError(File_MARC_Exception::$messages[File_MARC_Exception::ERROR_EMPTY_SUBFIELD], array("tag" => $tag)); $marc->addWarning($errorMessage); } // If the data is invalid, let's just ignore the one field try { $new_field = new File_MARC_Data_Field($tag, $subfield_data, $ind1, $ind2); $marc->appendField($new_field); } catch (Exception $e) { $marc->addWarning($e->getMessage()); } } } return $marc; } // }}} } // }}} PK�����u]6EW��W����data/Mail_mimeDecode/xmail.xslnu�[��������<?xml version="1.0" encoding="ISO-8859-1"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format"> <xsl:output method="text" omit-xml-declaration="yes" indent="no"/> <xsl:preserve-space elements="headervalue paramvalue body"/> <xsl:template name="mimepart"> <xsl:variable name="boundary"> <xsl:for-each select="./header"> <xsl:if test="string(./headername) = 'Content-Type'"> <xsl:for-each select="./parameter"> <xsl:if test="string(./paramname) = 'boundary'"> <xsl:value-of select="paramvalue"/> </xsl:if> </xsl:for-each> </xsl:if> </xsl:for-each> </xsl:variable> <xsl:for-each select="header"> <xsl:value-of select="headername"/> <xsl:text>: </xsl:text> <xsl:value-of select="headervalue"/> <xsl:if test="count(./parameter) = 0"> <xsl:text> </xsl:text> </xsl:if> <xsl:for-each select="parameter"> <xsl:text>; </xsl:text> <xsl:value-of select="paramname"/> <xsl:text>="</xsl:text> <xsl:value-of select="paramvalue"/> <xsl:text>"</xsl:text> </xsl:for-each> <xsl:if test="count(./parameter) > 0"> <xsl:text> </xsl:text> </xsl:if> </xsl:for-each> <xsl:text> </xsl:text> <!-- Which to do, print a body or process subparts? --> <xsl:choose> <xsl:when test="count(./mimepart) = 0"> <xsl:value-of select="body"/> <xsl:text> </xsl:text> </xsl:when> <xsl:otherwise> <xsl:for-each select="mimepart"> <xsl:text>--</xsl:text><xsl:value-of select="$boundary"/><xsl:text> </xsl:text> <xsl:call-template name="mimepart"/> </xsl:for-each> <xsl:text>--</xsl:text><xsl:value-of select="$boundary"/><xsl:text>-- </xsl:text> </xsl:otherwise> </xsl:choose> </xsl:template> <!-- This is where the stylesheet really starts, matching the top level email element --> <xsl:template match="email"> <xsl:call-template name="mimepart"/> </xsl:template> </xsl:stylesheet>PK�����u] $v6��6����data/Mail_mimeDecode/xmail.dtdnu�[��������<?xml version="1.0" encoding="ISO-8859-1"?> <!ENTITY lt "&#60;"> <!ENTITY gt ">"> <!ENTITY amp "&#38;"> <!ENTITY apos "'"> <!ENTITY quot """> <!ENTITY crlf " "> <!ELEMENT email (header+, (body | mimepart+))> <!ELEMENT mimepart (header+, (body | mimepart+))> <!ELEMENT body (#PCDATA)> <!ELEMENT header ((headername|headervalue|parameter)*)> <!ELEMENT headername (#PCDATA)> <!ELEMENT headervalue (#PCDATA)> <!ELEMENT parameter ((paramname|paramvalue)+)> <!ELEMENT paramvalue (#PCDATA)> <!ELEMENT paramname (#PCDATA)> PK�����u]������data/PEAR/template.specnu�[��������Summary: PEAR: @summary@ Name: @rpm_package@ Version: @version@ Release: 1 License: @release_license@ Group: Development/Libraries Source: http://@master_server@/get/@package@-%{version}.tgz BuildRoot: %{_tmppath}/%{name}-root URL: http://@master_server@/package/@package@ Prefix: %{_prefix} BuildArchitectures: @arch@ @extra_headers@ %description @description@ %prep rm -rf %{buildroot}/* %setup -c -T # XXX Source files location is missing here in pear cmd pear -v -c %{buildroot}/pearrc \ -d php_dir=%{_libdir}/php/pear \ -d doc_dir=/docs \ -d bin_dir=%{_bindir} \ -d data_dir=%{_libdir}/php/pear/data \ -d test_dir=%{_libdir}/php/pear/tests \ -d ext_dir=%{_libdir} \@extra_config@ -s %build echo BuildRoot=%{buildroot} %postun # if refcount = 0 then package has been removed (not upgraded) if [ "$1" -eq "0" ]; then pear uninstall --nodeps -r @possible_channel@@package@ rm @rpm_xml_dir@/@package@.xml fi %post # if refcount = 2 then package has been upgraded if [ "$1" -ge "2" ]; then pear upgrade --nodeps -r @rpm_xml_dir@/@package@.xml else pear install --nodeps -r @rpm_xml_dir@/@package@.xml fi %install pear -c %{buildroot}/pearrc install --nodeps -R %{buildroot} \ $RPM_SOURCE_DIR/@package@-%{version}.tgz rm %{buildroot}/pearrc rm %{buildroot}/%{_libdir}/php/pear/.filemap rm %{buildroot}/%{_libdir}/php/pear/.lock rm -rf %{buildroot}/%{_libdir}/php/pear/.registry if [ "@doc_files@" != "" ]; then mv %{buildroot}/docs/@package@/* . rm -rf %{buildroot}/docs fi mkdir -p %{buildroot}@rpm_xml_dir@ tar -xzf $RPM_SOURCE_DIR/@package@-%{version}.tgz package@package2xml@.xml cp -p package@package2xml@.xml %{buildroot}@rpm_xml_dir@/@package@.xml #rm -rf %{buildroot}/* #pear -q install -R %{buildroot} -n package@package2xml@.xml #mkdir -p %{buildroot}@rpm_xml_dir@ #cp -p package@package2xml@.xml %{buildroot}@rpm_xml_dir@/@package@.xml %files %defattr(-,root,root) %doc @doc_files@ / PK�����u]ũ �� ����data/PEAR/package.dtdnu�[��������<!-- This is the PEAR package description, version 1.0. It should be used with the informal public identifier: "-//PHP Group//DTD PEAR Package 1.0//EN//XML" Copyright (c) 1997-2005 The PHP Group This source file is subject to the New BSD License, that is bundled with this package in the file LICENSE, and is available at through the world-wide-web at http://opensource.org/licenses/bsd-license.php. If you did not receive a copy of the New BSD 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. Authors: Stig S. Bakken <ssb@fast.no> Gregory Beaver <cellog@php.net> --> <!ENTITY % NUMBER "CDATA"> <!ELEMENT package (name,summary,description,license?,maintainers,release,changelog?)> <!ATTLIST package type (source|binary|empty) "empty" version CDATA #REQUIRED packagerversion CDATA #IMPLIED> <!ELEMENT name (#PCDATA)> <!ELEMENT summary (#PCDATA)> <!ELEMENT license (#PCDATA)> <!ELEMENT description (#PCDATA)> <!ELEMENT maintainers (maintainer)+> <!ELEMENT maintainer (user|role|name|email)+> <!ELEMENT user (#PCDATA)> <!ELEMENT role (#PCDATA)> <!ELEMENT email (#PCDATA)> <!ELEMENT changelog (release)+> <!ELEMENT release (version,date,license,state,notes,warnings?,provides*,deps?,configureoptions?,filelist?)> <!ELEMENT version (#PCDATA)> <!ELEMENT date (#PCDATA)> <!ELEMENT state (#PCDATA)> <!ELEMENT notes (#PCDATA)> <!ELEMENT warnings (#PCDATA)> <!ELEMENT deps (dep*)> <!ELEMENT dep (#PCDATA)> <!ATTLIST dep type (pkg|ext|php) #REQUIRED rel (has|eq|lt|le|gt|ge) #IMPLIED version CDATA #IMPLIED optional (yes|no) 'no'> <!ELEMENT configureoptions (configureoption)+> <!ELEMENT configureoption EMPTY> <!ATTLIST configureoption name CDATA #REQUIRED default CDATA #IMPLIED prompt CDATA #REQUIRED> <!ELEMENT provides EMPTY> <!ATTLIST provides type (ext|prog|class|function|feature|api) #REQUIRED name CDATA #REQUIRED extends CDATA #IMPLIED> <!ELEMENT filelist (dir|file)+> <!ELEMENT dir (dir|file)+> <!ATTLIST dir name CDATA #REQUIRED role (php|ext|src|test|doc|data|script) 'php' baseinstalldir CDATA #IMPLIED> <!ELEMENT file (replace*)> <!ATTLIST file role (php|ext|src|test|doc|data|script) 'php' debug (na|on|off) 'na' format CDATA #IMPLIED baseinstalldir CDATA #IMPLIED platform CDATA #IMPLIED md5sum CDATA #IMPLIED name CDATA #REQUIRED install-as CDATA #IMPLIED> <!ELEMENT replace EMPTY> <!ATTLIST replace type (php-const|pear-config|package-info) #REQUIRED from CDATA #REQUIRED to CDATA #REQUIRED> PK�����u]%)c��c�� ��peclcmd.phpnu�[��������<?php /** * PEAR, the PHP Extension and Application Repository * * Command line interface * * PHP versions 4 and 5 * * @category pear * @package PEAR * @author Stig Bakken <ssb@php.net> * @author Tomas V.V.Cox <cox@idecnet.com> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR */ /** * @nodep Gtk */ //the space is needed for windows include paths with trailing backslash // http://pear.php.net/bugs/bug.php?id=19482 if ('/opt/alt/php56/usr/share/pear ' != '@'.'include_path'.'@ ') { ini_set('include_path', trim('/opt/alt/php56/usr/share/pear '). PATH_SEPARATOR . get_include_path()); $raw = false; } else { // this is a raw, uninstalled pear, either a cvs checkout, or php distro ini_set('include_path', __DIR__ . PATH_SEPARATOR . get_include_path()); $raw = true; } define('PEAR_RUNTYPE', 'pecl'); require_once 'pearcmd.php'; /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * indent-tabs-mode: nil * mode: php * End: */ // vim600:syn=php ?> PK�����u]Pi������.depdbnu�[��������a:3:{s:8:"_version";s:3:"1.0";s:12:"dependencies";a:1:{s:12:"pear.php.net";a:6:{s:4:"pear";a:9:{i:0;a:3:{s:3:"dep";a:4:{s:4:"name";s:11:"Archive_Tar";s:7:"channel";s:12:"pear.php.net";s:3:"min";s:5:"1.4.0";s:11:"recommended";s:5:"1.4.4";}s:4:"type";s:8:"required";s:5:"group";b:0;}i:1;a:3:{s:3:"dep";a:4:{s:4:"name";s:16:"Structures_Graph";s:7:"channel";s:12:"pear.php.net";s:3:"min";s:5:"1.1.0";s:11:"recommended";s:5:"1.1.1";}s:4:"type";s:8:"required";s:5:"group";b:0;}i:2;a:3:{s:3:"dep";a:4:{s:4:"name";s:14:"Console_Getopt";s:7:"channel";s:12:"pear.php.net";s:3:"min";s:5:"1.4.1";s:11:"recommended";s:5:"1.4.1";}s:4:"type";s:8:"required";s:5:"group";b:0;}i:3;a:3:{s:3:"dep";a:4:{s:4:"name";s:8:"XML_Util";s:7:"channel";s:12:"pear.php.net";s:3:"min";s:5:"1.3.0";s:11:"recommended";s:5:"1.4.3";}s:4:"type";s:8:"required";s:5:"group";b:0;}i:4;a:3:{s:3:"dep";a:4:{s:4:"name";s:17:"PEAR_Frontend_Web";s:7:"channel";s:12:"pear.php.net";s:3:"max";s:3:"0.4";s:9:"conflicts";s:0:"";}s:4:"type";s:8:"required";s:5:"group";b:0;}i:5;a:3:{s:3:"dep";a:5:{s:4:"name";s:17:"PEAR_Frontend_Gtk";s:7:"channel";s:12:"pear.php.net";s:3:"max";s:5:"0.4.0";s:7:"exclude";s:5:"0.4.0";s:9:"conflicts";s:0:"";}s:4:"type";s:8:"required";s:5:"group";b:0;}i:6;a:3:{s:3:"dep";a:3:{s:4:"name";s:17:"PEAR_Frontend_Web";s:7:"channel";s:12:"pear.php.net";s:3:"min";s:5:"0.5.1";}s:4:"type";s:8:"optional";s:5:"group";s:12:"webinstaller";}i:7;a:3:{s:3:"dep";a:3:{s:4:"name";s:17:"PEAR_Frontend_Gtk";s:7:"channel";s:12:"pear.php.net";s:3:"min";s:5:"0.4.0";}s:4:"type";s:8:"optional";s:5:"group";s:12:"gtkinstaller";}i:8;a:3:{s:3:"dep";a:2:{s:4:"name";s:18:"PEAR_Frontend_Gtk2";s:7:"channel";s:12:"pear.php.net";}s:4:"type";s:8:"optional";s:5:"group";s:13:"gtk2installer";}}s:9:"file_marc";a:1:{i:0;a:3:{s:3:"dep";a:2:{s:4:"name";s:13:"Validate_ISPN";s:7:"channel";s:12:"pear.php.net";}s:4:"type";s:8:"optional";s:5:"group";b:0;}}s:4:"mail";a:1:{i:0;a:3:{s:3:"dep";a:3:{s:4:"name";s:8:"Net_SMTP";s:7:"channel";s:12:"pear.php.net";s:3:"min";s:5:"1.4.1";}s:4:"type";s:8:"optional";s:5:"group";b:0;}}s:15:"mail_mimedecode";a:1:{i:0;a:3:{s:3:"dep";a:4:{s:4:"name";s:9:"Mail_Mime";s:7:"channel";s:12:"pear.php.net";s:3:"min";s:5:"1.4.0";s:7:"exclude";s:5:"1.4.0";}s:4:"type";s:8:"required";s:5:"group";b:0;}}s:9:"net_sieve";a:2:{i:0;a:3:{s:3:"dep";a:3:{s:4:"name";s:10:"Net_Socket";s:7:"channel";s:12:"pear.php.net";s:3:"min";s:3:"1.0";}s:4:"type";s:8:"required";s:5:"group";b:0;}i:1;a:3:{s:3:"dep";a:3:{s:4:"name";s:9:"Auth_SASL";s:7:"channel";s:12:"pear.php.net";s:3:"min";s:3:"1.0";}s:4:"type";s:8:"optional";s:5:"group";b:0;}}s:8:"net_smtp";a:2:{i:0;a:3:{s:3:"dep";a:3:{s:4:"name";s:10:"Net_Socket";s:7:"channel";s:12:"pear.php.net";s:3:"min";s:5:"1.0.7";}s:4:"type";s:8:"required";s:5:"group";b:0;}i:1;a:3:{s:3:"dep";a:3:{s:4:"name";s:9:"Auth_SASL";s:7:"channel";s:12:"pear.php.net";s:3:"min";s:5:"1.0.5";}s:4:"type";s:8:"optional";s:5:"group";b:0;}}}}s:8:"packages";a:1:{s:12:"pear.php.net";a:12:{s:11:"archive_tar";a:1:{i:0;a:2:{s:7:"channel";s:12:"pear.php.net";s:7:"package";s:4:"pear";}}s:16:"structures_graph";a:1:{i:0;a:2:{s:7:"channel";s:12:"pear.php.net";s:7:"package";s:4:"pear";}}s:14:"console_getopt";a:1:{i:0;a:2:{s:7:"channel";s:12:"pear.php.net";s:7:"package";s:4:"pear";}}s:8:"xml_util";a:1:{i:0;a:2:{s:7:"channel";s:12:"pear.php.net";s:7:"package";s:4:"pear";}}s:17:"pear_frontend_web";a:1:{i:0;a:2:{s:7:"channel";s:12:"pear.php.net";s:7:"package";s:4:"pear";}}s:17:"pear_frontend_gtk";a:1:{i:0;a:2:{s:7:"channel";s:12:"pear.php.net";s:7:"package";s:4:"pear";}}s:18:"pear_frontend_gtk2";a:1:{i:0;a:2:{s:7:"channel";s:12:"pear.php.net";s:7:"package";s:4:"pear";}}s:13:"validate_ispn";a:1:{i:0;a:2:{s:7:"channel";s:12:"pear.php.net";s:7:"package";s:9:"file_marc";}}s:8:"net_smtp";a:1:{i:0;a:2:{s:7:"channel";s:12:"pear.php.net";s:7:"package";s:4:"mail";}}s:9:"mail_mime";a:1:{i:0;a:2:{s:7:"channel";s:12:"pear.php.net";s:7:"package";s:15:"mail_mimedecode";}}s:10:"net_socket";a:2:{i:0;a:2:{s:7:"channel";s:12:"pear.php.net";s:7:"package";s:9:"net_sieve";}i:1;a:2:{s:7:"channel";s:12:"pear.php.net";s:7:"package";s:8:"net_smtp";}}s:9:"auth_sasl";a:2:{i:0;a:2:{s:7:"channel";s:12:"pear.php.net";s:7:"package";s:9:"net_sieve";}i:1;a:2:{s:7:"channel";s:12:"pear.php.net";s:7:"package";s:8:"net_smtp";}}}}}PK�����u]؛J��J����Mail/mimePart.phpnu�[��������<?php /** * The Mail_mimePart class is used to create MIME E-mail messages * * This class enables you to manipulate and build a mime email * from the ground up. The Mail_Mime class is a userfriendly api * to this class for people who aren't interested in the internals * of mime mail. * This class however allows full control over the email. * * Compatible with PHP version 5, 7 and 8 * * LICENSE: This LICENSE is in the BSD license style. * Copyright (c) 2002-2003, Richard Heyes <richard@phpguru.org> * Copyright (c) 2003-2006, PEAR <pear-group@php.net> * All rights reserved. * * Redistribution and use in source and binary forms, with or * without modification, are permitted provided that the following * conditions are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * - 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. * - Neither the name of the authors, nor the names of its contributors * may be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS 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 COPYRIGHT OWNER OR 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. * * @category Mail * @package Mail_Mime * @author Richard Heyes <richard@phpguru.org> * @author Cipriano Groenendal <cipri@php.net> * @author Sean Coates <sean@php.net> * @author Aleksander Machniak <alec@php.net> * @copyright 2003-2006 PEAR <pear-group@php.net> * @license http://www.opensource.org/licenses/bsd-license.php BSD License * @version Release: @package_version@ * @link http://pear.php.net/package/Mail_mime */ /** * Require PEAR * * This package depends on PEAR to raise errors. */ require_once 'PEAR.php'; /** * The Mail_mimePart class is used to create MIME E-mail messages * * This class enables you to manipulate and build a mime email * from the ground up. The Mail_Mime class is a userfriendly api * to this class for people who aren't interested in the internals * of mime mail. * This class however allows full control over the email. * * @category Mail * @package Mail_Mime * @author Richard Heyes <richard@phpguru.org> * @author Cipriano Groenendal <cipri@php.net> * @author Sean Coates <sean@php.net> * @author Aleksander Machniak <alec@php.net> * @copyright 2003-2006 PEAR <pear-group@php.net> * @license http://www.opensource.org/licenses/bsd-license.php BSD License * @version Release: @package_version@ * @link http://pear.php.net/package/Mail_mime */ class Mail_mimePart { /** * The encoding type of this part * * @var string */ protected $encoding; /** * An array of subparts * * @var array */ protected $subparts = array(); /** * The output of this part after being built * * @var string */ protected $encoded; /** * Headers for this part * * @var array */ protected $headers = array(); /** * The body of this part (not encoded) * * @var string */ protected $body; /** * The location of file with body of this part (not encoded) * * @var string */ protected $body_file; /** * The short text of multipart part preamble (RFC2046 5.1.1) * * @var string */ protected $preamble; /** * The end-of-line sequence * * @var string */ protected $eol = "\r\n"; /** * Constructor. * * Sets up the object. * * @param string $body The body of the mime part if any. * @param array $params An associative array of optional parameters: * - content_type: The content type for this part eg multipart/mixed * - encoding: The encoding to use, 7bit, 8bit, base64, or quoted-printable * - charset: Content character set * - cid: Content ID to apply * - disposition: Content disposition, inline or attachment * - filename: Filename parameter for content disposition * - description: Content description * - name_encoding: Encoding of the attachment name (Content-Type) * By default filenames are encoded using RFC2231 * Here you can set RFC2047 encoding (quoted-printable * or base64) instead * - filename_encoding: Encoding of the attachment filename (Content-Disposition) * See 'name_encoding' * - headers_charset: Charset of the headers e.g. filename, description. * If not set, 'charset' will be used * - eol: End of line sequence. Default: "\r\n" * - headers: Hash array with additional part headers. Array keys * can be in form of <header_name>:<parameter_name> * - body_file: Location of file with part's body (instead of $body) * - preamble: short text of multipart part preamble (RFC2046 5.1.1) */ public function __construct($body = '', $params = array()) { if (!empty($params['eol'])) { $this->eol = $params['eol']; } else if (defined('MAIL_MIMEPART_CRLF')) { // backward-copat. $this->eol = MAIL_MIMEPART_CRLF; } // Additional part headers if (!empty($params['headers']) && is_array($params['headers'])) { $headers = $params['headers']; } foreach ($params as $key => $value) { switch ($key) { case 'encoding': $this->encoding = $value; $headers['Content-Transfer-Encoding'] = $value; break; case 'cid': $headers['Content-ID'] = '<' . $value . '>'; break; case 'location': $headers['Content-Location'] = $value; break; case 'body_file': $this->body_file = $value; break; case 'preamble': $this->preamble = $value; break; // for backward compatibility case 'dfilename': $params['filename'] = $value; break; } } // Default content-type if (empty($params['content_type'])) { $params['content_type'] = 'text/plain'; } // Content-Type $headers['Content-Type'] = $params['content_type']; if (!empty($params['charset'])) { $charset = "charset={$params['charset']}"; // place charset parameter in the same line, if possible if ((strlen($headers['Content-Type']) + strlen($charset) + 16) <= 76) { $headers['Content-Type'] .= '; '; } else { $headers['Content-Type'] .= ';' . $this->eol . ' '; } $headers['Content-Type'] .= $charset; // Default headers charset if (!isset($params['headers_charset'])) { $params['headers_charset'] = $params['charset']; } } // header values encoding parameters $h_charset = !empty($params['headers_charset']) ? $params['headers_charset'] : 'US-ASCII'; $h_language = !empty($params['language']) ? $params['language'] : null; $h_encoding = !empty($params['name_encoding']) ? $params['name_encoding'] : null; if (!empty($params['filename'])) { $headers['Content-Type'] .= ';' . $this->eol; $headers['Content-Type'] .= $this->buildHeaderParam( 'name', $params['filename'], $h_charset, $h_language, $h_encoding ); } // Content-Disposition if (!empty($params['disposition'])) { $headers['Content-Disposition'] = $params['disposition']; if (!empty($params['filename'])) { $headers['Content-Disposition'] .= ';' . $this->eol; $headers['Content-Disposition'] .= $this->buildHeaderParam( 'filename', $params['filename'], $h_charset, $h_language, !empty($params['filename_encoding']) ? $params['filename_encoding'] : null ); } // add attachment size $size = $this->body_file ? filesize($this->body_file) : strlen($body); if ($size) { $headers['Content-Disposition'] .= ';' . $this->eol . ' size=' . $size; } } if (!empty($params['description'])) { $headers['Content-Description'] = $this->encodeHeader( 'Content-Description', $params['description'], $h_charset, $h_encoding, $this->eol ); } // Search and add existing headers' parameters foreach ($headers as $key => $value) { $items = explode(':', $key); if (count($items) == 2) { $header = $items[0]; $param = $items[1]; if (isset($headers[$header])) { $headers[$header] .= ';' . $this->eol; } $headers[$header] .= $this->buildHeaderParam( $param, $value, $h_charset, $h_language, $h_encoding ); unset($headers[$key]); } } // Default encoding if (!isset($this->encoding)) { $this->encoding = '7bit'; } // Assign stuff to member variables $this->encoded = array(); $this->headers = $headers; $this->body = $body; } /** * Encodes and returns the email. Also stores * it in the encoded member variable * * @param string $boundary Pre-defined boundary string * * @return An associative array containing two elements, * body and headers. The headers element is itself * an indexed array. On error returns PEAR error object. */ public function encode($boundary=null) { $encoded =& $this->encoded; if (count($this->subparts)) { $boundary = $boundary ? $boundary : '=_' . md5(rand() . microtime()); $eol = $this->eol; $this->headers['Content-Type'] .= ";$eol boundary=\"$boundary\""; $encoded['body'] = ''; if ($this->preamble) { $encoded['body'] .= $this->preamble . $eol . $eol; } for ($i = 0; $i < count($this->subparts); $i++) { $encoded['body'] .= '--' . $boundary . $eol; $tmp = $this->subparts[$i]->encode(); if (is_a($tmp, 'PEAR_Error')) { return $tmp; } foreach ($tmp['headers'] as $key => $value) { $encoded['body'] .= $key . ': ' . $value . $eol; } $encoded['body'] .= $eol . $tmp['body'] . $eol; } $encoded['body'] .= '--' . $boundary . '--' . $eol; } else if ($this->body) { $encoded['body'] = $this->getEncodedData($this->body, $this->encoding); } else if ($this->body_file) { // Temporarily reset magic_quotes_runtime for file reads and writes if (version_compare(PHP_VERSION, '5.4.0', '<')) { $magic_quotes = @ini_set('magic_quotes_runtime', 0); } $body = $this->getEncodedDataFromFile($this->body_file, $this->encoding); if (isset($magic_quotes)) { @ini_set('magic_quotes_runtime', $magic_quotes); } if (is_a($body, 'PEAR_Error')) { return $body; } $encoded['body'] = $body; } else { $encoded['body'] = ''; } // Add headers to $encoded $encoded['headers'] =& $this->headers; return $encoded; } /** * Encodes and saves the email into file or stream. * Data will be appended to the file/stream. * * @param mixed $filename Existing file location * or file pointer resource * @param string $boundary Pre-defined boundary string * @param boolean $skip_head True if you don't want to save headers * * @return array An associative array containing message headers * or PEAR error object * @since 1.6.0 */ public function encodeToFile($filename, $boundary = null, $skip_head = false) { if (!is_resource($filename)) { if (file_exists($filename) && !is_writable($filename)) { $err = self::raiseError('File is not writeable: ' . $filename); return $err; } if (!($fh = fopen($filename, 'ab'))) { $err = self::raiseError('Unable to open file: ' . $filename); return $err; } } else { $fh = $filename; } // Temporarily reset magic_quotes_runtime for file reads and writes if (version_compare(PHP_VERSION, '5.4.0', '<')) { $magic_quotes = @ini_set('magic_quotes_runtime', 0); } $res = $this->encodePartToFile($fh, $boundary, $skip_head); if (!is_resource($filename)) { fclose($fh); } if (isset($magic_quotes)) { @ini_set('magic_quotes_runtime', $magic_quotes); } return is_a($res, 'PEAR_Error') ? $res : $this->headers; } /** * Encodes given email part into file * * @param string $fh Output file handle * @param string $boundary Pre-defined boundary string * @param boolean $skip_head True if you don't want to save headers * * @return array True on sucess or PEAR error object */ protected function encodePartToFile($fh, $boundary = null, $skip_head = false) { $eol = $this->eol; if (count($this->subparts)) { $boundary = $boundary ? $boundary : '=_' . md5(rand() . microtime()); $this->headers['Content-Type'] .= ";$eol boundary=\"$boundary\""; } if (!$skip_head) { foreach ($this->headers as $key => $value) { fwrite($fh, $key . ': ' . $value . $eol); } $f_eol = $eol; } else { $f_eol = ''; } if (count($this->subparts)) { if ($this->preamble) { fwrite($fh, $f_eol . $this->preamble . $eol); $f_eol = $eol; } for ($i = 0; $i < count($this->subparts); $i++) { fwrite($fh, $f_eol . '--' . $boundary . $eol); $res = $this->subparts[$i]->encodePartToFile($fh); if (is_a($res, 'PEAR_Error')) { return $res; } $f_eol = $eol; } fwrite($fh, $eol . '--' . $boundary . '--' . $eol); } else if ($this->body) { fwrite($fh, $f_eol); fwrite($fh, $this->getEncodedData($this->body, $this->encoding)); } else if ($this->body_file) { fwrite($fh, $f_eol); $res = $this->getEncodedDataFromFile( $this->body_file, $this->encoding, $fh ); if (is_a($res, 'PEAR_Error')) { return $res; } } return true; } /** * Adds a subpart to current mime part and returns * a reference to it * * @param mixed $body The body of the subpart or Mail_mimePart object * @param array $params The parameters for the subpart, same * as the $params argument for constructor * * @return Mail_mimePart A reference to the part you just added. */ public function addSubpart($body, $params = null) { if ($body instanceof Mail_mimePart) { $part = $body; } else { $part = new Mail_mimePart($body, $params); } $this->subparts[] = $part; return $part; } /** * Returns encoded data based upon encoding passed to it * * @param string $data The data to encode. * @param string $encoding The encoding type to use, 7bit, base64, * or quoted-printable. * * @return string Encoded data string */ protected function getEncodedData($data, $encoding) { switch ($encoding) { case 'quoted-printable': return self::quotedPrintableEncode($data, 76, $this->eol); break; case 'base64': return rtrim(chunk_split(base64_encode($data), 76, $this->eol)); break; case '8bit': case '7bit': default: return $data; } } /** * Returns encoded data based upon encoding passed to it * * @param string $filename Data file location * @param string $encoding The encoding type to use, 7bit, base64, * or quoted-printable. * @param resource $fh Output file handle. If set, data will be * stored into it instead of returning it * * @return string Encoded data or PEAR error object */ protected function getEncodedDataFromFile($filename, $encoding, $fh = null) { if (!is_readable($filename)) { $err = self::raiseError('Unable to read file: ' . $filename); return $err; } if (!($fd = fopen($filename, 'rb'))) { $err = self::raiseError('Could not open file: ' . $filename); return $err; } $data = ''; switch ($encoding) { case 'quoted-printable': while (!feof($fd)) { $buffer = self::quotedPrintableEncode(fgets($fd), 76, $this->eol); if ($fh) { fwrite($fh, $buffer); } else { $data .= $buffer; } } break; case 'base64': while (!feof($fd)) { // Should read in a multiple of 57 bytes so that // the output is 76 bytes per line. Don't use big chunks // because base64 encoding is memory expensive $buffer = fread($fd, 57 * 9198); // ca. 0.5 MB $buffer = base64_encode($buffer); $buffer = chunk_split($buffer, 76, $this->eol); if (feof($fd)) { $buffer = rtrim($buffer); } if ($fh) { fwrite($fh, $buffer); } else { $data .= $buffer; } } break; case '8bit': case '7bit': default: while (!feof($fd)) { $buffer = fread($fd, 1048576); // 1 MB if ($fh) { fwrite($fh, $buffer); } else { $data .= $buffer; } } } fclose($fd); if (!$fh) { return $data; } } /** * Encodes data to quoted-printable standard. * * @param string $input The data to encode * @param int $line_max Optional max line length. Should * not be more than 76 chars * @param string $eol End-of-line sequence. Default: "\r\n" * * @return string Encoded data */ public static function quotedPrintableEncode($input , $line_max = 76, $eol = "\r\n") { /* // imap_8bit() is extremely fast, but doesn't handle properly some characters if (function_exists('imap_8bit') && $line_max == 76) { $input = preg_replace('/\r?\n/', "\r\n", $input); $input = imap_8bit($input); if ($eol != "\r\n") { $input = str_replace("\r\n", $eol, $input); } return $input; } */ $lines = preg_split("/\r?\n/", $input); $escape = '='; $output = ''; foreach ($lines as $idx => $line) { $newline = ''; $i = 0; while (isset($line[$i])) { $char = $line[$i]; $dec = ord($char); $i++; if (($dec == 32) && (!isset($line[$i]))) { // convert space at eol only $char = '=20'; } elseif ($dec == 9 && isset($line[$i])) { ; // Do nothing if a TAB is not on eol } elseif (($dec == 61) || ($dec < 32) || ($dec > 126)) { // Escape unprintable chars $char = $escape . sprintf('%02X', $dec); } elseif (($dec == 46) && (($newline == '') || ((strlen($newline) + strlen(".=")) > $line_max && isset($line[$i]))) ) { // Bug #9722: convert full-stop at bol, // some Windows servers need this, won't break anything (cipri) // Bug #11731: full-stop at bol also needs to be encoded // if this line would push us over the line_max limit. $char = '=2E'; } // EOL is not counted if ((strlen($newline) + strlen($char) == $line_max) && !isset($line[$i]) ) { ; // no soft break is needed if we're the last char } elseif ((strlen($newline) + strlen($char)) >= $line_max) { // soft line break; " =\r\n" is okay $output .= $newline . $escape . $eol; $newline = ''; } $newline .= $char; } // end of for $output .= $newline . $eol; unset($lines[$idx]); } // Don't want last crlf $output = substr($output, 0, -1 * strlen($eol)); return $output; } /** * Encodes the parameter of a header. * * @param string $name The name of the header-parameter * @param string $value The value of the paramter * @param string $charset The characterset of $value * @param string $language The language used in $value * @param string $encoding Parameter encoding. If not set, parameter value * is encoded according to RFC2231 * @param int $maxLength The maximum length of a line. Defauls to 75 * * @return string */ protected function buildHeaderParam($name, $value, $charset = null, $language = null, $encoding = null, $maxLength = 75 ) { // RFC 2045: // value needs encoding if contains non-ASCII chars or is longer than 78 chars if (!preg_match('#[^\x20-\x7E]#', $value)) { $token_regexp = '#([^\x21\x23-\x27\x2A\x2B\x2D' . '\x2E\x30-\x39\x41-\x5A\x5E-\x7E])#'; if (!preg_match($token_regexp, $value)) { // token if (strlen($name) + strlen($value) + 3 <= $maxLength) { return " {$name}={$value}"; } } else { // quoted-string $quoted = addcslashes($value, '\\"'); if (strlen($name) + strlen($quoted) + 5 <= $maxLength) { return " {$name}=\"{$quoted}\""; } } } // RFC2047: use quoted-printable/base64 encoding if ($encoding == 'quoted-printable' || $encoding == 'base64') { return $this->buildRFC2047Param($name, $value, $charset, $encoding); } // RFC2231: $encValue = preg_replace_callback( '/([^\x21\x23\x24\x26\x2B\x2D\x2E\x30-\x39\x41-\x5A\x5E-\x7E])/', array($this, 'encodeReplaceCallback'), $value ); $value = "$charset'$language'$encValue"; $header = " {$name}*={$value}"; if (strlen($header) <= $maxLength) { return $header; } $preLength = strlen(" {$name}*0*="); $maxLength = max(16, $maxLength - $preLength - 3); $maxLengthReg = "|(.{0,$maxLength}[^\%][^\%])|"; $headers = array(); $headCount = 0; while ($value) { $matches = array(); $found = preg_match($maxLengthReg, $value, $matches); if ($found) { $headers[] = " {$name}*{$headCount}*={$matches[0]}"; $value = substr($value, strlen($matches[0])); } else { $headers[] = " {$name}*{$headCount}*={$value}"; $value = ''; } $headCount++; } $headers = implode(';' . $this->eol, $headers); return $headers; } /** * Encodes header parameter as per RFC2047 if needed * * @param string $name The parameter name * @param string $value The parameter value * @param string $charset The parameter charset * @param string $encoding Encoding type (quoted-printable or base64) * @param int $maxLength Encoded parameter max length. Default: 76 * * @return string Parameter line */ protected function buildRFC2047Param($name, $value, $charset, $encoding = 'quoted-printable', $maxLength = 76 ) { // WARNING: RFC 2047 says: "An 'encoded-word' MUST NOT be used in // parameter of a MIME Content-Type or Content-Disposition field", // but... it's supported by many clients/servers $quoted = ''; if ($encoding == 'base64') { $value = base64_encode($value); $prefix = '=?' . $charset . '?B?'; $suffix = '?='; // 2 x SPACE, 2 x '"', '=', ';' $add_len = strlen($prefix . $suffix) + strlen($name) + 6; $len = $add_len + strlen($value); while ($len > $maxLength) { // We can cut base64-encoded string every 4 characters $real_len = floor(($maxLength - $add_len) / 4) * 4; $_quote = substr($value, 0, $real_len); $value = substr($value, $real_len); $quoted .= $prefix . $_quote . $suffix . $this->eol . ' '; $add_len = strlen($prefix . $suffix) + 4; // 2 x SPACE, '"', ';' $len = strlen($value) + $add_len; } $quoted .= $prefix . $value . $suffix; } else { // quoted-printable $value = $this->encodeQP($value); $prefix = '=?' . $charset . '?Q?'; $suffix = '?='; // 2 x SPACE, 2 x '"', '=', ';' $add_len = strlen($prefix . $suffix) + strlen($name) + 6; $len = $add_len + strlen($value); while ($len > $maxLength) { $length = $maxLength - $add_len; // don't break any encoded letters if (preg_match("/^(.{0,$length}[^\=][^\=])/", $value, $matches)) { $_quote = $matches[1]; } $quoted .= $prefix . $_quote . $suffix . $this->eol . ' '; $value = substr($value, strlen($_quote)); $add_len = strlen($prefix . $suffix) + 4; // 2 x SPACE, '"', ';' $len = strlen($value) + $add_len; } $quoted .= $prefix . $value . $suffix; } return " {$name}=\"{$quoted}\""; } /** * Return charset for mbstring functions. * Replace ISO-2022-JP with ISO-2022-JP-MS to convert Windows dependent * characters. * * @param string $charset A original charset * * @return string A charset for mbstring * @since 1.10.8 */ protected static function mbstringCharset($charset) { $mb_charset = $charset; if ($charset == 'ISO-2022-JP') { $mb_charset = 'ISO-2022-JP-MS'; } return $mb_charset; } /** * Encodes a header as per RFC2047 * * @param string $name The header name * @param string $value The header data to encode * @param string $charset Character set name * @param string $encoding Encoding name (base64 or quoted-printable) * @param string $eol End-of-line sequence. Default: "\r\n" * * @return string Encoded header data (without a name) * @since 1.6.1 */ public static function encodeHeader($name, $value, $charset = 'ISO-8859-1', $encoding = 'quoted-printable', $eol = "\r\n" ) { // Structured headers $comma_headers = array( 'from', 'to', 'cc', 'bcc', 'sender', 'reply-to', 'resent-from', 'resent-to', 'resent-cc', 'resent-bcc', 'resent-sender', 'resent-reply-to', 'mail-reply-to', 'mail-followup-to', 'return-receipt-to', 'disposition-notification-to', ); $other_headers = array( 'references', 'in-reply-to', 'message-id', 'resent-message-id', ); $name = strtolower($name); if (in_array($name, $comma_headers)) { $separator = ','; } else if (in_array($name, $other_headers)) { $separator = ' '; } if (!$charset) { $charset = 'ISO-8859-1'; } // exploding quoted strings as well as some regexes below do not // work properly with some charset e.g. ISO-2022-JP, we'll use UTF-8 $mb = $charset != 'UTF-8' && function_exists('mb_convert_encoding'); $mb_charset = Mail_mimePart::mbstringCharset($charset); // Structured header (make sure addr-spec inside is not encoded) if (!empty($separator)) { // Simple e-mail address regexp $email_regexp = '([^\s<]+|("[^\r\n"]+"))@[^\s"]+'; if ($mb) { $value = mb_convert_encoding($value, 'UTF-8', $mb_charset); } $parts = Mail_mimePart::explodeQuotedString("[\t$separator]", $value); $value = ''; foreach ($parts as $part) { $part = preg_replace('/\r?\n[\s\t]*/', $eol . ' ', $part); $part = trim($part); if (!$part) { continue; } if ($value) { $value .= $separator == ',' ? $separator . ' ' : ' '; } else { $value = $name . ': '; } // let's find phrase (name) and/or addr-spec if (preg_match('/^<' . $email_regexp . '>$/', $part)) { $value .= $part; } else if (preg_match('/^' . $email_regexp . '$/', $part)) { // address without brackets and without name $value .= $part; } else if (preg_match('/<*' . $email_regexp . '>*$/', $part, $matches)) { // address with name (handle name) $address = $matches[0]; $word = str_replace($address, '', $part); $word = trim($word); // check if phrase requires quoting if ($word) { // non-ASCII: require encoding if (preg_match('#([^\s\x21-\x7E]){1}#', $word)) { if ($word[0] == '"' && $word[strlen($word)-1] == '"') { // de-quote quoted-string, encoding changes // string to atom $word = substr($word, 1, -1); $word = preg_replace('/\\\\([\\\\"])/', '$1', $word); } if ($mb) { $word = mb_convert_encoding($word, $mb_charset, 'UTF-8'); } // find length of last line if (($pos = strrpos($value, $eol)) !== false) { $last_len = strlen($value) - $pos; } else { $last_len = strlen($value); } $word = Mail_mimePart::encodeHeaderValue( $word, $charset, $encoding, $last_len, $eol ); } else if (($word[0] != '"' || $word[strlen($word)-1] != '"') && preg_match('/[\(\)\<\>\\\.\[\]@,;:"]/', $word) ) { // ASCII: quote string if needed $word = '"'.addcslashes($word, '\\"').'"'; } } $value .= $word.' '.$address; } else { if ($mb) { $part = mb_convert_encoding($part, $mb_charset, 'UTF-8'); } // addr-spec not found, don't encode (?) $value .= $part; } // RFC2822 recommends 78 characters limit, use 76 from RFC2047 $value = wordwrap($value, 76, $eol . ' '); } // remove header name prefix (there could be EOL too) $value = preg_replace( '/^'.$name.':('.preg_quote($eol, '/').')* /', '', $value ); } else { // Unstructured header // non-ASCII: require encoding if (preg_match('#([^\s\x21-\x7E]){1}#', $value)) { if ($value[0] == '"' && $value[strlen($value)-1] == '"') { if ($mb) { $value = mb_convert_encoding($value, 'UTF-8', $mb_charset); } // de-quote quoted-string, encoding changes // string to atom $value = substr($value, 1, -1); $value = preg_replace('/\\\\([\\\\"])/', '$1', $value); if ($mb) { $value = mb_convert_encoding($value, $mb_charset, 'UTF-8'); } } $value = Mail_mimePart::encodeHeaderValue( $value, $charset, $encoding, strlen($name) + 2, $eol ); } else if (strlen($name.': '.$value) > 78) { // ASCII: check if header line isn't too long and use folding $value = preg_replace('/\r?\n[\s\t]*/', $eol . ' ', $value); $tmp = wordwrap($name . ': ' . $value, 78, $eol . ' '); $value = preg_replace('/^' . $name . ':\s*/', '', $tmp); // hard limit 998 (RFC2822) $value = wordwrap($value, 998, $eol . ' ', true); } } return $value; } /** * Explode quoted string * * @param string $delimiter Delimiter expression string for preg_match() * @param string $string Input string * * @return array String tokens array */ protected static function explodeQuotedString($delimiter, $string) { $result = array(); $strlen = strlen($string); $quoted_string = '"(?:[^"\\\\]|\\\\.)*"'; for ($p=$i=0; $i < $strlen; $i++) { if ($string[$i] === '"') { $r = preg_match("/$quoted_string/", $string, $matches, 0, $i); if (!$r || empty($matches[0])) { break; } $i += strlen($matches[0]) - 1; } else if (preg_match("/$delimiter/", $string[$i])) { $result[] = substr($string, $p, $i - $p); $p = $i + 1; } } $result[] = substr($string, $p); return $result; } /** * Encodes a header value as per RFC2047 * * @param string $value The header data to encode * @param string $charset Character set name * @param string $encoding Encoding name (base64 or quoted-printable) * @param int $prefix_len Prefix length. Default: 0 * @param string $eol End-of-line sequence. Default: "\r\n" * * @return string Encoded header data * @since 1.6.1 */ public static function encodeHeaderValue($value, $charset, $encoding, $prefix_len = 0, $eol = "\r\n") { // #17311: Use multibyte aware method (requires mbstring extension) if ($result = Mail_mimePart::encodeMB($value, $charset, $encoding, $prefix_len, $eol)) { return $result; } // Generate the header using the specified params and dynamicly // determine the maximum length of such strings. // 75 is the value specified in the RFC. $encoding = $encoding == 'base64' ? 'B' : 'Q'; $prefix = '=?' . $charset . '?' . $encoding .'?'; $suffix = '?='; $maxLength = 75 - strlen($prefix . $suffix); $maxLength1stLine = $maxLength - $prefix_len; if ($encoding == 'B') { // Base64 encode the entire string $value = base64_encode($value); // We can cut base64 every 4 characters, so the real max // we can get must be rounded down. $maxLength = $maxLength - ($maxLength % 4); $maxLength1stLine = $maxLength1stLine - ($maxLength1stLine % 4); $cutpoint = $maxLength1stLine; $output = ''; while ($value) { // Split translated string at every $maxLength $part = substr($value, 0, $cutpoint); $value = substr($value, $cutpoint); $cutpoint = $maxLength; // RFC 2047 specifies that any split header should // be separated by a CRLF SPACE. if ($output) { $output .= $eol . ' '; } $output .= $prefix . $part . $suffix; } $value = $output; } else { // quoted-printable encoding has been selected $value = Mail_mimePart::encodeQP($value); // This regexp will break QP-encoded text at every $maxLength // but will not break any encoded letters. $reg1st = "|(.{0,$maxLength1stLine}[^\=][^\=])|"; $reg2nd = "|(.{0,$maxLength}[^\=][^\=])|"; if (strlen($value) > $maxLength1stLine) { // Begin with the regexp for the first line. $reg = $reg1st; $output = ''; while ($value) { // Split translated string at every $maxLength // But make sure not to break any translated chars. $found = preg_match($reg, $value, $matches); // After this first line, we need to use a different // regexp for the first line. $reg = $reg2nd; // Save the found part and encapsulate it in the // prefix & suffix. Then remove the part from the // $value_out variable. if ($found) { $part = $matches[0]; $len = strlen($matches[0]); $value = substr($value, $len); } else { $part = $value; $value = ''; } // RFC 2047 specifies that any split header should // be separated by a CRLF SPACE if ($output) { $output .= $eol . ' '; } $output .= $prefix . $part . $suffix; } $value = $output; } else { $value = $prefix . $value . $suffix; } } return $value; } /** * Encodes the given string using quoted-printable * * @param string $str String to encode * * @return string Encoded string * @since 1.6.0 */ public static function encodeQP($str) { // Bug #17226 RFC 2047 restricts some characters // if the word is inside a phrase, permitted chars are only: // ASCII letters, decimal digits, "!", "*", "+", "-", "/", "=", and "_" // "=", "_", "?" must be encoded $regexp = '/([\x22-\x29\x2C\x2E\x3A-\x40\x5B-\x60\x7B-\x7E\x80-\xFF])/'; $str = preg_replace_callback( $regexp, array('Mail_mimePart', 'qpReplaceCallback'), $str ); return str_replace(' ', '_', $str); } /** * Encodes the given string using base64 or quoted-printable. * This method makes sure that encoded-word represents an integral * number of characters as per RFC2047. * * @param string $str String to encode * @param string $charset Character set name * @param string $encoding Encoding name (base64 or quoted-printable) * @param int $prefix_len Prefix length. Default: 0 * @param string $eol End-of-line sequence. Default: "\r\n" * * @return string Encoded string * @since 1.8.0 */ public static function encodeMB($str, $charset, $encoding, $prefix_len=0, $eol="\r\n") { if (!function_exists('mb_substr') || !function_exists('mb_strlen')) { return; } $encoding = $encoding == 'base64' ? 'B' : 'Q'; // 75 is the value specified in the RFC $prefix = '=?' . $charset . '?'.$encoding.'?'; $suffix = '?='; $maxLength = 75 - strlen($prefix . $suffix); $mb_charset = Mail_mimePart::mbstringCharset($charset); // A multi-octet character may not be split across adjacent encoded-words // So, we'll loop over each character // mb_stlen() with wrong charset will generate a warning here and return null $length = mb_strlen($str, $mb_charset); $result = ''; $line_length = $prefix_len; if ($encoding == 'B') { // base64 $start = 0; $prev = ''; for ($i=1; $i<=$length; $i++) { // See #17311 $chunk = mb_substr($str, $start, $i-$start, $mb_charset); $chunk = base64_encode($chunk); $chunk_len = strlen($chunk); if ($line_length + $chunk_len == $maxLength || $i == $length) { if ($result) { $result .= "\n"; } $result .= $chunk; $line_length = 0; $start = $i; } else if ($line_length + $chunk_len > $maxLength) { if ($result) { $result .= "\n"; } if ($prev) { $result .= $prev; } $line_length = 0; $start = $i - 1; } else { $prev = $chunk; } } } else { // quoted-printable // see encodeQP() $regexp = '/([\x22-\x29\x2C\x2E\x3A-\x40\x5B-\x60\x7B-\x7E\x80-\xFF])/'; for ($i=0; $i<=$length; $i++) { $char = mb_substr($str, $i, 1, $mb_charset); // RFC recommends underline (instead of =20) in place of the space // that's one of the reasons why we're not using iconv_mime_encode() if ($char == ' ') { $char = '_'; $char_len = 1; } else { $char = preg_replace_callback( $regexp, array('Mail_mimePart', 'qpReplaceCallback'), $char ); $char_len = strlen($char); } if ($line_length + $char_len > $maxLength) { if ($result) { $result .= "\n"; } $line_length = 0; } $result .= $char; $line_length += $char_len; } } if ($result) { $result = $prefix .str_replace("\n", $suffix.$eol.' '.$prefix, $result).$suffix; } return $result; } /** * Callback function to replace extended characters (\x80-xFF) with their * ASCII values (RFC2047: quoted-printable) * * @param array $matches Preg_replace's matches array * * @return string Encoded character string */ protected static function qpReplaceCallback($matches) { return sprintf('=%02X', ord($matches[1])); } /** * Callback function to replace extended characters (\x80-xFF) with their * ASCII values (RFC2231) * * @param array $matches Preg_replace's matches array * * @return string Encoded character string */ protected static function encodeReplaceCallback($matches) { return sprintf('%%%02X', ord($matches[1])); } /** * PEAR::raiseError implementation * * @param string $message A text error message * * @return PEAR_Error Instance of PEAR_Error */ public static function raiseError($message) { // PEAR::raiseError() is not PHP 5.4 compatible return new PEAR_Error($message); } } PK�����u]E@%>��>����Mail/sendmail.phpnu�[��������<?php /** * Sendmail implementation of the PEAR Mail interface. * * PHP version 5 * * LICENSE: * * Copyright (c) 2010-2017, Chuck Hagenbuch & Jon Parise * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are 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. Neither the name of the copyright holder nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS 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 COPYRIGHT * HOLDER OR 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. * * @category Mail * @package Mail * @author Jon Parise <jon@php.net> * @author Chuck Hagenbuch <chuck@horde.org> * @copyright 2010-2017 Chuck Hagenbuch * @license http://opensource.org/licenses/BSD-3-Clause New BSD License * @version CVS: $Id$ * @link http://pear.php.net/package/Mail/ */ /** * Sendmail implementation of the PEAR Mail:: interface. * @access public * @package Mail * @version $Revision$ */ class Mail_sendmail extends Mail { /** * The location of the sendmail or sendmail wrapper binary on the * filesystem. * @var string */ var $sendmail_path = '/usr/sbin/sendmail'; /** * Any extra command-line parameters to pass to the sendmail or * sendmail wrapper binary. * @var string */ var $sendmail_args = '-i'; /** * Constructor. * * Instantiates a new Mail_sendmail:: object based on the parameters * passed in. It looks for the following parameters: * sendmail_path The location of the sendmail binary on the * filesystem. Defaults to '/usr/sbin/sendmail'. * * sendmail_args Any extra parameters to pass to the sendmail * or sendmail wrapper binary. * * If a parameter is present in the $params array, it replaces the * default. * * @param array $params Hash containing any parameters different from the * defaults. */ public function __construct($params) { if (isset($params['sendmail_path'])) { $this->sendmail_path = $params['sendmail_path']; } if (isset($params['sendmail_args'])) { $this->sendmail_args = $params['sendmail_args']; } /* * Because we need to pass message headers to the sendmail program on * the commandline, we can't guarantee the use of the standard "\r\n" * separator. Instead, we use the system's native line separator. */ if (defined('PHP_EOL')) { $this->sep = PHP_EOL; } else { $this->sep = (strpos(PHP_OS, 'WIN') === false) ? "\n" : "\r\n"; } } /** * Implements Mail::send() function using the sendmail * command-line binary. * * @param mixed $recipients Either a comma-seperated list of recipients * (RFC822 compliant), or an array of recipients, * each RFC822 valid. This may contain recipients not * specified in the headers, for Bcc:, resending * messages, etc. * * @param array $headers The array of headers to send with the mail, in an * associative array, where the array key is the * header name (ie, 'Subject'), and the array value * is the header value (ie, 'test'). The header * produced from those values would be 'Subject: * test'. * * @param string $body The full text of the message body, including any * Mime parts, etc. * * @return mixed Returns true on success, or a PEAR_Error * containing a descriptive error message on * failure. */ public function send($recipients, $headers, $body) { if (!is_array($headers)) { return PEAR::raiseError('$headers must be an array'); } $result = $this->_sanitizeHeaders($headers); if (is_a($result, 'PEAR_Error')) { return $result; } $recipients = $this->parseRecipients($recipients); if (is_a($recipients, 'PEAR_Error')) { return $recipients; } $recipients = implode(' ', array_map('escapeshellarg', $recipients)); $headerElements = $this->prepareHeaders($headers); if (is_a($headerElements, 'PEAR_Error')) { return $headerElements; } list($from, $text_headers) = $headerElements; /* Since few MTAs are going to allow this header to be forged * unless it's in the MAIL FROM: exchange, we'll use * Return-Path instead of From: if it's set. */ if (!empty($headers['Return-Path'])) { $from = $headers['Return-Path']; } if (!isset($from)) { return PEAR::raiseError('No from address given.'); } elseif (strpos($from, ' ') !== false || strpos($from, ';') !== false || strpos($from, '&') !== false || strpos($from, '`') !== false) { return PEAR::raiseError('From address specified with dangerous characters.'); } $from = escapeshellarg($from); // Security bug #16200 $mail = @popen($this->sendmail_path . (!empty($this->sendmail_args) ? ' ' . $this->sendmail_args : '') . " -f$from -- $recipients", 'w'); if (!$mail) { return PEAR::raiseError('Failed to open sendmail [' . $this->sendmail_path . '] for execution.'); } // Write the headers following by two newlines: one to end the headers // section and a second to separate the headers block from the body. fputs($mail, $text_headers . $this->sep . $this->sep); fputs($mail, $body); $result = pclose($mail); if (version_compare(phpversion(), '4.2.3') == -1) { // With older php versions, we need to shift the pclose // result to get the exit code. $result = $result >> 8 & 0xFF; } if ($result != 0) { return PEAR::raiseError('sendmail returned error code ' . $result, $result); } return true; } } PK�����u]B_Ǭ=��=�� ��Mail/smtp.phpnu�[��������<?php /** * SMTP implementation of the PEAR Mail interface. Requires the Net_SMTP class. * * PHP version 5 * * LICENSE: * * Copyright (c) 2010-2017, Chuck Hagenbuch & Jon Parise * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are 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. Neither the name of the copyright holder nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS 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 COPYRIGHT * HOLDER OR 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. * * @category HTTP * @package HTTP_Request * @author Jon Parise <jon@php.net> * @author Chuck Hagenbuch <chuck@horde.org> * @copyright 2010-2017 Chuck Hagenbuch * @license http://opensource.org/licenses/BSD-3-Clause New BSD License * @version CVS: $Id$ * @link http://pear.php.net/package/Mail/ */ /** Error: Failed to create a Net_SMTP object */ define('PEAR_MAIL_SMTP_ERROR_CREATE', 10000); /** Error: Failed to connect to SMTP server */ define('PEAR_MAIL_SMTP_ERROR_CONNECT', 10001); /** Error: SMTP authentication failure */ define('PEAR_MAIL_SMTP_ERROR_AUTH', 10002); /** Error: No From: address has been provided */ define('PEAR_MAIL_SMTP_ERROR_FROM', 10003); /** Error: Failed to set sender */ define('PEAR_MAIL_SMTP_ERROR_SENDER', 10004); /** Error: Failed to add recipient */ define('PEAR_MAIL_SMTP_ERROR_RECIPIENT', 10005); /** Error: Failed to send data */ define('PEAR_MAIL_SMTP_ERROR_DATA', 10006); /** * SMTP implementation of the PEAR Mail interface. Requires the Net_SMTP class. * @access public * @package Mail * @version $Revision$ */ class Mail_smtp extends Mail { /** * SMTP connection object. * * @var object * @access private */ var $_smtp = null; /** * The list of service extension parameters to pass to the Net_SMTP * mailFrom() command. * * @var array */ var $_extparams = array(); /** * The SMTP host to connect to. * * @var string */ var $host = 'localhost'; /** * The port the SMTP server is on. * * @var integer */ var $port = 25; /** * Should SMTP authentication be used? * * This value may be set to true, false or the name of a specific * authentication method. * * If the value is set to true, the Net_SMTP package will attempt to use * the best authentication method advertised by the remote SMTP server. * * @var mixed */ var $auth = false; /** * The username to use if the SMTP server requires authentication. * * @var string */ var $username = ''; /** * The password to use if the SMTP server requires authentication. * * @var string */ var $password = ''; /** * Hostname or domain that will be sent to the remote SMTP server in the * HELO / EHLO message. * * @var string */ var $localhost = 'localhost'; /** * SMTP connection timeout value. NULL indicates no timeout. * * @var integer */ var $timeout = null; /** * Turn on Net_SMTP debugging? * * @var boolean $debug */ var $debug = false; /** * Indicates whether or not the SMTP connection should persist over * multiple calls to the send() method. * * @var boolean */ var $persist = false; /** * Use SMTP command pipelining (specified in RFC 2920) if the SMTP server * supports it. This speeds up delivery over high-latency connections. By * default, use the default value supplied by Net_SMTP. * * @var boolean */ var $pipelining; /** * The list of socket options * * @var array */ var $socket_options = array(); /** * Constructor. * * Instantiates a new Mail_smtp:: object based on the parameters * passed in. It looks for the following parameters: * host The server to connect to. Defaults to localhost. * port The port to connect to. Defaults to 25. * auth SMTP authentication. Defaults to none. * username The username to use for SMTP auth. No default. * password The password to use for SMTP auth. No default. * localhost The local hostname / domain. Defaults to localhost. * timeout The SMTP connection timeout. Defaults to none. * verp Whether to use VERP or not. Defaults to false. * DEPRECATED as of 1.2.0 (use setMailParams()). * debug Activate SMTP debug mode? Defaults to false. * persist Should the SMTP connection persist? * pipelining Use SMTP command pipelining * * If a parameter is present in the $params array, it replaces the * default. * * @param array Hash containing any parameters different from the * defaults. */ public function __construct($params) { if (isset($params['host'])) $this->host = $params['host']; if (isset($params['port'])) $this->port = $params['port']; if (isset($params['auth'])) $this->auth = $params['auth']; if (isset($params['username'])) $this->username = $params['username']; if (isset($params['password'])) $this->password = $params['password']; if (isset($params['localhost'])) $this->localhost = $params['localhost']; if (isset($params['timeout'])) $this->timeout = $params['timeout']; if (isset($params['debug'])) $this->debug = (bool)$params['debug']; if (isset($params['persist'])) $this->persist = (bool)$params['persist']; if (isset($params['pipelining'])) $this->pipelining = (bool)$params['pipelining']; if (isset($params['socket_options'])) $this->socket_options = $params['socket_options']; // Deprecated options if (isset($params['verp'])) { $this->addServiceExtensionParameter('XVERP', is_bool($params['verp']) ? null : $params['verp']); } } /** * Destructor implementation to ensure that we disconnect from any * potentially-alive persistent SMTP connections. */ public function __destruct() { $this->disconnect(); } /** * Implements Mail::send() function using SMTP. * * @param mixed $recipients Either a comma-seperated list of recipients * (RFC822 compliant), or an array of recipients, * each RFC822 valid. This may contain recipients not * specified in the headers, for Bcc:, resending * messages, etc. * * @param array $headers The array of headers to send with the mail, in an * associative array, where the array key is the * header name (e.g., 'Subject'), and the array value * is the header value (e.g., 'test'). The header * produced from those values would be 'Subject: * test'. * * @param string $body The full text of the message body, including any * MIME parts, etc. * * @return mixed Returns true on success, or a PEAR_Error * containing a descriptive error message on * failure. */ public function send($recipients, $headers, $body) { $result = $this->send_or_fail($recipients, $headers, $body); /* If persistent connections are disabled, destroy our SMTP object. */ if ($this->persist === false) { $this->disconnect(); } return $result; } protected function send_or_fail($recipients, $headers, $body) { /* If we don't already have an SMTP object, create one. */ $result = $this->getSMTPObject(); if (PEAR::isError($result)) { return $result; } if (!is_array($headers)) { return PEAR::raiseError('$headers must be an array'); } $this->_sanitizeHeaders($headers); $headerElements = $this->prepareHeaders($headers); if (is_a($headerElements, 'PEAR_Error')) { $this->_smtp->rset(); return $headerElements; } list($from, $textHeaders) = $headerElements; /* Since few MTAs are going to allow this header to be forged * unless it's in the MAIL FROM: exchange, we'll use * Return-Path instead of From: if it's set. */ if (!empty($headers['Return-Path'])) { $from = $headers['Return-Path']; } if (!isset($from)) { $this->_smtp->rset(); return PEAR::raiseError('No From: address has been provided', PEAR_MAIL_SMTP_ERROR_FROM); } $params = null; if (!empty($this->_extparams)) { foreach ($this->_extparams as $key => $val) { $params .= ' ' . $key . (is_null($val) ? '' : '=' . $val); } } if (PEAR::isError($res = $this->_smtp->mailFrom($from, ltrim($params)))) { $error = $this->_error("Failed to set sender: $from", $res); $this->_smtp->rset(); return PEAR::raiseError($error, PEAR_MAIL_SMTP_ERROR_SENDER); } $recipients = $this->parseRecipients($recipients); if (is_a($recipients, 'PEAR_Error')) { $this->_smtp->rset(); return $recipients; } foreach ($recipients as $recipient) { $res = $this->_smtp->rcptTo($recipient); if (is_a($res, 'PEAR_Error')) { $error = $this->_error("Failed to add recipient: $recipient", $res); $this->_smtp->rset(); return PEAR::raiseError($error, PEAR_MAIL_SMTP_ERROR_RECIPIENT); } } /* Send the message's headers and the body as SMTP data. */ $res = $this->_smtp->data($body, $textHeaders); list(,$args) = $this->_smtp->getResponse(); if (preg_match("/ queued as (.*)/", $args, $queued)) { $this->queued_as = $queued[1]; } /* we need the greeting; from it we can extract the authorative name of the mail server we've really connected to. * ideal if we're connecting to a round-robin of relay servers and need to track which exact one took the email */ $this->greeting = $this->_smtp->getGreeting(); if (is_a($res, 'PEAR_Error')) { $error = $this->_error('Failed to send data', $res); $this->_smtp->rset(); return PEAR::raiseError($error, PEAR_MAIL_SMTP_ERROR_DATA); } return true; } /** * Connect to the SMTP server by instantiating a Net_SMTP object. * * @return mixed Returns a reference to the Net_SMTP object on success, or * a PEAR_Error containing a descriptive error message on * failure. * * @since 1.2.0 */ public function getSMTPObject() { if (is_object($this->_smtp) !== false) { return $this->_smtp; } include_once 'Net/SMTP.php'; $this->_smtp = new Net_SMTP($this->host, $this->port, $this->localhost, $this->pipelining, 0, $this->socket_options); /* If we still don't have an SMTP object at this point, fail. */ if (is_object($this->_smtp) === false) { return PEAR::raiseError('Failed to create a Net_SMTP object', PEAR_MAIL_SMTP_ERROR_CREATE); } /* Configure the SMTP connection. */ if ($this->debug) { $this->_smtp->setDebug(true); } /* Attempt to connect to the configured SMTP server. */ if (PEAR::isError($res = $this->_smtp->connect($this->timeout))) { $error = $this->_error('Failed to connect to ' . $this->host . ':' . $this->port, $res); return PEAR::raiseError($error, PEAR_MAIL_SMTP_ERROR_CONNECT); } /* Attempt to authenticate if authentication has been enabled. */ if ($this->auth) { $method = is_string($this->auth) ? $this->auth : ''; if (PEAR::isError($res = $this->_smtp->auth($this->username, $this->password, $method))) { $error = $this->_error("$method authentication failure", $res); $this->_smtp->rset(); return PEAR::raiseError($error, PEAR_MAIL_SMTP_ERROR_AUTH); } } return $this->_smtp; } /** * Add parameter associated with a SMTP service extension. * * @param string Extension keyword. * @param string Any value the keyword needs. * * @since 1.2.0 */ public function addServiceExtensionParameter($keyword, $value = null) { $this->_extparams[$keyword] = $value; } /** * Disconnect and destroy the current SMTP connection. * * @return boolean True if the SMTP connection no longer exists. * * @since 1.1.9 */ public function disconnect() { /* If we have an SMTP object, disconnect and destroy it. */ if (is_object($this->_smtp) && $this->_smtp->disconnect()) { $this->_smtp = null; } /* We are disconnected if we no longer have an SMTP object. */ return ($this->_smtp === null); } /** * Build a standardized string describing the current SMTP error. * * @param string $text Custom string describing the error context. * @param object $error Reference to the current PEAR_Error object. * * @return string A string describing the current SMTP error. * * @since 1.1.7 */ protected function _error($text, $error) { /* Split the SMTP response into a code and a response string. */ list($code, $response) = $this->_smtp->getResponse(); /* Build our standardized error string. */ return $text . ' [SMTP: ' . $error->getMessage() . " (code: $code, response: $response)]"; } } PK�����u]Bsh��h�� ��Mail/mock.phpnu�[��������<?php /** * Mock implementation * * PHP version 5 * * LICENSE: * * Copyright (c) 2010-2017, Chuck Hagenbuch * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are 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. Neither the name of the copyright holder nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS 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 COPYRIGHT * HOLDER OR 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. * * @category Mail * @package Mail * @author Chuck Hagenbuch <chuck@horde.org> * @copyright 2010-2017 Chuck Hagenbuch * @license http://opensource.org/licenses/BSD-3-Clause New BSD License * @version CVS: $Id$ * @link http://pear.php.net/package/Mail/ */ /** * Mock implementation of the PEAR Mail:: interface for testing. * @access public * @package Mail * @version $Revision$ */ class Mail_mock extends Mail { /** * Array of messages that have been sent with the mock. * * @var array */ public $sentMessages = array(); /** * Callback before sending mail. * * @var callback */ protected $_preSendCallback; /** * Callback after sending mai. * * @var callback */ protected $_postSendCallback; /** * Constructor. * * Instantiates a new Mail_mock:: object based on the parameters * passed in. It looks for the following parameters, both optional: * preSendCallback Called before an email would be sent. * postSendCallback Called after an email would have been sent. * * @param array Hash containing any parameters. */ public function __construct($params) { if (isset($params['preSendCallback']) && is_callable($params['preSendCallback'])) { $this->_preSendCallback = $params['preSendCallback']; } if (isset($params['postSendCallback']) && is_callable($params['postSendCallback'])) { $this->_postSendCallback = $params['postSendCallback']; } } /** * Implements Mail_mock::send() function. Silently discards all * mail. * * @param mixed $recipients Either a comma-seperated list of recipients * (RFC822 compliant), or an array of recipients, * each RFC822 valid. This may contain recipients not * specified in the headers, for Bcc:, resending * messages, etc. * * @param array $headers The array of headers to send with the mail, in an * associative array, where the array key is the * header name (ie, 'Subject'), and the array value * is the header value (ie, 'test'). The header * produced from those values would be 'Subject: * test'. * * @param string $body The full text of the message body, including any * Mime parts, etc. * * @return mixed Returns true on success, or a PEAR_Error * containing a descriptive error message on * failure. */ public function send($recipients, $headers, $body) { if ($this->_preSendCallback) { call_user_func_array($this->_preSendCallback, array(&$this, $recipients, $headers, $body)); } $entry = array('recipients' => $recipients, 'headers' => $headers, 'body' => $body); $this->sentMessages[] = $entry; if ($this->_postSendCallback) { call_user_func_array($this->_postSendCallback, array(&$this, $recipients, $headers, $body)); } return true; } } PK�����u]x ع������Mail/mimeDecode.phpnu�[��������<?php /** * The Mail_mimeDecode class is used to decode mail/mime messages * * This class will parse a raw mime email and return * the structure. Returned structure is similar to * that returned by imap_fetchstructure(). * * +----------------------------- IMPORTANT ------------------------------+ * | Usage of this class compared to native php extensions such as | * | mailparse or imap, is slow and may be feature deficient. If available| * | you are STRONGLY recommended to use the php extensions. | * +----------------------------------------------------------------------+ * * Compatible with PHP versions 4 and 5 * * LICENSE: This LICENSE is in the BSD license style. * Copyright (c) 2002-2003, Richard Heyes <richard@phpguru.org> * Copyright (c) 2003-2006, PEAR <pear-group@php.net> * All rights reserved. * * Redistribution and use in source and binary forms, with or * without modification, are permitted provided that the following * conditions are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * - 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. * - Neither the name of the authors, nor the names of its contributors * may be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS 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 COPYRIGHT OWNER OR 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. * * @category Mail * @package Mail_Mime * @author Richard Heyes <richard@phpguru.org> * @author George Schlossnagle <george@omniti.com> * @author Cipriano Groenendal <cipri@php.net> * @author Sean Coates <sean@php.net> * @copyright 2003-2006 PEAR <pear-group@php.net> * @license http://www.opensource.org/licenses/bsd-license.php BSD License * @version CVS: $Id: mimeDecode.php 337165 2015-07-15 09:42:08Z alan_k $ * @link http://pear.php.net/package/Mail_mime */ /** * require PEAR * * This package depends on PEAR to raise errors. */ require_once 'PEAR.php'; /** * The Mail_mimeDecode class is used to decode mail/mime messages * * This class will parse a raw mime email and return the structure. * Returned structure is similar to that returned by imap_fetchstructure(). * * +----------------------------- IMPORTANT ------------------------------+ * | Usage of this class compared to native php extensions such as | * | mailparse or imap, is slow and may be feature deficient. If available| * | you are STRONGLY recommended to use the php extensions. | * +----------------------------------------------------------------------+ * * @category Mail * @package Mail_Mime * @author Richard Heyes <richard@phpguru.org> * @author George Schlossnagle <george@omniti.com> * @author Cipriano Groenendal <cipri@php.net> * @author Sean Coates <sean@php.net> * @copyright 2003-2006 PEAR <pear-group@php.net> * @license http://www.opensource.org/licenses/bsd-license.php BSD License * @version Release: @package_version@ * @link http://pear.php.net/package/Mail_mime */ class Mail_mimeDecode extends PEAR { /** * The raw email to decode * * @var string * @access private */ var $_input; /** * The header part of the input * * @var string * @access private */ var $_header; /** * The body part of the input * * @var string * @access private */ var $_body; /** * If an error occurs, this is used to store the message * * @var string * @access private */ var $_error; /** * Flag to determine whether to include bodies in the * returned object. * * @var boolean * @access private */ var $_include_bodies; /** * Flag to determine whether to decode bodies * * @var boolean * @access private */ var $_decode_bodies; /** * Flag to determine whether to decode headers * (set to UTF8 to iconv convert headers) * @var mixed * @access private */ var $_decode_headers; /** * Flag to determine whether to include attached messages * as body in the returned object. Depends on $_include_bodies * * @var boolean * @access private */ var $_rfc822_bodies; /** * Constructor. * * Sets up the object, initialise the variables, and splits and * stores the header and body of the input. * * @param string The input to decode * @access public */ function __construct($input) { list($header, $body) = $this->_splitBodyHeader($input); $this->_input = $input; $this->_header = $header; $this->_body = $body; $this->_decode_bodies = false; $this->_include_bodies = true; $this->_rfc822_bodies = false; } // BC function Mail_mimeDecode($input) { $this->__construct($input); } /** * Begins the decoding process. If called statically * it will create an object and call the decode() method * of it. * * @param array An array of various parameters that determine * various things: * include_bodies - Whether to include the body in the returned * object. * decode_bodies - Whether to decode the bodies * of the parts. (Transfer encoding) * decode_headers - Whether to decode headers, * - use "UTF8//IGNORE" to convert charset. * * input - If called statically, this will be treated * as the input * @return object Decoded results * @access public */ function decode($params = null) { // determine if this method has been called statically $isStatic = empty($this) || !is_a($this, __CLASS__); // Have we been called statically? // If so, create an object and pass details to that. if ($isStatic AND isset($params['input'])) { $obj = new Mail_mimeDecode($params['input']); $structure = $obj->decode($params); // Called statically but no input } elseif ($isStatic) { return PEAR::raiseError('Called statically and no input given'); // Called via an object } else { $this->_include_bodies = isset($params['include_bodies']) ? $params['include_bodies'] : false; $this->_decode_bodies = isset($params['decode_bodies']) ? $params['decode_bodies'] : false; $this->_decode_headers = isset($params['decode_headers']) ? $params['decode_headers'] : false; $this->_rfc822_bodies = isset($params['rfc_822bodies']) ? $params['rfc_822bodies'] : false; if (is_string($this->_decode_headers) && !function_exists('iconv')) { PEAR::raiseError('header decode conversion requested, however iconv is missing'); } $structure = $this->_decode($this->_header, $this->_body); if ($structure === false) { $structure = $this->raiseError($this->_error); } } return $structure; } /** * Performs the decoding. Decodes the body string passed to it * If it finds certain content-types it will call itself in a * recursive fashion * * @param string Header section * @param string Body section * @return object Results of decoding process * @access private */ function _decode($headers, $body, $default_ctype = 'text/plain') { $return = new stdClass; $return->headers = array(); $headers = $this->_parseHeaders($headers); foreach ($headers as $value) { $value['value'] = $this->_decodeHeader($value['value']); if (isset($return->headers[strtolower($value['name'])]) AND !is_array($return->headers[strtolower($value['name'])])) { $return->headers[strtolower($value['name'])] = array($return->headers[strtolower($value['name'])]); $return->headers[strtolower($value['name'])][] = $value['value']; } elseif (isset($return->headers[strtolower($value['name'])])) { $return->headers[strtolower($value['name'])][] = $value['value']; } else { $return->headers[strtolower($value['name'])] = $value['value']; } } foreach ($headers as $key => $value) { $headers[$key]['name'] = strtolower($headers[$key]['name']); switch ($headers[$key]['name']) { case 'content-type': $content_type = $this->_parseHeaderValue($headers[$key]['value']); if (preg_match('/([0-9a-z+.-]+)\/([0-9a-z+.-]+)/i', $content_type['value'], $regs)) { $return->ctype_primary = $regs[1]; $return->ctype_secondary = $regs[2]; } if (isset($content_type['other'])) { foreach($content_type['other'] as $p_name => $p_value) { $return->ctype_parameters[$p_name] = $p_value; } } break; case 'content-disposition': $content_disposition = $this->_parseHeaderValue($headers[$key]['value']); $return->disposition = $content_disposition['value']; if (isset($content_disposition['other'])) { foreach($content_disposition['other'] as $p_name => $p_value) { $return->d_parameters[$p_name] = $p_value; } } break; case 'content-transfer-encoding': $content_transfer_encoding = $this->_parseHeaderValue($headers[$key]['value']); break; } } if (isset($content_type)) { switch (strtolower($content_type['value'])) { case 'text/plain': $encoding = isset($content_transfer_encoding) ? $content_transfer_encoding['value'] : '7bit'; $this->_include_bodies ? $return->body = ($this->_decode_bodies ? $this->_decodeBody($body, $encoding) : $body) : null; break; case 'text/html': $encoding = isset($content_transfer_encoding) ? $content_transfer_encoding['value'] : '7bit'; $this->_include_bodies ? $return->body = ($this->_decode_bodies ? $this->_decodeBody($body, $encoding) : $body) : null; break; case 'multipart/signed': // PGP $parts = $this->_boundarySplit($body, $content_type['other']['boundary'], true); $return->parts['msg_body'] = $parts[0]; list($part_header, $part_body) = $this->_splitBodyHeader($parts[1]); $return->parts['sig_hdr'] = $part_header; $return->parts['sig_body'] = $part_body; break; case 'multipart/parallel': case 'multipart/appledouble': // Appledouble mail case 'multipart/report': // RFC1892 case 'multipart/signed': // PGP case 'multipart/digest': case 'multipart/alternative': case 'multipart/related': case 'multipart/relative': //#20431 - android case 'multipart/mixed': case 'application/vnd.wap.multipart.related': if(!isset($content_type['other']['boundary'])){ $this->_error = 'No boundary found for ' . $content_type['value'] . ' part'; return false; } $default_ctype = (strtolower($content_type['value']) === 'multipart/digest') ? 'message/rfc822' : 'text/plain'; $parts = $this->_boundarySplit($body, $content_type['other']['boundary']); for ($i = 0; $i < count($parts); $i++) { list($part_header, $part_body) = $this->_splitBodyHeader($parts[$i]); $part = $this->_decode($part_header, $part_body, $default_ctype); if($part === false) $part = $this->raiseError($this->_error); $return->parts[] = $part; } break; case 'message/rfc822': case 'message/delivery-status': // #bug #18693 if ($this->_rfc822_bodies) { $encoding = isset($content_transfer_encoding) ? $content_transfer_encoding['value'] : '7bit'; $return->body = ($this->_decode_bodies ? $this->_decodeBody($body, $encoding) : $body); } $obj = new Mail_mimeDecode($body); $return->parts[] = $obj->decode(array('include_bodies' => $this->_include_bodies, 'decode_bodies' => $this->_decode_bodies, 'decode_headers' => $this->_decode_headers)); unset($obj); break; default: if(!isset($content_transfer_encoding['value'])) $content_transfer_encoding['value'] = '7bit'; $this->_include_bodies ? $return->body = ($this->_decode_bodies ? $this->_decodeBody($body, $content_transfer_encoding['value']) : $body) : null; break; } } else { $ctype = explode('/', $default_ctype); $return->ctype_primary = $ctype[0]; $return->ctype_secondary = $ctype[1]; $this->_include_bodies ? $return->body = ($this->_decode_bodies ? $this->_decodeBody($body) : $body) : null; } return $return; } /** * Given the output of the above function, this will return an * array of references to the parts, indexed by mime number. * * @param object $structure The structure to go through * @param string $mime_number Internal use only. * @return array Mime numbers */ function &getMimeNumbers(&$structure, $no_refs = false, $mime_number = '', $prepend = '') { $return = array(); if (!empty($structure->parts)) { if ($mime_number != '') { $structure->mime_id = $prepend . $mime_number; $return[$prepend . $mime_number] = &$structure; } for ($i = 0; $i < count($structure->parts); $i++) { if (!empty($structure->headers['content-type']) AND substr(strtolower($structure->headers['content-type']), 0, 8) == 'message/') { $prepend = $prepend . $mime_number . '.'; $_mime_number = ''; } else { $_mime_number = ($mime_number == '' ? $i + 1 : sprintf('%s.%s', $mime_number, $i + 1)); } $arr = &Mail_mimeDecode::getMimeNumbers($structure->parts[$i], $no_refs, $_mime_number, $prepend); foreach ($arr as $key => $val) { $no_refs ? $return[$key] = '' : $return[$key] = &$arr[$key]; } } } else { if ($mime_number == '') { $mime_number = '1'; } $structure->mime_id = $prepend . $mime_number; $no_refs ? $return[$prepend . $mime_number] = '' : $return[$prepend . $mime_number] = &$structure; } return $return; } /** * Given a string containing a header and body * section, this function will split them (at the first * blank line) and return them. * * @param string Input to split apart * @return array Contains header and body section * @access private */ function _splitBodyHeader($input) { if (preg_match("/^(.*?)\r?\n\r?\n(.*)/s", $input, $match)) { return array($match[1], $match[2]); } // bug #17325 - empty bodies are allowed. - we just check that at least one line // of headers exist.. if (count(explode("\n",$input))) { return array($input, ''); } $this->_error = 'Could not split header and body'; return false; } /** * Parse headers given in $input and return * as assoc array. * * @param string Headers to parse * @return array Contains parsed headers * @access private */ function _parseHeaders($input) { if ($input !== '') { // Unfold the input $input = preg_replace("/\r?\n/", "\r\n", $input); //#7065 - wrapping.. with encoded stuff.. - probably not needed, // wrapping space should only get removed if the trailing item on previous line is a // encoded character $input = preg_replace("/=\r\n(\t| )+/", '=', $input); $input = preg_replace("/\r\n(\t| )+/", ' ', $input); $headers = explode("\r\n", trim($input)); $got_start = false; foreach ($headers as $value) { if (!$got_start) { // munge headers for mbox style from if ($value[0] == '>') { $value = substring($value, 1); // remove mbox > } if (substr($value,0,5) == 'From ') { $value = 'Return-Path: ' . substr($value, 5); } else { $got_start = true; } } $hdr_name = substr($value, 0, $pos = strpos($value, ':')); $hdr_value = substr($value, $pos+1); if($hdr_value[0] == ' ') { $hdr_value = substr($hdr_value, 1); } $return[] = array( 'name' => $hdr_name, 'value' => $hdr_value ); } } else { $return = array(); } return $return; } /** * Function to parse a header value, * extract first part, and any secondary * parts (after ;) This function is not as * robust as it could be. Eg. header comments * in the wrong place will probably break it. * * Extra things this can handle * filename*0=...... * filename*1=...... * * This is where lines are broken in, and need merging. * * filename*0*=ENC'lang'urlencoded data. * filename*1*=ENC'lang'urlencoded data. * * * * @param string Header value to parse * @return array Contains parsed result * @access private */ function _parseHeaderValue($input) { if (($pos = strpos($input, ';')) === false) { $input = $this->_decodeHeader($input); $return['value'] = trim($input); return $return; } $value = substr($input, 0, $pos); $value = $this->_decodeHeader($value); $return['value'] = trim($value); $input = trim(substr($input, $pos+1)); if (!strlen($input) > 0) { return $return; } // at this point input contains xxxx=".....";zzzz="...." // since we are dealing with quoted strings, we need to handle this properly.. $i = 0; $l = strlen($input); $key = ''; $val = false; // our string - including quotes.. $q = false; // in quote.. $lq = ''; // last quote.. while ($i < $l) { $c = $input[$i]; //var_dump(array('i'=>$i,'c'=>$c,'q'=>$q, 'lq'=>$lq, 'key'=>$key, 'val' =>$val)); $escaped = false; if ($c == '\\') { $i++; if ($i == $l-1) { // end of string. break; } $escaped = true; $c = $input[$i]; } // state - in key.. if ($val === false) { if (!$escaped && $c == '=') { $val = ''; $key = trim($key); $i++; continue; } if (!$escaped && $c == ';') { if ($key) { // a key without a value.. $key= trim($key); $return['other'][$key] = ''; } $key = ''; } $key .= $c; $i++; continue; } // state - in value.. (as $val is set..) if ($q === false) { // not in quote yet. if ((!strlen($val) || $lq !== false) && $c == ' ' || $c == "\t") { $i++; continue; // skip leading spaces after '=' or after '"' } // do not de-quote 'xxx*= itesm.. $key_is_trans = $key[strlen($key)-1] == '*'; if (!$key_is_trans && !$escaped && ($c == '"' || $c == "'")) { // start quoted area.. $q = $c; // in theory should not happen raw text in value part.. // but we will handle it as a merged part of the string.. $val = !strlen(trim($val)) ? '' : trim($val); $i++; continue; } // got end.... if (!$escaped && $c == ';') { $return['other'][$key] = trim($val); $val = false; $key = ''; $lq = false; $i++; continue; } $val .= $c; $i++; continue; } // state - in quote.. if (!$escaped && $c == $q) { // potential exit state.. // end of quoted string.. $lq = $q; $q = false; $i++; continue; } // normal char inside of quoted string.. $val.= $c; $i++; } // do we have anything left.. if (strlen(trim($key)) || $val !== false) { $val = trim($val); $return['other'][$key] = $val; } $clean_others = array(); // merge added values. eg. *1[*] foreach($return['other'] as $key =>$val) { if (preg_match('/\*[0-9]+\**$/', $key)) { $key = preg_replace('/(.*)\*[0-9]+(\**)$/', '\1\2', $key); if (isset($clean_others[$key])) { $clean_others[$key] .= $val; continue; } } $clean_others[$key] = $val; } // handle language translation of '*' ending others. foreach( $clean_others as $key =>$val) { if ( $key[strlen($key)-1] != '*') { $clean_others[strtolower($key)] = $val; continue; } unset($clean_others[$key]); $key = substr($key,0,-1); //extended-initial-value := [charset] "'" [language] "'" // extended-other-values $match = array(); $info = preg_match("/^([^']+)'([^']*)'(.*)$/", $val, $match); $clean_others[$key] = urldecode($match[3]); $clean_others[strtolower($key)] = $clean_others[$key]; $clean_others[strtolower($key).'-charset'] = $match[1]; $clean_others[strtolower($key).'-language'] = $match[2]; } $return['other'] = $clean_others; // decode values. foreach($return['other'] as $key =>$val) { $charset = isset($return['other'][$key . '-charset']) ? $return['other'][$key . '-charset'] : false; $return['other'][$key] = $this->_decodeHeader($val, $charset); } return $return; } /** * This function splits the input based * on the given boundary * * @param string Input to parse * @return array Contains array of resulting mime parts * @access private */ function _boundarySplit($input, $boundary, $eatline = false) { $parts = array(); $bs_possible = substr($boundary, 2, -2); $bs_check = '\"' . $bs_possible . '\"'; if ($boundary == $bs_check) { $boundary = $bs_possible; } // eatline is used by multipart/signed. $tmp = $eatline ? preg_split("/\r?\n--".preg_quote($boundary, '/')."(|--)\n/", $input) : preg_split("/--".preg_quote($boundary, '/')."((?=\s)|--)/", $input); $len = count($tmp) -1; for ($i = 1; $i < $len; $i++) { if (strlen(trim($tmp[$i]))) { $parts[] = $tmp[$i]; } } // add the last part on if it does not end with the 'closing indicator' if (!empty($tmp[$len]) && strlen(trim($tmp[$len])) && $tmp[$len][0] != '-') { $parts[] = $tmp[$len]; } return $parts; } /** * Given a header, this function will decode it * according to RFC2047. Probably not *exactly* * conformant, but it does pass all the given * examples (in RFC2047). * * @param string Input header value to decode * @return string Decoded header value * @access private */ function _decodeHeader($input, $default_charset=false) { if (!$this->_decode_headers) { return $input; } // Remove white space between encoded-words $input = preg_replace('/(=\?[^?]+\?(q|b)\?[^?]*\?=)(\s)+=\?/i', '\1=?', $input); // For each encoded-word... while (preg_match('/(=\?([^?]+)\?(q|b)\?([^?]*)\?=)/i', $input, $matches)) { $encoded = $matches[1]; $charset = $matches[2]; $encoding = $matches[3]; $text = $matches[4]; switch (strtolower($encoding)) { case 'b': $text = base64_decode($text); break; case 'q': $text = str_replace('_', ' ', $text); preg_match_all('/=([a-f0-9]{2})/i', $text, $matches); foreach($matches[1] as $value) $text = str_replace('='.$value, chr(hexdec($value)), $text); break; } if (is_string($this->_decode_headers)) { $conv = @iconv($charset, $this->_decode_headers, $text); $text = ($conv === false) ? $text : $conv; } $input = str_replace($encoded, $text, $input); } if ($default_charset && is_string($this->_decode_headers)) { $conv = @iconv($charset, $this->_decode_headers, $input); $input = ($conv === false) ? $input : $conv; } return $input; } /** * Given a body string and an encoding type, * this function will decode and return it. * * @param string Input body to decode * @param string Encoding type to use. * @return string Decoded body * @access private */ function _decodeBody($input, $encoding = '7bit') { switch (strtolower($encoding)) { case '7bit': return $input; break; case 'quoted-printable': return $this->_quotedPrintableDecode($input); break; case 'base64': return base64_decode($input); break; default: return $input; } } /** * Given a quoted-printable string, this * function will decode and return it. * * @param string Input body to decode * @return string Decoded body * @access private */ function _quotedPrintableDecode($input) { // Remove soft line breaks $input = preg_replace("/=\r?\n/", '', $input); // Replace encoded characters $cb = create_function('$matches', ' return chr(hexdec($matches[0]));'); $input = preg_replace_callback( '/=([a-f0-9]{2})/i', $cb, $input); return $input; } /** * Checks the input for uuencoded files and returns * an array of them. Can be called statically, eg: * * $files =& Mail_mimeDecode::uudecode($some_text); * * It will check for the begin 666 ... end syntax * however and won't just blindly decode whatever you * pass it. * * @param string Input body to look for attahcments in * @return array Decoded bodies, filenames and permissions * @access public * @author Unknown */ function &uudecode($input) { // Find all uuencoded sections preg_match_all("/begin ([0-7]{3}) (.+)\r?\n(.+)\r?\nend/Us", $input, $matches); for ($j = 0; $j < count($matches[3]); $j++) { $str = $matches[3][$j]; $filename = $matches[2][$j]; $fileperm = $matches[1][$j]; $file = ''; $str = preg_split("/\r?\n/", trim($str)); $strlen = count($str); for ($i = 0; $i < $strlen; $i++) { $pos = 1; $d = 0; $len=(int)(((ord(substr($str[$i],0,1)) -32) - ' ') & 077); while (($d + 3 <= $len) AND ($pos + 4 <= strlen($str[$i]))) { $c0 = (ord(substr($str[$i],$pos,1)) ^ 0x20); $c1 = (ord(substr($str[$i],$pos+1,1)) ^ 0x20); $c2 = (ord(substr($str[$i],$pos+2,1)) ^ 0x20); $c3 = (ord(substr($str[$i],$pos+3,1)) ^ 0x20); $file .= chr(((($c0 - ' ') & 077) << 2) | ((($c1 - ' ') & 077) >> 4)); $file .= chr(((($c1 - ' ') & 077) << 4) | ((($c2 - ' ') & 077) >> 2)); $file .= chr(((($c2 - ' ') & 077) << 6) | (($c3 - ' ') & 077)); $pos += 4; $d += 3; } if (($d + 2 <= $len) && ($pos + 3 <= strlen($str[$i]))) { $c0 = (ord(substr($str[$i],$pos,1)) ^ 0x20); $c1 = (ord(substr($str[$i],$pos+1,1)) ^ 0x20); $c2 = (ord(substr($str[$i],$pos+2,1)) ^ 0x20); $file .= chr(((($c0 - ' ') & 077) << 2) | ((($c1 - ' ') & 077) >> 4)); $file .= chr(((($c1 - ' ') & 077) << 4) | ((($c2 - ' ') & 077) >> 2)); $pos += 3; $d += 2; } if (($d + 1 <= $len) && ($pos + 2 <= strlen($str[$i]))) { $c0 = (ord(substr($str[$i],$pos,1)) ^ 0x20); $c1 = (ord(substr($str[$i],$pos+1,1)) ^ 0x20); $file .= chr(((($c0 - ' ') & 077) << 2) | ((($c1 - ' ') & 077) >> 4)); } } $files[] = array('filename' => $filename, 'fileperm' => $fileperm, 'filedata' => $file); } return $files; } /** * getSendArray() returns the arguments required for Mail::send() * used to build the arguments for a mail::send() call * * Usage: * $mailtext = Full email (for example generated by a template) * $decoder = new Mail_mimeDecode($mailtext); * $parts = $decoder->getSendArray(); * if (!PEAR::isError($parts) { * list($recipents,$headers,$body) = $parts; * $mail = Mail::factory('smtp'); * $mail->send($recipents,$headers,$body); * } else { * echo $parts->message; * } * @return mixed array of recipeint, headers,body or Pear_Error * @access public * @author Alan Knowles <alan@akbkhome.com> */ function getSendArray() { // prevent warning if this is not set $this->_decode_headers = FALSE; $headerlist =$this->_parseHeaders($this->_header); $to = ""; if (!$headerlist) { return $this->raiseError("Message did not contain headers"); } foreach($headerlist as $item) { $header[$item['name']] = $item['value']; switch (strtolower($item['name'])) { case "to": case "cc": case "bcc": $to .= ",".$item['value']; default: break; } } if ($to == "") { return $this->raiseError("Message did not contain any recipents"); } $to = substr($to,1); return array($to,$header,$this->_body); } /** * Returns a xml copy of the output of * Mail_mimeDecode::decode. Pass the output in as the * argument. This function can be called statically. Eg: * * $output = $obj->decode(); * $xml = Mail_mimeDecode::getXML($output); * * The DTD used for this should have been in the package. Or * alternatively you can get it from cvs, or here: * http://www.phpguru.org/xmail/xmail.dtd. * * @param object Input to convert to xml. This should be the * output of the Mail_mimeDecode::decode function * @return string XML version of input * @access public */ function getXML($input) { $crlf = "\r\n"; $output = '<?xml version=\'1.0\'?>' . $crlf . '<!DOCTYPE email SYSTEM "http://www.phpguru.org/xmail/xmail.dtd">' . $crlf . '<email>' . $crlf . Mail_mimeDecode::_getXML($input) . '</email>'; return $output; } /** * Function that does the actual conversion to xml. Does a single * mimepart at a time. * * @param object Input to convert to xml. This is a mimepart object. * It may or may not contain subparts. * @param integer Number of tabs to indent * @return string XML version of input * @access private */ function _getXML($input, $indent = 1) { $htab = "\t"; $crlf = "\r\n"; $output = ''; $headers = @(array)$input->headers; foreach ($headers as $hdr_name => $hdr_value) { // Multiple headers with this name if (is_array($headers[$hdr_name])) { for ($i = 0; $i < count($hdr_value); $i++) { $output .= Mail_mimeDecode::_getXML_helper($hdr_name, $hdr_value[$i], $indent); } // Only one header of this sort } else { $output .= Mail_mimeDecode::_getXML_helper($hdr_name, $hdr_value, $indent); } } if (!empty($input->parts)) { for ($i = 0; $i < count($input->parts); $i++) { $output .= $crlf . str_repeat($htab, $indent) . '<mimepart>' . $crlf . Mail_mimeDecode::_getXML($input->parts[$i], $indent+1) . str_repeat($htab, $indent) . '</mimepart>' . $crlf; } } elseif (isset($input->body)) { $output .= $crlf . str_repeat($htab, $indent) . '<body><![CDATA[' . $input->body . ']]></body>' . $crlf; } return $output; } /** * Helper function to _getXML(). Returns xml of a header. * * @param string Name of header * @param string Value of header * @param integer Number of tabs to indent * @return string XML version of input * @access private */ function _getXML_helper($hdr_name, $hdr_value, $indent) { $htab = "\t"; $crlf = "\r\n"; $return = ''; $new_hdr_value = ($hdr_name != 'received') ? Mail_mimeDecode::_parseHeaderValue($hdr_value) : array('value' => $hdr_value); $new_hdr_name = str_replace(' ', '-', ucwords(str_replace('-', ' ', $hdr_name))); // Sort out any parameters if (!empty($new_hdr_value['other'])) { foreach ($new_hdr_value['other'] as $paramname => $paramvalue) { $params[] = str_repeat($htab, $indent) . $htab . '<parameter>' . $crlf . str_repeat($htab, $indent) . $htab . $htab . '<paramname>' . htmlspecialchars($paramname) . '</paramname>' . $crlf . str_repeat($htab, $indent) . $htab . $htab . '<paramvalue>' . htmlspecialchars($paramvalue) . '</paramvalue>' . $crlf . str_repeat($htab, $indent) . $htab . '</parameter>' . $crlf; } $params = implode('', $params); } else { $params = ''; } $return = str_repeat($htab, $indent) . '<header>' . $crlf . str_repeat($htab, $indent) . $htab . '<headername>' . htmlspecialchars($new_hdr_name) . '</headername>' . $crlf . str_repeat($htab, $indent) . $htab . '<headervalue>' . htmlspecialchars($new_hdr_value['value']) . '</headervalue>' . $crlf . $params . str_repeat($htab, $indent) . '</header>' . $crlf; return $return; } } // End of class PK�����u]{ �� �� ��Mail/null.phpnu�[��������<?php /** * Null implementation of the PEAR Mail interface * * PHP version 5 * * LICENSE: * * Copyright (c) 2010-2017, Phil Kernick * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are 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. Neither the name of the copyright holder nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS 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 COPYRIGHT * HOLDER OR 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. * * @category Mail * @package Mail * @author Phil Kernick <philk@rotfl.com.au> * @copyright 2010-2017 Phil Kernick * @license http://opensource.org/licenses/BSD-3-Clause New BSD License * @version CVS: $Id$ * @link http://pear.php.net/package/Mail/ */ /** * Null implementation of the PEAR Mail:: interface. * @access public * @package Mail * @version $Revision$ */ class Mail_null extends Mail { /** * Implements Mail_null::send() function. Silently discards all * mail. * * @param mixed $recipients Either a comma-seperated list of recipients * (RFC822 compliant), or an array of recipients, * each RFC822 valid. This may contain recipients not * specified in the headers, for Bcc:, resending * messages, etc. * * @param array $headers The array of headers to send with the mail, in an * associative array, where the array key is the * header name (ie, 'Subject'), and the array value * is the header value (ie, 'test'). The header * produced from those values would be 'Subject: * test'. * * @param string $body The full text of the message body, including any * Mime parts, etc. * * @return mixed Returns true on success, or a PEAR_Error * containing a descriptive error message on * failure. */ public function send($recipients, $headers, $body) { return true; } } PK�����u]A~{��{����Mail/RFC822.phpnu�[��������<?php /** * RFC 822 Email address list validation Utility * * PHP version 5 * * LICENSE: * * Copyright (c) 2001-2017, Chuck Hagenbuch & Richard Heyes * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are 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. Neither the name of the copyright holder nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS 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 COPYRIGHT * HOLDER OR 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. * * @category Mail * @package Mail * @author Richard Heyes <richard@phpguru.org> * @author Chuck Hagenbuch <chuck@horde.org * @copyright 2001-2017 Richard Heyes * @license http://opensource.org/licenses/BSD-3-Clause New BSD License * @version CVS: $Id$ * @link http://pear.php.net/package/Mail/ */ /** * RFC 822 Email address list validation Utility * * What is it? * * This class will take an address string, and parse it into it's consituent * parts, be that either addresses, groups, or combinations. Nested groups * are not supported. The structure it returns is pretty straight forward, * and is similar to that provided by the imap_rfc822_parse_adrlist(). Use * print_r() to view the structure. * * How do I use it? * * $address_string = 'My Group: "Richard" <richard@localhost> (A comment), ted@example.com (Ted Bloggs), Barney;'; * $structure = Mail_RFC822::parseAddressList($address_string, 'example.com', true) * print_r($structure); * * @author Richard Heyes <richard@phpguru.org> * @author Chuck Hagenbuch <chuck@horde.org> * @version $Revision$ * @license BSD * @package Mail */ class Mail_RFC822 { /** * The address being parsed by the RFC822 object. * @var string $address */ var $address = ''; /** * The default domain to use for unqualified addresses. * @var string $default_domain */ var $default_domain = 'localhost'; /** * Should we return a nested array showing groups, or flatten everything? * @var boolean $nestGroups */ var $nestGroups = true; /** * Whether or not to validate atoms for non-ascii characters. * @var boolean $validate */ var $validate = true; /** * The array of raw addresses built up as we parse. * @var array $addresses */ var $addresses = array(); /** * The final array of parsed address information that we build up. * @var array $structure */ var $structure = array(); /** * The current error message, if any. * @var string $error */ var $error = null; /** * An internal counter/pointer. * @var integer $index */ var $index = null; /** * The number of groups that have been found in the address list. * @var integer $num_groups * @access public */ var $num_groups = 0; /** * A variable so that we can tell whether or not we're inside a * Mail_RFC822 object. * @var boolean $mailRFC822 */ var $mailRFC822 = true; /** * A limit after which processing stops * @var int $limit */ var $limit = null; /** * Sets up the object. The address must either be set here or when * calling parseAddressList(). One or the other. * * @param string $address The address(es) to validate. * @param string $default_domain Default domain/host etc. If not supplied, will be set to localhost. * @param boolean $nest_groups Whether to return the structure with groups nested for easier viewing. * @param boolean $validate Whether to validate atoms. Turn this off if you need to run addresses through before encoding the personal names, for instance. * * @return object Mail_RFC822 A new Mail_RFC822 object. */ public function __construct($address = null, $default_domain = null, $nest_groups = null, $validate = null, $limit = null) { if (isset($address)) $this->address = $address; if (isset($default_domain)) $this->default_domain = $default_domain; if (isset($nest_groups)) $this->nestGroups = $nest_groups; if (isset($validate)) $this->validate = $validate; if (isset($limit)) $this->limit = $limit; } /** * Starts the whole process. The address must either be set here * or when creating the object. One or the other. * * @param string $address The address(es) to validate. * @param string $default_domain Default domain/host etc. * @param boolean $nest_groups Whether to return the structure with groups nested for easier viewing. * @param boolean $validate Whether to validate atoms. Turn this off if you need to run addresses through before encoding the personal names, for instance. * * @return array A structured array of addresses. */ public function parseAddressList($address = null, $default_domain = null, $nest_groups = null, $validate = null, $limit = null) { if (!isset($this) || !isset($this->mailRFC822)) { $obj = new Mail_RFC822($address, $default_domain, $nest_groups, $validate, $limit); return $obj->parseAddressList(); } if (isset($address)) $this->address = $address; if (isset($default_domain)) $this->default_domain = $default_domain; if (isset($nest_groups)) $this->nestGroups = $nest_groups; if (isset($validate)) $this->validate = $validate; if (isset($limit)) $this->limit = $limit; $this->structure = array(); $this->addresses = array(); $this->error = null; $this->index = null; // Unfold any long lines in $this->address. $this->address = preg_replace('/\r?\n/', "\r\n", $this->address); $this->address = preg_replace('/\r\n(\t| )+/', ' ', $this->address); while ($this->address = $this->_splitAddresses($this->address)); if ($this->address === false || isset($this->error)) { require_once 'PEAR.php'; return PEAR::raiseError($this->error); } // Validate each address individually. If we encounter an invalid // address, stop iterating and return an error immediately. foreach ($this->addresses as $address) { $valid = $this->_validateAddress($address); if ($valid === false || isset($this->error)) { require_once 'PEAR.php'; return PEAR::raiseError($this->error); } if (!$this->nestGroups) { $this->structure = array_merge($this->structure, $valid); } else { $this->structure[] = $valid; } } return $this->structure; } /** * Splits an address into separate addresses. * * @param string $address The addresses to split. * @return boolean Success or failure. */ protected function _splitAddresses($address) { if (!empty($this->limit) && count($this->addresses) == $this->limit) { return ''; } if ($this->_isGroup($address) && !isset($this->error)) { $split_char = ';'; $is_group = true; } elseif (!isset($this->error)) { $split_char = ','; $is_group = false; } elseif (isset($this->error)) { return false; } // Split the string based on the above ten or so lines. $parts = explode($split_char, $address); $string = $this->_splitCheck($parts, $split_char); // If a group... if ($is_group) { // If $string does not contain a colon outside of // brackets/quotes etc then something's fubar. // First check there's a colon at all: if (strpos($string, ':') === false) { $this->error = 'Invalid address: ' . $string; return false; } // Now check it's outside of brackets/quotes: if (!$this->_splitCheck(explode(':', $string), ':')) { return false; } // We must have a group at this point, so increase the counter: $this->num_groups++; } // $string now contains the first full address/group. // Add to the addresses array. $this->addresses[] = array( 'address' => trim($string), 'group' => $is_group ); // Remove the now stored address from the initial line, the +1 // is to account for the explode character. $address = trim(substr($address, strlen($string) + 1)); // If the next char is a comma and this was a group, then // there are more addresses, otherwise, if there are any more // chars, then there is another address. if ($is_group && substr($address, 0, 1) == ','){ $address = trim(substr($address, 1)); return $address; } elseif (strlen($address) > 0) { return $address; } else { return ''; } // If you got here then something's off return false; } /** * Checks for a group at the start of the string. * * @param string $address The address to check. * @return boolean Whether or not there is a group at the start of the string. */ protected function _isGroup($address) { // First comma not in quotes, angles or escaped: $parts = explode(',', $address); $string = $this->_splitCheck($parts, ','); // Now we have the first address, we can reliably check for a // group by searching for a colon that's not escaped or in // quotes or angle brackets. if (count($parts = explode(':', $string)) > 1) { $string2 = $this->_splitCheck($parts, ':'); return ($string2 !== $string); } else { return false; } } /** * A common function that will check an exploded string. * * @param array $parts The exloded string. * @param string $char The char that was exploded on. * @return mixed False if the string contains unclosed quotes/brackets, or the string on success. */ protected function _splitCheck($parts, $char) { $string = $parts[0]; for ($i = 0; $i < count($parts); $i++) { if ($this->_hasUnclosedQuotes($string) || $this->_hasUnclosedBrackets($string, '<>') || $this->_hasUnclosedBrackets($string, '[]') || $this->_hasUnclosedBrackets($string, '()') || substr($string, -1) == '\\') { if (isset($parts[$i + 1])) { $string = $string . $char . $parts[$i + 1]; } else { $this->error = 'Invalid address spec. Unclosed bracket or quotes'; return false; } } else { $this->index = $i; break; } } return $string; } /** * Checks if a string has unclosed quotes or not. * * @param string $string The string to check. * @return boolean True if there are unclosed quotes inside the string, * false otherwise. */ protected function _hasUnclosedQuotes($string) { $string = trim($string); $iMax = strlen($string); $in_quote = false; $i = $slashes = 0; for (; $i < $iMax; ++$i) { switch ($string[$i]) { case '\\': ++$slashes; break; case '"': if ($slashes % 2 == 0) { $in_quote = !$in_quote; } // Fall through to default action below. default: $slashes = 0; break; } } return $in_quote; } /** * Checks if a string has an unclosed brackets or not. IMPORTANT: * This function handles both angle brackets and square brackets; * * @param string $string The string to check. * @param string $chars The characters to check for. * @return boolean True if there are unclosed brackets inside the string, false otherwise. */ protected function _hasUnclosedBrackets($string, $chars) { $num_angle_start = substr_count($string, $chars[0]); $num_angle_end = substr_count($string, $chars[1]); $this->_hasUnclosedBracketsSub($string, $num_angle_start, $chars[0]); $this->_hasUnclosedBracketsSub($string, $num_angle_end, $chars[1]); if ($num_angle_start < $num_angle_end) { $this->error = 'Invalid address spec. Unmatched quote or bracket (' . $chars . ')'; return false; } else { return ($num_angle_start > $num_angle_end); } } /** * Sub function that is used only by hasUnclosedBrackets(). * * @param string $string The string to check. * @param integer &$num The number of occurences. * @param string $char The character to count. * @return integer The number of occurences of $char in $string, adjusted for backslashes. */ protected function _hasUnclosedBracketsSub($string, &$num, $char) { $parts = explode($char, $string); for ($i = 0; $i < count($parts); $i++){ if (substr($parts[$i], -1) == '\\' || $this->_hasUnclosedQuotes($parts[$i])) $num--; if (isset($parts[$i + 1])) $parts[$i + 1] = $parts[$i] . $char . $parts[$i + 1]; } return $num; } /** * Function to begin checking the address. * * @param string $address The address to validate. * @return mixed False on failure, or a structured array of address information on success. */ protected function _validateAddress($address) { $is_group = false; $addresses = array(); if ($address['group']) { $is_group = true; // Get the group part of the name $parts = explode(':', $address['address']); $groupname = $this->_splitCheck($parts, ':'); $structure = array(); // And validate the group part of the name. if (!$this->_validatePhrase($groupname)){ $this->error = 'Group name did not validate.'; return false; } else { // Don't include groups if we are not nesting // them. This avoids returning invalid addresses. if ($this->nestGroups) { $structure = new stdClass; $structure->groupname = $groupname; } } $address['address'] = ltrim(substr($address['address'], strlen($groupname . ':'))); } // If a group then split on comma and put into an array. // Otherwise, Just put the whole address in an array. if ($is_group) { while (strlen($address['address']) > 0) { $parts = explode(',', $address['address']); $addresses[] = $this->_splitCheck($parts, ','); $address['address'] = trim(substr($address['address'], strlen(end($addresses) . ','))); } } else { $addresses[] = $address['address']; } // Trim the whitespace from all of the address strings. array_map('trim', $addresses); // Validate each mailbox. // Format could be one of: name <geezer@domain.com> // geezer@domain.com // geezer // ... or any other format valid by RFC 822. for ($i = 0; $i < count($addresses); $i++) { if (!$this->validateMailbox($addresses[$i])) { if (empty($this->error)) { $this->error = 'Validation failed for: ' . $addresses[$i]; } return false; } } // Nested format if ($this->nestGroups) { if ($is_group) { $structure->addresses = $addresses; } else { $structure = $addresses[0]; } // Flat format } else { if ($is_group) { $structure = array_merge($structure, $addresses); } else { $structure = $addresses; } } return $structure; } /** * Function to validate a phrase. * * @param string $phrase The phrase to check. * @return boolean Success or failure. */ protected function _validatePhrase($phrase) { // Splits on one or more Tab or space. $parts = preg_split('/[ \\x09]+/', $phrase, -1, PREG_SPLIT_NO_EMPTY); $phrase_parts = array(); while (count($parts) > 0){ $phrase_parts[] = $this->_splitCheck($parts, ' '); for ($i = 0; $i < $this->index + 1; $i++) array_shift($parts); } foreach ($phrase_parts as $part) { // If quoted string: if (substr($part, 0, 1) == '"') { if (!$this->_validateQuotedString($part)) { return false; } continue; } // Otherwise it's an atom: if (!$this->_validateAtom($part)) return false; } return true; } /** * Function to validate an atom which from rfc822 is: * atom = 1*<any CHAR except specials, SPACE and CTLs> * * If validation ($this->validate) has been turned off, then * validateAtom() doesn't actually check anything. This is so that you * can split a list of addresses up before encoding personal names * (umlauts, etc.), for example. * * @param string $atom The string to check. * @return boolean Success or failure. */ protected function _validateAtom($atom) { if (!$this->validate) { // Validation has been turned off; assume the atom is okay. return true; } // Check for any char from ASCII 0 - ASCII 127 if (!preg_match('/^[\\x00-\\x7E]+$/i', $atom, $matches)) { return false; } // Check for specials: if (preg_match('/[][()<>@,;\\:". ]/', $atom)) { return false; } // Check for control characters (ASCII 0-31): if (preg_match('/[\\x00-\\x1F]+/', $atom)) { return false; } return true; } /** * Function to validate quoted string, which is: * quoted-string = <"> *(qtext/quoted-pair) <"> * * @param string $qstring The string to check * @return boolean Success or failure. */ protected function _validateQuotedString($qstring) { // Leading and trailing " $qstring = substr($qstring, 1, -1); // Perform check, removing quoted characters first. return !preg_match('/[\x0D\\\\"]/', preg_replace('/\\\\./', '', $qstring)); } /** * Function to validate a mailbox, which is: * mailbox = addr-spec ; simple address * / phrase route-addr ; name and route-addr * * @param string &$mailbox The string to check. * @return boolean Success or failure. */ public function validateMailbox(&$mailbox) { // A couple of defaults. $phrase = ''; $comment = ''; $comments = array(); // Catch any RFC822 comments and store them separately. $_mailbox = $mailbox; while (strlen(trim($_mailbox)) > 0) { $parts = explode('(', $_mailbox); $before_comment = $this->_splitCheck($parts, '('); if ($before_comment != $_mailbox) { // First char should be a (. $comment = substr(str_replace($before_comment, '', $_mailbox), 1); $parts = explode(')', $comment); $comment = $this->_splitCheck($parts, ')'); $comments[] = $comment; // +2 is for the brackets $_mailbox = substr($_mailbox, strpos($_mailbox, '('.$comment)+strlen($comment)+2); } else { break; } } foreach ($comments as $comment) { $mailbox = str_replace("($comment)", '', $mailbox); } $mailbox = trim($mailbox); // Check for name + route-addr if (substr($mailbox, -1) == '>' && substr($mailbox, 0, 1) != '<') { $parts = explode('<', $mailbox); $name = $this->_splitCheck($parts, '<'); $phrase = trim($name); $route_addr = trim(substr($mailbox, strlen($name.'<'), -1)); if ($this->_validatePhrase($phrase) === false || ($route_addr = $this->_validateRouteAddr($route_addr)) === false) { return false; } // Only got addr-spec } else { // First snip angle brackets if present. if (substr($mailbox, 0, 1) == '<' && substr($mailbox, -1) == '>') { $addr_spec = substr($mailbox, 1, -1); } else { $addr_spec = $mailbox; } if (($addr_spec = $this->_validateAddrSpec($addr_spec)) === false) { return false; } } // Construct the object that will be returned. $mbox = new stdClass(); // Add the phrase (even if empty) and comments $mbox->personal = $phrase; $mbox->comment = isset($comments) ? $comments : array(); if (isset($route_addr)) { $mbox->mailbox = $route_addr['local_part']; $mbox->host = $route_addr['domain']; $route_addr['adl'] !== '' ? $mbox->adl = $route_addr['adl'] : ''; } else { $mbox->mailbox = $addr_spec['local_part']; $mbox->host = $addr_spec['domain']; } $mailbox = $mbox; return true; } /** * This function validates a route-addr which is: * route-addr = "<" [route] addr-spec ">" * * Angle brackets have already been removed at the point of * getting to this function. * * @param string $route_addr The string to check. * @return mixed False on failure, or an array containing validated address/route information on success. */ protected function _validateRouteAddr($route_addr) { // Check for colon. if (strpos($route_addr, ':') !== false) { $parts = explode(':', $route_addr); $route = $this->_splitCheck($parts, ':'); } else { $route = $route_addr; } // If $route is same as $route_addr then the colon was in // quotes or brackets or, of course, non existent. if ($route === $route_addr){ unset($route); $addr_spec = $route_addr; if (($addr_spec = $this->_validateAddrSpec($addr_spec)) === false) { return false; } } else { // Validate route part. if (($route = $this->_validateRoute($route)) === false) { return false; } $addr_spec = substr($route_addr, strlen($route . ':')); // Validate addr-spec part. if (($addr_spec = $this->_validateAddrSpec($addr_spec)) === false) { return false; } } if (isset($route)) { $return['adl'] = $route; } else { $return['adl'] = ''; } $return = array_merge($return, $addr_spec); return $return; } /** * Function to validate a route, which is: * route = 1#("@" domain) ":" * * @param string $route The string to check. * @return mixed False on failure, or the validated $route on success. */ protected function _validateRoute($route) { // Split on comma. $domains = explode(',', trim($route)); foreach ($domains as $domain) { $domain = str_replace('@', '', trim($domain)); if (!$this->_validateDomain($domain)) return false; } return $route; } /** * Function to validate a domain, though this is not quite what * you expect of a strict internet domain. * * domain = sub-domain *("." sub-domain) * * @param string $domain The string to check. * @return mixed False on failure, or the validated domain on success. */ protected function _validateDomain($domain) { // Note the different use of $subdomains and $sub_domains $subdomains = explode('.', $domain); while (count($subdomains) > 0) { $sub_domains[] = $this->_splitCheck($subdomains, '.'); for ($i = 0; $i < $this->index + 1; $i++) array_shift($subdomains); } foreach ($sub_domains as $sub_domain) { if (!$this->_validateSubdomain(trim($sub_domain))) return false; } // Managed to get here, so return input. return $domain; } /** * Function to validate a subdomain: * subdomain = domain-ref / domain-literal * * @param string $subdomain The string to check. * @return boolean Success or failure. */ protected function _validateSubdomain($subdomain) { if (preg_match('|^\[(.*)]$|', $subdomain, $arr)){ if (!$this->_validateDliteral($arr[1])) return false; } else { if (!$this->_validateAtom($subdomain)) return false; } // Got here, so return successful. return true; } /** * Function to validate a domain literal: * domain-literal = "[" *(dtext / quoted-pair) "]" * * @param string $dliteral The string to check. * @return boolean Success or failure. */ protected function _validateDliteral($dliteral) { return !preg_match('/(.)[][\x0D\\\\]/', $dliteral, $matches) && ((! isset($matches[1])) || $matches[1] != '\\'); } /** * Function to validate an addr-spec. * * addr-spec = local-part "@" domain * * @param string $addr_spec The string to check. * @return mixed False on failure, or the validated addr-spec on success. */ protected function _validateAddrSpec($addr_spec) { $addr_spec = trim($addr_spec); // Split on @ sign if there is one. if (strpos($addr_spec, '@') !== false) { $parts = explode('@', $addr_spec); $local_part = $this->_splitCheck($parts, '@'); $domain = substr($addr_spec, strlen($local_part . '@')); // No @ sign so assume the default domain. } else { $local_part = $addr_spec; $domain = $this->default_domain; } if (($local_part = $this->_validateLocalPart($local_part)) === false) return false; if (($domain = $this->_validateDomain($domain)) === false) return false; // Got here so return successful. return array('local_part' => $local_part, 'domain' => $domain); } /** * Function to validate the local part of an address: * local-part = word *("." word) * * @param string $local_part * @return mixed False on failure, or the validated local part on success. */ protected function _validateLocalPart($local_part) { $parts = explode('.', $local_part); $words = array(); // Split the local_part into words. while (count($parts) > 0) { $words[] = $this->_splitCheck($parts, '.'); for ($i = 0; $i < $this->index + 1; $i++) { array_shift($parts); } } // Validate each word. foreach ($words as $word) { // word cannot be empty (#17317) if ($word === '') { return false; } // If this word contains an unquoted space, it is invalid. (6.2.4) if (strpos($word, ' ') && $word[0] !== '"') { return false; } if ($this->_validatePhrase(trim($word)) === false) return false; } // Managed to get here, so return the input. return $local_part; } /** * Returns an approximate count of how many addresses are in the * given string. This is APPROXIMATE as it only splits based on a * comma which has no preceding backslash. Could be useful as * large amounts of addresses will end up producing *large* * structures when used with parseAddressList(). * * @param string $data Addresses to count * @return int Approximate count */ public function approximateCount($data) { return count(preg_split('/(?<!\\\\),/', $data)); } /** * This is a email validating function separate to the rest of the * class. It simply validates whether an email is of the common * internet form: <user>@<domain>. This can be sufficient for most * people. Optional stricter mode can be utilised which restricts * mailbox characters allowed to alphanumeric, full stop, hyphen * and underscore. * * @param string $data Address to check * @param boolean $strict Optional stricter mode * @return mixed False if it fails, an indexed array * username/domain if it matches */ public function isValidInetAddress($data, $strict = false) { $regex = $strict ? '/^([.0-9a-z_+-]+)@(([0-9a-z-]+\.)+[0-9a-z]{2,})$/i' : '/^([*+!.&#$|\'\\%\/0-9a-z^_`{}=?~:-]+)@(([0-9a-z-]+\.)+[0-9a-z]{2,})$/i'; if (preg_match($regex, trim($data), $matches)) { return array($matches[1], $matches[2]); } else { return false; } } } PK�����u]wԐE;��E;����Mail/smtpmx.phpnu�[��������<?php /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ /** * SMTP MX * * SMTP MX implementation of the PEAR Mail interface. Requires the Net_SMTP class. * * PHP version 5 * * LICENSE: * * Copyright (c) 2010-2017 gERD Schaufelberger * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are 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. Neither the name of the copyright holder nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS 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 COPYRIGHT * HOLDER OR 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. * * @category Mail * @package Mail_smtpmx * @author gERD Schaufelberger <gerd@php-tools.net> * @copyright 2010-2017 gERD Schaufelberger * @license http://opensource.org/licenses/BSD-3-Clause New BSD License * @version CVS: $Id$ * @link http://pear.php.net/package/Mail/ */ require_once 'Net/SMTP.php'; /** * SMTP MX implementation of the PEAR Mail interface. Requires the Net_SMTP class. * * * @access public * @author gERD Schaufelberger <gerd@php-tools.net> * @package Mail * @version $Revision$ */ class Mail_smtpmx extends Mail { /** * SMTP connection object. * * @var object * @access private */ var $_smtp = null; /** * The port the SMTP server is on. * @var integer * @see getservicebyname() */ var $port = 25; /** * Hostname or domain that will be sent to the remote SMTP server in the * HELO / EHLO message. * * @var string * @see posix_uname() */ var $mailname = 'localhost'; /** * SMTP connection timeout value. NULL indicates no timeout. * * @var integer */ var $timeout = 10; /** * use either PEAR:Net_DNS or getmxrr * * @var boolean */ var $withNetDns = true; /** * PEAR:Net_DNS_Resolver * * @var object */ var $resolver; /** * Whether to use VERP or not. If not a boolean, the string value * will be used as the VERP separators. * * @var mixed boolean or string */ var $verp = false; /** * Whether to use VRFY or not. * * @var boolean $vrfy */ var $vrfy = false; /** * Switch to test mode - don't send emails for real * * @var boolean $debug */ var $test = false; /** * Turn on Net_SMTP debugging? * * @var boolean $peardebug */ var $debug = false; /** * internal error codes * * translate internal error identifier to PEAR-Error codes and human * readable messages. * * @var boolean $debug * @todo as I need unique error-codes to identify what exactly went wrond * I did not use intergers as it should be. Instead I added a "namespace" * for each code. This avoids conflicts with error codes from different * classes. How can I use unique error codes and stay conform with PEAR? */ var $errorCode = array( 'not_connected' => array( 'code' => 1, 'msg' => 'Could not connect to any mail server ({HOST}) at port {PORT} to send mail to {RCPT}.' ), 'failed_vrfy_rcpt' => array( 'code' => 2, 'msg' => 'Recipient "{RCPT}" could not be veryfied.' ), 'failed_set_from' => array( 'code' => 3, 'msg' => 'Failed to set sender: {FROM}.' ), 'failed_set_rcpt' => array( 'code' => 4, 'msg' => 'Failed to set recipient: {RCPT}.' ), 'failed_send_data' => array( 'code' => 5, 'msg' => 'Failed to send mail to: {RCPT}.' ), 'no_from' => array( 'code' => 5, 'msg' => 'No from address has be provided.' ), 'send_data' => array( 'code' => 7, 'msg' => 'Failed to create Net_SMTP object.' ), 'no_mx' => array( 'code' => 8, 'msg' => 'No MX-record for {RCPT} found.' ), 'no_resolver' => array( 'code' => 9, 'msg' => 'Could not start resolver! Install PEAR:Net_DNS or switch off "netdns"' ), 'failed_rset' => array( 'code' => 10, 'msg' => 'RSET command failed, SMTP-connection corrupt.' ), ); /** * Constructor. * * Instantiates a new Mail_smtp:: object based on the parameters * passed in. It looks for the following parameters: * mailname The name of the local mail system (a valid hostname which matches the reverse lookup) * port smtp-port - the default comes from getservicebyname() and should work fine * timeout The SMTP connection timeout. Defaults to 30 seconds. * vrfy Whether to use VRFY or not. Defaults to false. * verp Whether to use VERP or not. Defaults to false. * test Activate test mode? Defaults to false. * debug Activate SMTP and Net_DNS debug mode? Defaults to false. * netdns whether to use PEAR:Net_DNS or the PHP build in function getmxrr, default is true * * If a parameter is present in the $params array, it replaces the * default. * * @access public * @param array Hash containing any parameters different from the * defaults. * @see _Mail_smtpmx() */ function __construct($params) { if (isset($params['mailname'])) { $this->mailname = $params['mailname']; } else { // try to find a valid mailname if (function_exists('posix_uname')) { $uname = posix_uname(); $this->mailname = $uname['nodename']; } } // port number if (isset($params['port'])) { $this->_port = $params['port']; } else { $this->_port = getservbyname('smtp', 'tcp'); } if (isset($params['timeout'])) $this->timeout = $params['timeout']; if (isset($params['verp'])) $this->verp = $params['verp']; if (isset($params['test'])) $this->test = $params['test']; if (isset($params['peardebug'])) $this->test = $params['peardebug']; if (isset($params['netdns'])) $this->withNetDns = $params['netdns']; } /** * Constructor wrapper for PHP4 * * @access public * @param array Hash containing any parameters different from the defaults * @see __construct() */ function Mail_smtpmx($params) { $this->__construct($params); register_shutdown_function(array(&$this, '__destruct')); } /** * Destructor implementation to ensure that we disconnect from any * potentially-alive persistent SMTP connections. */ function __destruct() { if (is_object($this->_smtp)) { $this->_smtp->disconnect(); $this->_smtp = null; } } /** * Implements Mail::send() function using SMTP direct delivery * * @access public * @param mixed $recipients in RFC822 style or array * @param array $headers The array of headers to send with the mail. * @param string $body The full text of the message body, * @return mixed Returns true on success, or a PEAR_Error */ function send($recipients, $headers, $body) { if (!is_array($headers)) { return PEAR::raiseError('$headers must be an array'); } $result = $this->_sanitizeHeaders($headers); if (is_a($result, 'PEAR_Error')) { return $result; } // Prepare headers $headerElements = $this->prepareHeaders($headers); if (is_a($headerElements, 'PEAR_Error')) { return $headerElements; } list($from, $textHeaders) = $headerElements; // use 'Return-Path' if possible if (!empty($headers['Return-Path'])) { $from = $headers['Return-Path']; } if (!isset($from)) { return $this->_raiseError('no_from'); } // Prepare recipients $recipients = $this->parseRecipients($recipients); if (is_a($recipients, 'PEAR_Error')) { return $recipients; } foreach ($recipients as $rcpt) { list($user, $host) = explode('@', $rcpt); $mx = $this->_getMx($host); if (is_a($mx, 'PEAR_Error')) { return $mx; } if (empty($mx)) { $info = array('rcpt' => $rcpt); return $this->_raiseError('no_mx', $info); } $connected = false; foreach ($mx as $mserver => $mpriority) { $this->_smtp = new Net_SMTP($mserver, $this->port, $this->mailname); // configure the SMTP connection. if ($this->debug) { $this->_smtp->setDebug(true); } // attempt to connect to the configured SMTP server. $res = $this->_smtp->connect($this->timeout); if (is_a($res, 'PEAR_Error')) { $this->_smtp = null; continue; } // connection established if ($res) { $connected = true; break; } } if (!$connected) { $info = array( 'host' => implode(', ', array_keys($mx)), 'port' => $this->port, 'rcpt' => $rcpt, ); return $this->_raiseError('not_connected', $info); } // Verify recipient if ($this->vrfy) { $res = $this->_smtp->vrfy($rcpt); if (is_a($res, 'PEAR_Error')) { $info = array('rcpt' => $rcpt); return $this->_raiseError('failed_vrfy_rcpt', $info); } } // mail from: $args['verp'] = $this->verp; $res = $this->_smtp->mailFrom($from, $args); if (is_a($res, 'PEAR_Error')) { $info = array('from' => $from); return $this->_raiseError('failed_set_from', $info); } // rcpt to: $res = $this->_smtp->rcptTo($rcpt); if (is_a($res, 'PEAR_Error')) { $info = array('rcpt' => $rcpt); return $this->_raiseError('failed_set_rcpt', $info); } // Don't send anything in test mode if ($this->test) { $result = $this->_smtp->rset(); $res = $this->_smtp->rset(); if (is_a($res, 'PEAR_Error')) { return $this->_raiseError('failed_rset'); } $this->_smtp->disconnect(); $this->_smtp = null; return true; } // Send data $res = $this->_smtp->data($body, $textHeaders); if (is_a($res, 'PEAR_Error')) { $info = array('rcpt' => $rcpt); return $this->_raiseError('failed_send_data', $info); } $this->_smtp->disconnect(); $this->_smtp = null; } return true; } /** * Recieve mx rexords for a spciefied host * * The MX records * * @access private * @param string $host mail host * @return mixed sorted */ function _getMx($host) { $mx = array(); if ($this->withNetDns) { $res = $this->_loadNetDns(); if (is_a($res, 'PEAR_Error')) { return $res; } $response = $this->resolver->query($host, 'MX'); if (!$response) { return false; } foreach ($response->answer as $rr) { if ($rr->type == 'MX') { $mx[$rr->exchange] = $rr->preference; } } } else { $mxHost = array(); $mxWeight = array(); if (!getmxrr($host, $mxHost, $mxWeight)) { return false; } for ($i = 0; $i < count($mxHost); ++$i) { $mx[$mxHost[$i]] = $mxWeight[$i]; } } asort($mx); return $mx; } /** * initialize PEAR:Net_DNS_Resolver * * @access private * @return boolean true on success */ function _loadNetDns() { if (is_object($this->resolver)) { return true; } if (!include_once 'Net/DNS.php') { return $this->_raiseError('no_resolver'); } $this->resolver = new Net_DNS_Resolver(); if ($this->debug) { $this->resolver->test = 1; } return true; } /** * raise standardized error * * include additional information in error message * * @access private * @param string $id maps error ids to codes and message * @param array $info optional information in associative array * @see _errorCode */ function _raiseError($id, $info = array()) { $code = $this->errorCode[$id]['code']; $msg = $this->errorCode[$id]['msg']; // include info to messages if (!empty($info)) { $search = array(); $replace = array(); foreach ($info as $key => $value) { array_push($search, '{' . strtoupper($key) . '}'); array_push($replace, $value); } $msg = str_replace($search, $replace, $msg); } return PEAR::raiseError($msg, $code); } } PK�����u]@iE\��\�� ��Mail/mail.phpnu�[��������<?php /** * internal PHP-mail() implementation of the PEAR Mail:: interface. * * PHP version 5 * * LICENSE: * * Copyright (c) 2010-2017, Chuck Hagenbuch * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are 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. Neither the name of the copyright holder nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS 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 COPYRIGHT * HOLDER OR 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. * * @category Mail * @package Mail * @author Chuck Hagenbuch <chuck@horde.org> * @copyright 2010-2017 Chuck Hagenbuch * @license http://opensource.org/licenses/BSD-3-Clause New BSD License * @version CVS: $Id$ * @link http://pear.php.net/package/Mail/ */ /** * internal PHP-mail() implementation of the PEAR Mail:: interface. * @package Mail * @version $Revision$ */ class Mail_mail extends Mail { /** * Any arguments to pass to the mail() function. * @var string */ var $_params = ''; /** * Constructor. * * Instantiates a new Mail_mail:: object based on the parameters * passed in. * * @param array $params Extra arguments for the mail() function. */ public function __construct($params = null) { // The other mail implementations accept parameters as arrays. // In the interest of being consistent, explode an array into // a string of parameter arguments. if (is_array($params)) { $this->_params = join(' ', $params); } else { $this->_params = $params; } /* Because the mail() function may pass headers as command * line arguments, we can't guarantee the use of the standard * "\r\n" separator. Instead, we use the system's native line * separator. */ if (defined('PHP_EOL')) { $this->sep = PHP_EOL; } else { $this->sep = (strpos(PHP_OS, 'WIN') === false) ? "\n" : "\r\n"; } } /** * Implements Mail_mail::send() function using php's built-in mail() * command. * * @param mixed $recipients Either a comma-seperated list of recipients * (RFC822 compliant), or an array of recipients, * each RFC822 valid. This may contain recipients not * specified in the headers, for Bcc:, resending * messages, etc. * * @param array $headers The array of headers to send with the mail, in an * associative array, where the array key is the * header name (ie, 'Subject'), and the array value * is the header value (ie, 'test'). The header * produced from those values would be 'Subject: * test'. * * @param string $body The full text of the message body, including any * Mime parts, etc. * * @return mixed Returns true on success, or a PEAR_Error * containing a descriptive error message on * failure. */ public function send($recipients, $headers, $body) { if (!is_array($headers)) { return PEAR::raiseError('$headers must be an array'); } $result = $this->_sanitizeHeaders($headers); if (is_a($result, 'PEAR_Error')) { return $result; } // If we're passed an array of recipients, implode it. if (is_array($recipients)) { $recipients = implode(', ', $recipients); } // Get the Subject out of the headers array so that we can // pass it as a seperate argument to mail(). $subject = ''; if (isset($headers['Subject'])) { $subject = $headers['Subject']; unset($headers['Subject']); } // Also remove the To: header. The mail() function will add its own // To: header based on the contents of $recipients. unset($headers['To']); // Flatten the headers out. $headerElements = $this->prepareHeaders($headers); if (is_a($headerElements, 'PEAR_Error')) { return $headerElements; } list(, $text_headers) = $headerElements; // We only use mail()'s optional fifth parameter if the additional // parameters have been provided and we're not running in safe mode. if (empty($this->_params) || ini_get('safe_mode')) { $result = mail($recipients, $subject, $body, $text_headers); } else { $result = mail($recipients, $subject, $body, $text_headers, $this->_params); } // If the mail() function returned failure, we need to create a // PEAR_Error object and return it instead of the boolean result. if ($result === false) { $result = PEAR::raiseError('mail() returned failure'); } return $result; } } PK�����u]+V���� ��Mail/mime.phpnu�[��������<?php /** * The Mail_Mime class is used to create MIME E-mail messages * * The Mail_Mime class provides an OO interface to create MIME * enabled email messages. This way you can create emails that * contain plain-text bodies, HTML bodies, attachments, inline * images and specific headers. * * Compatible with PHP version 5, 7 and 8 * * LICENSE: This LICENSE is in the BSD license style. * Copyright (c) 2002-2003, Richard Heyes <richard@phpguru.org> * Copyright (c) 2003-2006, PEAR <pear-group@php.net> * All rights reserved. * * Redistribution and use in source and binary forms, with or * without modification, are permitted provided that the following * conditions are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * - 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. * - Neither the name of the authors, nor the names of its contributors * may be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS 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 COPYRIGHT OWNER OR 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. * * @category Mail * @package Mail_Mime * @author Richard Heyes <richard@phpguru.org> * @author Tomas V.V. Cox <cox@idecnet.com> * @author Cipriano Groenendal <cipri@php.net> * @author Sean Coates <sean@php.net> * @author Aleksander Machniak <alec@php.net> * @copyright 2003-2006 PEAR <pear-group@php.net> * @license http://www.opensource.org/licenses/bsd-license.php BSD License * @version Release: @package_version@ * @link http://pear.php.net/package/Mail_mime * * This class is based on HTML Mime Mail class from * Richard Heyes <richard@phpguru.org> which was based also * in the mime_mail.class by Tobias Ratschiller <tobias@dnet.it> * and Sascha Schumann <sascha@schumann.cx> */ require_once 'PEAR.php'; require_once 'Mail/mimePart.php'; /** * The Mail_Mime class provides an OO interface to create MIME * enabled email messages. This way you can create emails that * contain plain-text bodies, HTML bodies, attachments, inline * images and specific headers. * * @category Mail * @package Mail_Mime * @author Richard Heyes <richard@phpguru.org> * @author Tomas V.V. Cox <cox@idecnet.com> * @author Cipriano Groenendal <cipri@php.net> * @author Sean Coates <sean@php.net> * @copyright 2003-2006 PEAR <pear-group@php.net> * @license http://www.opensource.org/licenses/bsd-license.php BSD License * @version Release: @package_version@ * @link http://pear.php.net/package/Mail_mime */ class Mail_mime { /** * Contains the plain text part of the email * * @var string */ protected $txtbody = ''; /** * Contains the html part of the email * * @var string */ protected $htmlbody = ''; /** * Contains the text/calendar part of the email * * @var string */ protected $calbody = ''; /** * List of the attached images * * @var array */ protected $html_images = array(); /** * List of the attachements * * @var array */ protected $parts = array(); /** * Headers for the mail * * @var array */ protected $headers = array(); /** * Build parameters * * @var array */ protected $build_params = array( // What encoding to use for the headers // Options: quoted-printable or base64 'head_encoding' => 'quoted-printable', // What encoding to use for plain text // Options: 7bit, 8bit, base64, or quoted-printable 'text_encoding' => 'quoted-printable', // What encoding to use for html // Options: 7bit, 8bit, base64, or quoted-printable 'html_encoding' => 'quoted-printable', // What encoding to use for calendar part // Options: 7bit, 8bit, base64, or quoted-printable 'calendar_encoding' => 'quoted-printable', // The character set to use for html 'html_charset' => 'ISO-8859-1', // The character set to use for text 'text_charset' => 'ISO-8859-1', // The character set to use for calendar part 'calendar_charset' => 'UTF-8', // The character set to use for headers 'head_charset' => 'ISO-8859-1', // End-of-line sequence 'eol' => "\r\n", // Delay attachment files IO until building the message 'delay_file_io' => false, // Default calendar method 'calendar_method' => 'request', // multipart part preamble (RFC2046 5.1.1) 'preamble' => '', ); /** * Constructor function * * @param mixed $params Build parameters that change the way the email * is built. Should be an associative array. * See $_build_params. * * @return void */ public function __construct($params = array()) { // Backward-compatible EOL setting if (is_string($params)) { $this->build_params['eol'] = $params; } else if (defined('MAIL_MIME_CRLF') && !isset($params['eol'])) { $this->build_params['eol'] = MAIL_MIME_CRLF; } // Update build parameters if (!empty($params) && is_array($params)) { $this->build_params = array_merge($this->build_params, $params); } } /** * Set build parameter value * * @param string $name Parameter name * @param string $value Parameter value * * @return void * @since 1.6.0 */ public function setParam($name, $value) { $this->build_params[$name] = $value; } /** * Get build parameter value * * @param string $name Parameter name * * @return mixed Parameter value * @since 1.6.0 */ public function getParam($name) { return isset($this->build_params[$name]) ? $this->build_params[$name] : null; } /** * Accessor function to set the body text. Body text is used if * it's not an html mail being sent or else is used to fill the * text/plain part that emails clients who don't support * html should show. * * @param string $data Either a string or the file name with the contents * @param bool $isfile If true the first param should be treated * as a file name, else as a string (default) * @param bool $append If true the text or file is appended to * the existing body, else the old body is * overwritten * * @return mixed True on success or PEAR_Error object */ public function setTXTBody($data, $isfile = false, $append = false) { return $this->setBody('txtbody', $data, $isfile, $append); } /** * Get message text body * * @return string Text body * @since 1.6.0 */ public function getTXTBody() { return $this->txtbody; } /** * Adds a html part to the mail. * * @param string $data Either a string or the file name with the contents * @param bool $isfile A flag that determines whether $data is a * filename, or a string(false, default) * * @return bool True on success or PEAR_Error object */ public function setHTMLBody($data, $isfile = false) { return $this->setBody('htmlbody', $data, $isfile); } /** * Get message HTML body * * @return string HTML body * @since 1.6.0 */ public function getHTMLBody() { return $this->htmlbody; } /** * Function to set a body of text/calendar part (not attachment) * * @param string $data Either a string or the file name with the contents * @param bool $isfile If true the first param should be treated * as a file name, else as a string (default) * @param bool $append If true the text or file is appended to * the existing body, else the old body is * overwritten * @param string $method iCalendar object method * @param string $charset iCalendar character set * @param string $encoding Transfer encoding * * @return mixed True on success or PEAR_Error object * @since 1.9.0 */ public function setCalendarBody($data, $isfile = false, $append = false, $method = 'request', $charset = 'UTF-8', $encoding = 'quoted-printable' ) { $result = $this->setBody('calbody', $data, $isfile, $append); if ($result === true) { $this->build_params['calendar_method'] = $method; $this->build_params['calendar_charset'] = $charset; $this->build_params['calendar_encoding'] = $encoding; } } /** * Get body of calendar part * * @return string Calendar part body * @since 1.9.0 */ public function getCalendarBody() { return $this->calbody; } /** * Adds an image to the list of embedded images. * Images added this way will be added as related parts of the HTML message. * * To correctly match the HTML image with the related attachment * HTML should refer to it by a filename (specified in $file or $name * arguments) or by cid:<content-id> (specified in $content_id arg). * * @param string $file The image file name OR image data itself * @param string $c_type The content type * @param string $name The filename of the image. Used to find * the image in HTML content. * @param bool $isfile Whether $file is a filename or not. * Defaults to true * @param string $content_id Desired Content-ID of MIME part * Defaults to generated unique ID * * @return bool True on success */ public function addHTMLImage($file, $c_type = 'application/octet-stream', $name = '', $isfile = true, $content_id = null ) { $bodyfile = null; if ($isfile) { // Don't load file into memory if ($this->build_params['delay_file_io']) { $filedata = null; $bodyfile = $file; } else { if (self::isError($filedata = $this->file2str($file))) { return $filedata; } } $filename = $name ? $name : $file; } else { $filedata = $file; $filename = $name; } if (!$content_id) { $content_id = preg_replace('/[^0-9a-zA-Z]/', '', uniqid(time(), true)); } $this->html_images[] = array( 'body' => $filedata, 'body_file' => $bodyfile, 'name' => $filename, 'c_type' => $c_type, 'cid' => $content_id ); return true; } /** * Adds a file to the list of attachments. * * @param mixed $file The file name or the file contents itself, * it can be also Mail_mimePart object * @param string $c_type The content type * @param string $name The filename of the attachment * Only use if $file is the contents * @param bool $isfile Whether $file is a filename or not. Defaults to true * @param string $encoding The type of encoding to use. Defaults to base64. * Possible values: 7bit, 8bit, base64 or quoted-printable. * @param string $disposition The content-disposition of this file * Defaults to attachment. * Possible values: attachment, inline. * @param string $charset The character set of attachment's content. * @param string $language The language of the attachment * @param string $location The RFC 2557.4 location of the attachment * @param string $n_encoding Encoding of the attachment's name in Content-Type * By default filenames are encoded using RFC2231 method * Here you can set RFC2047 encoding (quoted-printable * or base64) instead * @param string $f_encoding Encoding of the attachment's filename * in Content-Disposition header. * @param string $description Content-Description header * @param string $h_charset The character set of the headers e.g. filename * If not specified, $charset will be used * @param array $add_headers Additional part headers. Array keys can be in form * of <header_name>:<parameter_name> * * @return mixed True on success or PEAR_Error object */ public function addAttachment($file, $c_type = 'application/octet-stream', $name = '', $isfile = true, $encoding = 'base64', $disposition = 'attachment', $charset = '', $language = '', $location = '', $n_encoding = null, $f_encoding = null, $description = '', $h_charset = null, $add_headers = array() ) { if ($file instanceof Mail_mimePart) { $this->parts[] = $file; return true; } $bodyfile = null; if ($isfile) { // Don't load file into memory if ($this->build_params['delay_file_io']) { $filedata = null; $bodyfile = $file; } else { if (self::isError($filedata = $this->file2str($file))) { return $filedata; } } // Force the name the user supplied, otherwise use $file $filename = ($name ? $name : $this->basename($file)); } else { $filedata = $file; $filename = $name; } if (!strlen($filename)) { $msg = "The supplied filename for the attachment can't be empty"; return self::raiseError($msg); } $this->parts[] = array( 'body' => $filedata, 'body_file' => $bodyfile, 'name' => $filename, 'c_type' => $c_type, 'charset' => $charset, 'encoding' => $encoding, 'language' => $language, 'location' => $location, 'disposition' => $disposition, 'description' => $description, 'add_headers' => $add_headers, 'name_encoding' => $n_encoding, 'filename_encoding' => $f_encoding, 'headers_charset' => $h_charset, ); return true; } /** * Checks if the current message has many parts * * @return bool True if the message has many parts, False otherwise. * @since 1.9.0 */ public function isMultipart() { return count($this->parts) > 0 || count($this->html_images) > 0 || (strlen($this->htmlbody) > 0 && strlen($this->txtbody) > 0); } /** * Get the contents of the given file name as string * * @param string $file_name Path of file to process * * @return string Contents of $file_name */ protected function file2str($file_name) { // Check state of file and raise an error properly if (!file_exists($file_name)) { return self::raiseError('File not found: ' . $file_name); } if (!is_file($file_name)) { return self::raiseError('Not a regular file: ' . $file_name); } if (!is_readable($file_name)) { return self::raiseError('File is not readable: ' . $file_name); } // Temporarily reset magic_quotes_runtime and read file contents if (version_compare(PHP_VERSION, '5.4.0', '<')) { $magic_quotes = @ini_set('magic_quotes_runtime', 0); } $cont = file_get_contents($file_name); if (isset($magic_quotes)) { @ini_set('magic_quotes_runtime', $magic_quotes); } return $cont; } /** * Adds a text subpart to the mimePart object and * returns it during the build process. * * @param mixed $obj The object to add the part to, or * anything else if a new object is to be created. * * @return object The text mimePart object */ protected function addTextPart($obj = null) { return $this->addBodyPart($obj, $this->txtbody, 'text/plain', 'text'); } /** * Adds a html subpart to the mimePart object and * returns it during the build process. * * @param mixed $obj The object to add the part to, or * anything else if a new object is to be created. * * @return object The html mimePart object */ protected function addHtmlPart($obj = null) { return $this->addBodyPart($obj, $this->htmlbody, 'text/html', 'html'); } /** * Adds a calendar subpart to the mimePart object and * returns it during the build process. * * @param mixed $obj The object to add the part to, or * anything else if a new object is to be created. * * @return object The text mimePart object */ protected function addCalendarPart($obj = null) { $ctype = 'text/calendar; method='. $this->build_params['calendar_method']; return $this->addBodyPart($obj, $this->calbody, $ctype, 'calendar'); } /** * Creates a new mimePart object, using multipart/mixed as * the initial content-type and returns it during the * build process. * * @param array $params Additional part parameters * * @return object The multipart/mixed mimePart object */ protected function addMixedPart($params = array()) { $params['content_type'] = 'multipart/mixed'; $params['eol'] = $this->build_params['eol']; // Create empty multipart/mixed Mail_mimePart object to return return new Mail_mimePart('', $params); } /** * Adds a multipart/alternative part to a mimePart * object (or creates one), and returns it during * the build process. * * @param mixed $obj The object to add the part to, or * anything else if a new object is to be created. * * @return object The multipart/mixed mimePart object */ protected function addAlternativePart($obj = null) { $params['content_type'] = 'multipart/alternative'; $params['eol'] = $this->build_params['eol']; if (is_object($obj)) { $ret = $obj->addSubpart('', $params); } else { $ret = new Mail_mimePart('', $params); } return $ret; } /** * Adds a multipart/related part to a mimePart * object (or creates one), and returns it during * the build process. * * @param mixed $obj The object to add the part to, or * anything else if a new object is to be created * * @return object The multipart/mixed mimePart object */ protected function addRelatedPart($obj = null) { $params['content_type'] = 'multipart/related'; $params['eol'] = $this->build_params['eol']; if (is_object($obj)) { $ret = $obj->addSubpart('', $params); } else { $ret = new Mail_mimePart('', $params); } return $ret; } /** * Adds an html image subpart to a mimePart object * and returns it during the build process. * * @param object $obj The mimePart to add the image to * @param array $value The image information * * @return object The image mimePart object */ protected function addHtmlImagePart($obj, $value) { $params['content_type'] = $value['c_type']; $params['encoding'] = 'base64'; $params['disposition'] = 'inline'; $params['filename'] = $value['name']; $params['cid'] = $value['cid']; $params['body_file'] = $value['body_file']; $params['eol'] = $this->build_params['eol']; if (!empty($value['name_encoding'])) { $params['name_encoding'] = $value['name_encoding']; } if (!empty($value['filename_encoding'])) { $params['filename_encoding'] = $value['filename_encoding']; } return $obj->addSubpart($value['body'], $params); } /** * Adds an attachment subpart to a mimePart object * and returns it during the build process. * * @param object $obj The mimePart to add the image to * @param mixed $value The attachment information array or Mail_mimePart object * * @return object The image mimePart object */ protected function addAttachmentPart($obj, $value) { if ($value instanceof Mail_mimePart) { return $obj->addSubpart($value); } $params['eol'] = $this->build_params['eol']; $params['filename'] = $value['name']; $params['encoding'] = $value['encoding']; $params['content_type'] = $value['c_type']; $params['body_file'] = $value['body_file']; $params['disposition'] = isset($value['disposition']) ? $value['disposition'] : 'attachment'; // content charset if (!empty($value['charset'])) { $params['charset'] = $value['charset']; } // headers charset (filename, description) if (!empty($value['headers_charset'])) { $params['headers_charset'] = $value['headers_charset']; } if (!empty($value['language'])) { $params['language'] = $value['language']; } if (!empty($value['location'])) { $params['location'] = $value['location']; } if (!empty($value['name_encoding'])) { $params['name_encoding'] = $value['name_encoding']; } if (!empty($value['filename_encoding'])) { $params['filename_encoding'] = $value['filename_encoding']; } if (!empty($value['description'])) { $params['description'] = $value['description']; } if (is_array($value['add_headers'])) { $params['headers'] = $value['add_headers']; } return $obj->addSubpart($value['body'], $params); } /** * Returns the complete e-mail, ready to send using an alternative * mail delivery method. Note that only the mailpart that is made * with Mail_Mime is created. This means that, * YOU WILL HAVE NO TO: HEADERS UNLESS YOU SET IT YOURSELF * using the $headers parameter! * * @param string $separation The separation between these two parts. * @param array $params The Build parameters passed to the * get() function. See get() for more info. * @param array $headers The extra headers that should be passed * to the headers() method. * See that function for more info. * @param bool $overwrite Overwrite the existing headers with new. * * @return mixed The complete e-mail or PEAR error object */ public function getMessage($separation = null, $params = null, $headers = null, $overwrite = false ) { if ($separation === null) { $separation = $this->build_params['eol']; } $body = $this->get($params); if (self::isError($body)) { return $body; } return $this->txtHeaders($headers, $overwrite) . $separation . $body; } /** * Returns the complete e-mail body, ready to send using an alternative * mail delivery method. * * @param array $params The Build parameters passed to the * get() method. See get() for more info. * * @return mixed The e-mail body or PEAR error object * @since 1.6.0 */ public function getMessageBody($params = null) { return $this->get($params, null, true); } /** * Writes (appends) the complete e-mail into file. * * @param string $filename Output file location * @param array $params The Build parameters passed to the * get() method. See get() for more info. * @param array $headers The extra headers that should be passed * to the headers() function. * See that function for more info. * @param bool $overwrite Overwrite the existing headers with new. * * @return mixed True or PEAR error object * @since 1.6.0 */ public function saveMessage($filename, $params = null, $headers = null, $overwrite = false) { // Check state of file and raise an error properly if (file_exists($filename) && !is_writable($filename)) { return self::raiseError('File is not writable: ' . $filename); } // Temporarily reset magic_quotes_runtime and read file contents if (version_compare(PHP_VERSION, '5.4.0', '<')) { $magic_quotes = @ini_set('magic_quotes_runtime', 0); } if (!($fh = fopen($filename, 'ab'))) { return self::raiseError('Unable to open file: ' . $filename); } // Write message headers into file (skipping Content-* headers) $head = $this->txtHeaders($headers, $overwrite, true); if (fwrite($fh, $head) === false) { return self::raiseError('Error writing to file: ' . $filename); } fclose($fh); if (isset($magic_quotes)) { @ini_set('magic_quotes_runtime', $magic_quotes); } // Write the rest of the message into file $res = $this->get($params, $filename); return $res ? $res : true; } /** * Writes (appends) the complete e-mail body into file or stream. * * @param mixed $filename Output filename or file pointer where to save * the message instead of returning it * @param array $params The Build parameters passed to the * get() method. See get() for more info. * * @return mixed True or PEAR error object * @since 1.6.0 */ public function saveMessageBody($filename, $params = null) { if (!is_resource($filename)) { // Check state of file and raise an error properly if (!file_exists($filename) || !is_writable($filename)) { return self::raiseError('File is not writable: ' . $filename); } if (!($fh = fopen($filename, 'ab'))) { return self::raiseError('Unable to open file: ' . $filename); } } else { $fh = $filename; } // Temporarily reset magic_quotes_runtime and read file contents if (version_compare(PHP_VERSION, '5.4.0', '<')) { $magic_quotes = @ini_set('magic_quotes_runtime', 0); } // Write the rest of the message into file $res = $this->get($params, $fh, true); if (!is_resource($filename)) { fclose($fh); } if (isset($magic_quotes)) { @ini_set('magic_quotes_runtime', $magic_quotes); } return $res ? $res : true; } /** * Builds the multipart message from the list ($this->parts) and * returns the mime content. * * @param array $params Build parameters that change the way the email * is built. Should be associative. See $_build_params. * @param mixed $filename Output filename or file pointer where to save * the message instead of returning it * @param boolean $skip_head True if you want to return/save only the message * without headers * * @return mixed The MIME message content string, null or PEAR error object */ public function get($params = null, $filename = null, $skip_head = false) { if (!empty($params) && is_array($params)) { $this->build_params = array_merge($this->build_params, $params); } if (isset($this->headers['From'])) { // Bug #11381: Illegal characters in domain ID if (preg_match('#(@[0-9a-zA-Z\-\.]+)#', $this->headers['From'], $matches)) { $domainID = $matches[1]; } else { $domainID = '@localhost'; } foreach ($this->html_images as $i => $img) { $cid = $this->html_images[$i]['cid']; if (!preg_match('#'.preg_quote($domainID).'$#', $cid)) { $this->html_images[$i]['cid'] = $cid . $domainID; } } } if (count($this->html_images) && strlen($this->htmlbody) > 0) { foreach ($this->html_images as $key => $value) { $rval = preg_quote($value['name'], '#'); $regex = array( '#(\s)((?i)src|background|href(?-i))\s*=\s*(["\']?)' . $rval . '\3#', '#(?i)url(?-i)\(\s*(["\']?)' . $rval . '\1\s*\)#', ); $rep = array( '\1\2=\3cid:' . $value['cid'] .'\3', 'url(\1cid:' . $value['cid'] . '\1)', ); $this->htmlbody = preg_replace($regex, $rep, $this->htmlbody); $this->html_images[$key]['name'] = $this->basename($this->html_images[$key]['name']); } } $this->checkParams(); $message = $this->buildBodyPart(); if (!isset($message)) { return null; } // Use saved boundary if (!empty($this->build_params['boundary'])) { $boundary = $this->build_params['boundary']; } else { $boundary = null; } // Write output to file if ($filename) { // Append mimePart message headers and body into file $headers = $message->encodeToFile($filename, $boundary, $skip_head); if (self::isError($headers)) { return $headers; } $this->headers = array_merge($this->headers, $headers); } else { $output = $message->encode($boundary, $skip_head); if (self::isError($output)) { return $output; } $this->headers = array_merge($this->headers, $output['headers']); } // remember the boundary used, in case we'd handle headers() call later if (empty($boundary) && !empty($this->headers['Content-Type'])) { if (preg_match('/boundary="([^"]+)/', $this->headers['Content-Type'], $m)) { $this->build_params['boundary'] = $m[1]; } } return $filename ? null : $output['body']; } /** * Builds the main body MIME part for the email body. It will add a mixed part * if attachments are found. If no attachments are found it will return an * alternative part if several body texts are found (text, html, calendar), * or a single part if only one body text is found. * * @return Mail_mimePart|null The corresponding part for the body or null. * * @see buildAlternativeParts * @see buildHtmlParts */ protected function buildBodyPart() { $parts_count = count($this->parts); $mixed_params = array('preamble' => $this->build_params['preamble']); $message = null; if ($parts_count > 0) { $message = $this->addMixedPart($mixed_params); $this->buildAlternativeParts($message, null); for ($i = 0; $i < $parts_count; $i++) { $this->addAttachmentPart($message, $this->parts[$i]); } } else { $message = $this->buildAlternativeParts(null, $mixed_params); } return $message; } /** * Builds a single text, html, or calendar part only if one of them is found. * If two or more parts are found, then an alternative part containing them is built. * * @param Mail_mimePart|null $parent_part The parent mime part to add * the part or null * @param array $mixed_params The needed params to create the * part when no parent_part is * received. * * @return null|object The main part built inside the method. It will be an * alternative part or text, html, or calendar part. * Null if no body texts are found. */ protected function buildAlternativeParts($parent_part, $mixed_params = null) { $html = strlen($this->htmlbody) > 0; $calendar = strlen($this->calbody) > 0; $has_text = strlen($this->txtbody) > 0; $alternatives_count = $html + $calendar + $has_text; if ($alternatives_count > 1) { $alt_part = $this->addAlternativePart($parent_part ? $parent_part : $mixed_params); } else { $alt_part = null; } $dest_part = $alt_part ? $alt_part : $parent_part; $part = null; if ($has_text) { $part = $this->addTextPart($dest_part); } if ($html) { $part = $this->buildHtmlParts($dest_part); } if ($calendar) { $part = $this->addCalendarPart($dest_part); } return $dest_part ? $dest_part : $part; } /** * Builds html part as a single part or inside a related part with the html * images thar were found. * * @param Mail_mimePart|null $parent_part The object to add the part to, * or anything else if a new object * is to be created. * * @return Mail_mimePart|null The created part or null if no htmlbody found. */ protected function buildHtmlParts($parent_part) { if (!strlen($this->htmlbody)) { return null; } $count_html_images = count($this->html_images); if ($count_html_images > 0) { $part = $this->addRelatedPart($parent_part); $this->addHtmlPart($part); } else { $part = $this->addHtmlPart($parent_part); } for ($i = 0; $i < $count_html_images; $i++) { $this->addHtmlImagePart($part, $this->html_images[$i]); } return $part; } /** * Returns an array with the headers needed to prepend to the email * (MIME-Version and Content-Type). Format of argument is: * $array['header-name'] = 'header-value'; * * @param array $xtra_headers Assoc array with any extra headers (optional) * (Don't set Content-Type for multipart messages here!) * @param bool $overwrite Overwrite already existing headers. * @param bool $skip_content Don't return content headers: Content-Type, * Content-Disposition and Content-Transfer-Encoding * * @return array Assoc array with the mime headers */ public function headers($xtra_headers = null, $overwrite = false, $skip_content = false) { // Add mime version header $headers['MIME-Version'] = '1.0'; if (!empty($xtra_headers)) { $headers = array_merge($headers, $xtra_headers); } if ($overwrite) { $this->headers = array_merge($this->headers, $headers); } else { $this->headers = array_merge($headers, $this->headers); } // Always reset Content-Type/Content-Transfer-Encoding headers // In case the message structure changed in meantime unset($this->headers['Content-Type']); unset($this->headers['Content-Transfer-Encoding']); unset($this->headers['Content-Disposition']); $this->headers = array_merge($this->headers, $this->contentHeaders()); $headers = $this->headers; if ($skip_content) { unset($headers['Content-Type']); unset($headers['Content-Transfer-Encoding']); unset($headers['Content-Disposition']); } else if (!empty($this->build_params['ctype'])) { $headers['Content-Type'] = $this->build_params['ctype']; } return $this->encodeHeaders($headers); } /** * Get the text version of the headers * (usefull if you want to use the PHP mail() function) * * @param array $xtra_headers Assoc array with any extra headers (optional) * (Don't set Content-Type for multipart messages here!) * @param bool $overwrite Overwrite the existing headers with new. * @param bool $skip_content Don't return content headers: Content-Type, * Content-Disposition and Content-Transfer-Encoding * * @return string Plain text headers */ public function txtHeaders($xtra_headers = null, $overwrite = false, $skip_content = false) { $headers = $this->headers($xtra_headers, $overwrite, $skip_content); // Place Received: headers at the beginning of the message // Spam detectors often flag messages with it after the Subject: as spam if (isset($headers['Received'])) { $received = $headers['Received']; unset($headers['Received']); $headers = array('Received' => $received) + $headers; } $ret = ''; $eol = $this->build_params['eol']; foreach ($headers as $key => $val) { if (is_array($val)) { foreach ($val as $value) { $ret .= "$key: $value" . $eol; } } else { $ret .= "$key: $val" . $eol; } } return $ret; } /** * Sets message Content-Type header. * Use it to build messages with various content-types e.g. miltipart/raport * not supported by contentHeaders() function. * * @param string $type Type name * @param array $params Hash array of header parameters * * @return void * @since 1.7.0 */ public function setContentType($type, $params = array()) { $header = $type; $eol = !empty($this->build_params['eol']) ? $this->build_params['eol'] : "\r\n"; // add parameters $token_regexp = '#([^\x21\x23-\x27\x2A\x2B\x2D\x2E\x30-\x39\x41-\x5A\x5E-\x7E])#'; if (is_array($params)) { foreach ($params as $name => $value) { if ($name == 'boundary') { $this->build_params['boundary'] = $value; } else if (!preg_match($token_regexp, $value)) { $header .= ";$eol $name=$value"; } else { $value = addcslashes($value, '\\"'); $header .= ";$eol $name=\"$value\""; } } } // add required boundary parameter if not defined if (stripos($type, 'multipart/') === 0) { if (empty($this->build_params['boundary'])) { $this->build_params['boundary'] = '=_' . md5(rand() . microtime()); } $header .= ";$eol boundary=\"".$this->build_params['boundary']."\""; } $this->build_params['ctype'] = $header; } /** * Sets the Subject header * * @param string $subject String to set the subject to. * * @return void */ public function setSubject($subject) { $this->headers['Subject'] = $subject; } /** * Set an email to the From (the sender) header * * @param string $email The email address to use * * @return void */ public function setFrom($email) { $this->headers['From'] = $email; } /** * Add an email to the To header * (multiple calls to this method are allowed) * * @param string $email The email direction to add * * @return void */ public function addTo($email) { if (isset($this->headers['To'])) { $this->headers['To'] .= ", $email"; } else { $this->headers['To'] = $email; } } /** * Add an email to the Cc (carbon copy) header * (multiple calls to this method are allowed) * * @param string $email The email direction to add * * @return void */ public function addCc($email) { if (isset($this->headers['Cc'])) { $this->headers['Cc'] .= ", $email"; } else { $this->headers['Cc'] = $email; } } /** * Add an email to the Bcc (blank carbon copy) header * (multiple calls to this method are allowed) * * @param string $email The email direction to add * * @return void */ public function addBcc($email) { if (isset($this->headers['Bcc'])) { $this->headers['Bcc'] .= ", $email"; } else { $this->headers['Bcc'] = $email; } } /** * Since the PHP send function requires you to specify * recipients (To: header) separately from the other * headers, the To: header is not properly encoded. * To fix this, you can use this public method to encode * your recipients before sending to the send function. * * @param string $recipients A comma-delimited list of recipients * * @return string Encoded data */ public function encodeRecipients($recipients) { $input = array('To' => $recipients); $retval = $this->encodeHeaders($input); return $retval['To'] ; } /** * Encodes headers as per RFC2047 * * @param array $input The header data to encode * @param array $params Extra build parameters * * @return array Encoded data */ protected function encodeHeaders($input, $params = array()) { $build_params = $this->build_params; if (!empty($params)) { $build_params = array_merge($build_params, $params); } foreach ($input as $hdr_name => $hdr_value) { if (is_array($hdr_value)) { foreach ($hdr_value as $idx => $value) { $input[$hdr_name][$idx] = $this->encodeHeader( $hdr_name, $value, $build_params['head_charset'], $build_params['head_encoding'] ); } } else if ($hdr_value !== null) { $input[$hdr_name] = $this->encodeHeader( $hdr_name, $hdr_value, $build_params['head_charset'], $build_params['head_encoding'] ); } else { unset($input[$hdr_name]); } } return $input; } /** * Encodes a header as per RFC2047 * * @param string $name The header name * @param string $value The header data to encode * @param string $charset Character set name * @param string $encoding Encoding name (base64 or quoted-printable) * * @return string Encoded header data (without a name) * @since 1.5.3 */ public function encodeHeader($name, $value, $charset, $encoding) { return Mail_mimePart::encodeHeader( $name, $value, $charset, $encoding, $this->build_params['eol'] ); } /** * Get file's basename (locale independent) * * @param string $filename Filename * * @return string Basename */ protected function basename($filename) { // basename() is not unicode safe and locale dependent if (stristr(PHP_OS, 'win') || stristr(PHP_OS, 'netware')) { return preg_replace('/^.*[\\\\\\/]/', '', $filename); } else { return preg_replace('/^.*[\/]/', '', $filename); } } /** * Get Content-Type and Content-Transfer-Encoding headers of the message * * @return array Headers array */ protected function contentHeaders() { $attachments = count($this->parts) > 0; $html_images = count($this->html_images) > 0; $html = strlen($this->htmlbody) > 0; $calendar = strlen($this->calbody) > 0; $has_text = strlen($this->txtbody) > 0; $has_alternatives = ($html + $calendar + $has_text) > 1; $headers = array(); // See get() switch (true) { case $has_text && !$attachments && !$has_alternatives: $headers['Content-Type'] = 'text/plain'; break; case $html && !$html_images && !$attachments && !$has_alternatives: $headers['Content-Type'] = 'text/html'; break; case $html && $html_images && !$attachments && !$has_alternatives: $headers['Content-Type'] = 'multipart/related'; break; case $calendar && !$attachments && !$has_alternatives: $headers['Content-Type'] = 'text/calendar'; break; case $has_alternatives && !$attachments: $headers['Content-Type'] = 'multipart/alternative'; break; case $attachments: $headers['Content-Type'] = 'multipart/mixed'; break; } // Note: This is outside of the above switch construct to workaround // opcache bug: https://bugzilla.opensuse.org/show_bug.cgi?id=1166235 if (empty($headers)) { return $headers; } $this->checkParams(); $eol = !empty($this->build_params['eol']) ? $this->build_params['eol'] : "\r\n"; if ($headers['Content-Type'] == 'text/plain') { // single-part message: add charset and encoding if ($this->build_params['text_charset']) { $charset = 'charset=' . $this->build_params['text_charset']; // place charset parameter in the same line, if possible // 26 = strlen("Content-Type: text/plain; ") $headers['Content-Type'] .= (strlen($charset) + 26 <= 76) ? "; $charset" : ";$eol $charset"; } $headers['Content-Transfer-Encoding'] = $this->build_params['text_encoding']; } else if ($headers['Content-Type'] == 'text/html') { // single-part message: add charset and encoding if ($this->build_params['html_charset']) { $charset = 'charset=' . $this->build_params['html_charset']; // place charset parameter in the same line, if possible $headers['Content-Type'] .= (strlen($charset) + 25 <= 76) ? "; $charset" : ";$eol $charset"; } $headers['Content-Transfer-Encoding'] = $this->build_params['html_encoding']; } else if ($headers['Content-Type'] == 'text/calendar') { // single-part message: add charset and encoding if ($this->build_params['calendar_charset']) { $charset = 'charset=' . $this->build_params['calendar_charset']; $headers['Content-Type'] .= "; $charset"; } if ($this->build_params['calendar_method']) { $method = 'method=' . $this->build_params['calendar_method']; $headers['Content-Type'] .= "; $method"; } $headers['Content-Transfer-Encoding'] = $this->build_params['calendar_encoding']; } else { // multipart message: and boundary if (!empty($this->build_params['boundary'])) { $boundary = $this->build_params['boundary']; } else if (!empty($this->headers['Content-Type']) && preg_match('/boundary="([^"]+)"/', $this->headers['Content-Type'], $m) ) { $boundary = $m[1]; } else { $boundary = '=_' . md5(rand() . microtime()); } $this->build_params['boundary'] = $boundary; $headers['Content-Type'] .= ";$eol boundary=\"$boundary\""; } return $headers; } /** * Validate and set build parameters * * @return void */ protected function checkParams() { $encodings = array('7bit', '8bit', 'base64', 'quoted-printable'); $this->build_params['text_encoding'] = strtolower($this->build_params['text_encoding']); $this->build_params['html_encoding'] = strtolower($this->build_params['html_encoding']); $this->build_params['calendar_encoding'] = strtolower($this->build_params['calendar_encoding']); if (!in_array($this->build_params['text_encoding'], $encodings)) { $this->build_params['text_encoding'] = '7bit'; } if (!in_array($this->build_params['html_encoding'], $encodings)) { $this->build_params['html_encoding'] = '7bit'; } if (!in_array($this->build_params['calendar_encoding'], $encodings)) { $this->build_params['calendar_encoding'] = '7bit'; } // text body if ($this->build_params['text_encoding'] == '7bit' && !preg_match('/ascii/i', $this->build_params['text_charset']) && preg_match('/[^\x00-\x7F]/', $this->txtbody) ) { $this->build_params['text_encoding'] = 'quoted-printable'; } // html body if ($this->build_params['html_encoding'] == '7bit' && !preg_match('/ascii/i', $this->build_params['html_charset']) && preg_match('/[^\x00-\x7F]/', $this->htmlbody) ) { $this->build_params['html_encoding'] = 'quoted-printable'; } // calendar body if ($this->build_params['calendar_encoding'] == '7bit' && !preg_match('/ascii/i', $this->build_params['calendar_charset']) && preg_match('/[^\x00-\x7F]/', $this->calbody) ) { $this->build_params['calendar_encoding'] = 'quoted-printable'; } } /** * Set body of specified message part * * @param string $type One of: txtbody, calbody, htmlbody * @param string $data Either a string or the file name with the contents * @param bool $isfile If true the first param should be treated * as a file name, else as a string (default) * @param bool $append If true the text or file is appended to * the existing body, else the old body is * overwritten * * @return mixed True on success or PEAR_Error object */ protected function setBody($type, $data, $isfile = false, $append = false) { if ($isfile) { $data = $this->file2str($data); if (self::isError($data)) { return $data; } } if (!$append) { $this->{$type} = $data; } else { $this->{$type} .= $data; } return true; } /** * Adds a subpart to the mimePart object and * returns it during the build process. * * @param mixed $obj The object to add the part to, or * anything else if a new object is to be created. * @param string $body Part body * @param string $ctype Part content type * @param string $type Internal part type * * @return object The mimePart object */ protected function addBodyPart($obj, $body, $ctype, $type) { $params['content_type'] = $ctype; $params['encoding'] = $this->build_params[$type . '_encoding']; $params['charset'] = $this->build_params[$type . '_charset']; $params['eol'] = $this->build_params['eol']; if (is_object($obj)) { $ret = $obj->addSubpart($body, $params); } else { $ret = new Mail_mimePart($body, $params); } return $ret; } /** * PEAR::isError implementation * * @param mixed $data Object * * @return bool True if object is an instance of PEAR_Error */ public static function isError($data) { // PEAR::isError() is not PHP 5.4 compatible (see Bug #19473) if (is_a($data, 'PEAR_Error')) { return true; } return false; } /** * PEAR::raiseError implementation * * @param string $message A text error message * * @return PEAR_Error Instance of PEAR_Error */ public static function raiseError($message) { // PEAR::raiseError() is not PHP 5.4 compatible return new PEAR_Error($message); } } PK�����u]oP��P�� ��System.phpnu�[��������<?php /** * File/Directory manipulation * * PHP versions 4 and 5 * * @category pear * @package System * @author Tomas V.V.Cox <cox@idecnet.com> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 0.1 */ /** * base class */ require_once 'PEAR.php'; require_once 'Console/Getopt.php'; $GLOBALS['_System_temp_files'] = array(); /** * System offers cross platform compatible system functions * * Static functions for different operations. Should work under * Unix and Windows. The names and usage has been taken from its respectively * GNU commands. The functions will return (bool) false on error and will * trigger the error with the PHP trigger_error() function (you can silence * the error by prefixing a '@' sign after the function call, but this * is not recommended practice. Instead use an error handler with * {@link set_error_handler()}). * * Documentation on this class you can find in: * http://pear.php.net/manual/ * * Example usage: * if (!@System::rm('-r file1 dir1')) { * print "could not delete file1 or dir1"; * } * * In case you need to to pass file names with spaces, * pass the params as an array: * * System::rm(array('-r', $file1, $dir1)); * * @category pear * @package System * @author Tomas V.V. Cox <cox@idecnet.com> * @copyright 1997-2006 The PHP Group * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 0.1 * @static */ class System { /** * returns the commandline arguments of a function * * @param string $argv the commandline * @param string $short_options the allowed option short-tags * @param string $long_options the allowed option long-tags * @return array the given options and there values */ public static function _parseArgs($argv, $short_options, $long_options = null) { if (!is_array($argv) && $argv !== null) { /* // Quote all items that are a short option $av = preg_split('/(\A| )--?[a-z0-9]+[ =]?((?<!\\\\)((,\s*)|((?<!,)\s+))?)/i', $argv, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_OFFSET_CAPTURE); $offset = 0; foreach ($av as $a) { $b = trim($a[0]); if ($b[0] == '"' || $b[0] == "'") { continue; } $escape = escapeshellarg($b); $pos = $a[1] + $offset; $argv = substr_replace($argv, $escape, $pos, strlen($b)); $offset += 2; } */ // Find all items, quoted or otherwise preg_match_all("/(?:[\"'])(.*?)(?:['\"])|([^\s]+)/", $argv, $av); $argv = $av[1]; foreach ($av[2] as $k => $a) { if (empty($a)) { continue; } $argv[$k] = trim($a) ; } } return Console_Getopt::getopt2($argv, $short_options, $long_options); } /** * Output errors with PHP trigger_error(). You can silence the errors * with prefixing a "@" sign to the function call: @System::mkdir(..); * * @param mixed $error a PEAR error or a string with the error message * @return bool false */ protected static function raiseError($error) { if (PEAR::isError($error)) { $error = $error->getMessage(); } trigger_error($error, E_USER_WARNING); return false; } /** * Creates a nested array representing the structure of a directory * * System::_dirToStruct('dir1', 0) => * Array * ( * [dirs] => Array * ( * [0] => dir1 * ) * * [files] => Array * ( * [0] => dir1/file2 * [1] => dir1/file3 * ) * ) * @param string $sPath Name of the directory * @param integer $maxinst max. deep of the lookup * @param integer $aktinst starting deep of the lookup * @param bool $silent if true, do not emit errors. * @return array the structure of the dir */ protected static function _dirToStruct($sPath, $maxinst, $aktinst = 0, $silent = false) { $struct = array('dirs' => array(), 'files' => array()); if (($dir = @opendir($sPath)) === false) { if (!$silent) { System::raiseError("Could not open dir $sPath"); } return $struct; // XXX could not open error } $struct['dirs'][] = $sPath = realpath($sPath); // XXX don't add if '.' or '..' ? $list = array(); while (false !== ($file = readdir($dir))) { if ($file != '.' && $file != '..') { $list[] = $file; } } closedir($dir); natsort($list); if ($aktinst < $maxinst || $maxinst == 0) { foreach ($list as $val) { $path = $sPath . DIRECTORY_SEPARATOR . $val; if (is_dir($path) && !is_link($path)) { $tmp = System::_dirToStruct($path, $maxinst, $aktinst+1, $silent); $struct = array_merge_recursive($struct, $tmp); } else { $struct['files'][] = $path; } } } return $struct; } /** * Creates a nested array representing the structure of a directory and files * * @param array $files Array listing files and dirs * @return array * @static * @see System::_dirToStruct() */ protected static function _multipleToStruct($files) { $struct = array('dirs' => array(), 'files' => array()); settype($files, 'array'); foreach ($files as $file) { if (is_dir($file) && !is_link($file)) { $tmp = System::_dirToStruct($file, 0); $struct = array_merge_recursive($tmp, $struct); } else { if (!in_array($file, $struct['files'])) { $struct['files'][] = $file; } } } return $struct; } /** * The rm command for removing files. * Supports multiple files and dirs and also recursive deletes * * @param string $args the arguments for rm * @return mixed PEAR_Error or true for success * @static * @access public */ public static function rm($args) { $opts = System::_parseArgs($args, 'rf'); // "f" does nothing but I like it :-) if (PEAR::isError($opts)) { return System::raiseError($opts); } foreach ($opts[0] as $opt) { if ($opt[0] == 'r') { $do_recursive = true; } } $ret = true; if (isset($do_recursive)) { $struct = System::_multipleToStruct($opts[1]); foreach ($struct['files'] as $file) { if (!@unlink($file)) { $ret = false; } } rsort($struct['dirs']); foreach ($struct['dirs'] as $dir) { if (!@rmdir($dir)) { $ret = false; } } } else { foreach ($opts[1] as $file) { $delete = (is_dir($file)) ? 'rmdir' : 'unlink'; if (!@$delete($file)) { $ret = false; } } } return $ret; } /** * Make directories. * * The -p option will create parent directories * @param string $args the name of the director(y|ies) to create * @return bool True for success */ public static function mkDir($args) { $opts = System::_parseArgs($args, 'pm:'); if (PEAR::isError($opts)) { return System::raiseError($opts); } $mode = 0777; // default mode foreach ($opts[0] as $opt) { if ($opt[0] == 'p') { $create_parents = true; } elseif ($opt[0] == 'm') { // if the mode is clearly an octal number (starts with 0) // convert it to decimal if (strlen($opt[1]) && $opt[1][0] == '0') { $opt[1] = octdec($opt[1]); } else { // convert to int $opt[1] += 0; } $mode = $opt[1]; } } $ret = true; if (isset($create_parents)) { foreach ($opts[1] as $dir) { $dirstack = array(); while ((!file_exists($dir) || !is_dir($dir)) && $dir != DIRECTORY_SEPARATOR) { array_unshift($dirstack, $dir); $dir = dirname($dir); } while ($newdir = array_shift($dirstack)) { if (!is_writeable(dirname($newdir))) { $ret = false; break; } if (!mkdir($newdir, $mode)) { $ret = false; } } } } else { foreach($opts[1] as $dir) { if ((@file_exists($dir) || !is_dir($dir)) && !mkdir($dir, $mode)) { $ret = false; } } } return $ret; } /** * Concatenate files * * Usage: * 1) $var = System::cat('sample.txt test.txt'); * 2) System::cat('sample.txt test.txt > final.txt'); * 3) System::cat('sample.txt test.txt >> final.txt'); * * Note: as the class use fopen, urls should work also * * @param string $args the arguments * @return boolean true on success */ public static function &cat($args) { $ret = null; $files = array(); if (!is_array($args)) { $args = preg_split('/\s+/', $args, -1, PREG_SPLIT_NO_EMPTY); } $count_args = count($args); for ($i = 0; $i < $count_args; $i++) { if ($args[$i] == '>') { $mode = 'wb'; $outputfile = $args[$i+1]; break; } elseif ($args[$i] == '>>') { $mode = 'ab+'; $outputfile = $args[$i+1]; break; } else { $files[] = $args[$i]; } } $outputfd = false; if (isset($mode)) { if (!$outputfd = fopen($outputfile, $mode)) { $err = System::raiseError("Could not open $outputfile"); return $err; } $ret = true; } foreach ($files as $file) { if (!$fd = fopen($file, 'r')) { System::raiseError("Could not open $file"); continue; } while ($cont = fread($fd, 2048)) { if (is_resource($outputfd)) { fwrite($outputfd, $cont); } else { $ret .= $cont; } } fclose($fd); } if (is_resource($outputfd)) { fclose($outputfd); } return $ret; } /** * Creates temporary files or directories. This function will remove * the created files when the scripts finish its execution. * * Usage: * 1) $tempfile = System::mktemp("prefix"); * 2) $tempdir = System::mktemp("-d prefix"); * 3) $tempfile = System::mktemp(); * 4) $tempfile = System::mktemp("-t /var/tmp prefix"); * * prefix -> The string that will be prepended to the temp name * (defaults to "tmp"). * -d -> A temporary dir will be created instead of a file. * -t -> The target dir where the temporary (file|dir) will be created. If * this param is missing by default the env vars TMP on Windows or * TMPDIR in Unix will be used. If these vars are also missing * c:\windows\temp or /tmp will be used. * * @param string $args The arguments * @return mixed the full path of the created (file|dir) or false * @see System::tmpdir() */ public static function mktemp($args = null) { static $first_time = true; $opts = System::_parseArgs($args, 't:d'); if (PEAR::isError($opts)) { return System::raiseError($opts); } foreach ($opts[0] as $opt) { if ($opt[0] == 'd') { $tmp_is_dir = true; } elseif ($opt[0] == 't') { $tmpdir = $opt[1]; } } $prefix = (isset($opts[1][0])) ? $opts[1][0] : 'tmp'; if (!isset($tmpdir)) { $tmpdir = System::tmpdir(); } if (!System::mkDir(array('-p', $tmpdir))) { return false; } $tmp = tempnam($tmpdir, $prefix); if (isset($tmp_is_dir)) { unlink($tmp); // be careful possible race condition here if (!mkdir($tmp, 0700)) { return System::raiseError("Unable to create temporary directory $tmpdir"); } } $GLOBALS['_System_temp_files'][] = $tmp; if (isset($tmp_is_dir)) { //$GLOBALS['_System_temp_files'][] = dirname($tmp); } if ($first_time) { PEAR::registerShutdownFunc(array('System', '_removeTmpFiles')); $first_time = false; } return $tmp; } /** * Remove temporary files created my mkTemp. This function is executed * at script shutdown time */ public static function _removeTmpFiles() { if (count($GLOBALS['_System_temp_files'])) { $delete = $GLOBALS['_System_temp_files']; array_unshift($delete, '-r'); System::rm($delete); $GLOBALS['_System_temp_files'] = array(); } } /** * Get the path of the temporal directory set in the system * by looking in its environments variables. * Note: php.ini-recommended removes the "E" from the variables_order setting, * making unavaible the $_ENV array, that s why we do tests with _ENV * * @return string The temporary directory on the system */ public static function tmpdir() { if (OS_WINDOWS) { if ($var = isset($_ENV['TMP']) ? $_ENV['TMP'] : getenv('TMP')) { return $var; } if ($var = isset($_ENV['TEMP']) ? $_ENV['TEMP'] : getenv('TEMP')) { return $var; } if ($var = isset($_ENV['USERPROFILE']) ? $_ENV['USERPROFILE'] : getenv('USERPROFILE')) { return $var; } if ($var = isset($_ENV['windir']) ? $_ENV['windir'] : getenv('windir')) { return $var; } return getenv('SystemRoot') . '\temp'; } if ($var = isset($_ENV['TMPDIR']) ? $_ENV['TMPDIR'] : getenv('TMPDIR')) { return $var; } return realpath(function_exists('sys_get_temp_dir') ? sys_get_temp_dir() : '/tmp'); } /** * The "which" command (show the full path of a command) * * @param string $program The command to search for * @param mixed $fallback Value to return if $program is not found * * @return mixed A string with the full path or false if not found * @author Stig Bakken <ssb@php.net> */ public static function which($program, $fallback = false) { // enforce API if (!is_string($program) || '' == $program) { return $fallback; } // full path given if (basename($program) != $program) { $path_elements[] = dirname($program); $program = basename($program); } else { $path = getenv('PATH'); if (!$path) { $path = getenv('Path'); // some OSes are just stupid enough to do this } $path_elements = explode(PATH_SEPARATOR, $path); } if (OS_WINDOWS) { $exe_suffixes = getenv('PATHEXT') ? explode(PATH_SEPARATOR, getenv('PATHEXT')) : array('.exe','.bat','.cmd','.com'); // allow passing a command.exe param if (strpos($program, '.') !== false) { array_unshift($exe_suffixes, ''); } } else { $exe_suffixes = array(''); } foreach ($exe_suffixes as $suff) { foreach ($path_elements as $dir) { $file = $dir . DIRECTORY_SEPARATOR . $program . $suff; // It's possible to run a .bat on Windows that is_executable // would return false for. The is_executable check is meaningless... if (OS_WINDOWS) { if (file_exists($file)) { return $file; } } else { if (is_executable($file)) { return $file; } } } } return $fallback; } /** * The "find" command * * Usage: * * System::find($dir); * System::find("$dir -type d"); * System::find("$dir -type f"); * System::find("$dir -name *.php"); * System::find("$dir -name *.php -name *.htm*"); * System::find("$dir -maxdepth 1"); * * Params implemented: * $dir -> Start the search at this directory * -type d -> return only directories * -type f -> return only files * -maxdepth <n> -> max depth of recursion * -name <pattern> -> search pattern (bash style). Multiple -name param allowed * * @param mixed Either array or string with the command line * @return array Array of found files */ public static function find($args) { if (!is_array($args)) { $args = preg_split('/\s+/', $args, -1, PREG_SPLIT_NO_EMPTY); } $dir = realpath(array_shift($args)); if (!$dir) { return array(); } $patterns = array(); $depth = 0; $do_files = $do_dirs = true; $args_count = count($args); for ($i = 0; $i < $args_count; $i++) { switch ($args[$i]) { case '-type': if (in_array($args[$i+1], array('d', 'f'))) { if ($args[$i+1] == 'd') { $do_files = false; } else { $do_dirs = false; } } $i++; break; case '-name': $name = preg_quote($args[$i+1], '#'); // our magic characters ? and * have just been escaped, // so now we change the escaped versions to PCRE operators $name = strtr($name, array('\?' => '.', '\*' => '.*')); $patterns[] = '('.$name.')'; $i++; break; case '-maxdepth': $depth = $args[$i+1]; break; } } $path = System::_dirToStruct($dir, $depth, 0, true); if ($do_files && $do_dirs) { $files = array_merge($path['files'], $path['dirs']); } elseif ($do_dirs) { $files = $path['dirs']; } else { $files = $path['files']; } if (count($patterns)) { $dsq = preg_quote(DIRECTORY_SEPARATOR, '#'); $pattern = '#(^|'.$dsq.')'.implode('|', $patterns).'($|'.$dsq.')#'; $ret = array(); $files_count = count($files); for ($i = 0; $i < $files_count; $i++) { // only search in the part of the file below the current directory $filepart = basename($files[$i]); if (preg_match($pattern, $filepart)) { $ret[] = $files[$i]; } } return $ret; } return $files; } } PK�����u]=Y�Y���Archive/Tar.phpnu�[��������<?php /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ /** * File::CSV * * PHP versions 4 and 5 * * Copyright (c) 1997-2008, * Vincent Blavet <vincent@phpconcept.net> * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 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. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS 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 COPYRIGHT OWNER OR 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. * * @category File_Formats * @package Archive_Tar * @author Vincent Blavet <vincent@phpconcept.net> * @copyright 1997-2010 The Authors * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version CVS: $Id$ * @link http://pear.php.net/package/Archive_Tar */ // If the PEAR class cannot be loaded via the autoloader, // then try to require_once it from the PHP include path. if (!class_exists('PEAR')) { require_once 'PEAR.php'; } define('ARCHIVE_TAR_ATT_SEPARATOR', 90001); define('ARCHIVE_TAR_END_BLOCK', pack("a512", '')); if (!function_exists('gzopen') && function_exists('gzopen64')) { function gzopen($filename, $mode, $use_include_path = 0) { return gzopen64($filename, $mode, $use_include_path); } } if (!function_exists('gztell') && function_exists('gztell64')) { function gztell($zp) { return gztell64($zp); } } if (!function_exists('gzseek') && function_exists('gzseek64')) { function gzseek($zp, $offset, $whence = SEEK_SET) { return gzseek64($zp, $offset, $whence); } } /** * Creates a (compressed) Tar archive * * @package Archive_Tar * @author Vincent Blavet <vincent@phpconcept.net> * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version $Revision$ */ class Archive_Tar extends PEAR { /** * @var string Name of the Tar */ public $_tarname = ''; /** * @var boolean if true, the Tar file will be gzipped */ public $_compress = false; /** * @var string Type of compression : 'none', 'gz', 'bz2' or 'lzma2' */ public $_compress_type = 'none'; /** * @var string Explode separator */ public $_separator = ' '; /** * @var file descriptor */ public $_file = 0; /** * @var string Local Tar name of a remote Tar (http:// or ftp://) */ public $_temp_tarname = ''; /** * @var string regular expression for ignoring files or directories */ public $_ignore_regexp = ''; /** * @var object PEAR_Error object */ public $error_object = null; /** * Format for data extraction * * @var string */ public $_fmt = ''; /** * @var int Length of the read buffer in bytes */ protected $buffer_length; /** * Archive_Tar Class constructor. This flavour of the constructor only * declare a new Archive_Tar object, identifying it by the name of the * tar file. * If the compress argument is set the tar will be read or created as a * gzip or bz2 compressed TAR file. * * @param string $p_tarname The name of the tar archive to create * @param string $p_compress can be null, 'gz', 'bz2' or 'lzma2'. This * parameter indicates if gzip, bz2 or lzma2 compression * is required. For compatibility reason the * boolean value 'true' means 'gz'. * @param int $buffer_length Length of the read buffer in bytes * * @return bool */ public function __construct($p_tarname, $p_compress = null, $buffer_length = 512) { parent::__construct(); $this->_compress = false; $this->_compress_type = 'none'; if (($p_compress === null) || ($p_compress == '')) { if (@file_exists($p_tarname)) { if ($fp = @fopen($p_tarname, "rb")) { // look for gzip magic cookie $data = fread($fp, 2); fclose($fp); if ($data == "\37\213") { $this->_compress = true; $this->_compress_type = 'gz'; // No sure it's enought for a magic code .... } elseif ($data == "BZ") { $this->_compress = true; $this->_compress_type = 'bz2'; } elseif (file_get_contents($p_tarname, false, null, 1, 4) == '7zXZ') { $this->_compress = true; $this->_compress_type = 'lzma2'; } } } else { // probably a remote file or some file accessible // through a stream interface if (substr($p_tarname, -2) == 'gz') { $this->_compress = true; $this->_compress_type = 'gz'; } elseif ((substr($p_tarname, -3) == 'bz2') || (substr($p_tarname, -2) == 'bz') ) { $this->_compress = true; $this->_compress_type = 'bz2'; } else { if (substr($p_tarname, -2) == 'xz') { $this->_compress = true; $this->_compress_type = 'lzma2'; } } } } else { if (($p_compress === true) || ($p_compress == 'gz')) { $this->_compress = true; $this->_compress_type = 'gz'; } else { if ($p_compress == 'bz2') { $this->_compress = true; $this->_compress_type = 'bz2'; } else { if ($p_compress == 'lzma2') { $this->_compress = true; $this->_compress_type = 'lzma2'; } else { $this->_error( "Unsupported compression type '$p_compress'\n" . "Supported types are 'gz', 'bz2' and 'lzma2'.\n" ); return false; } } } } $this->_tarname = $p_tarname; if ($this->_compress) { // assert zlib or bz2 or xz extension support if ($this->_compress_type == 'gz') { $extname = 'zlib'; } else { if ($this->_compress_type == 'bz2') { $extname = 'bz2'; } else { if ($this->_compress_type == 'lzma2') { $extname = 'xz'; } } } if (!extension_loaded($extname)) { PEAR::loadExtension($extname); } if (!extension_loaded($extname)) { $this->_error( "The extension '$extname' couldn't be found.\n" . "Please make sure your version of PHP was built " . "with '$extname' support.\n" ); return false; } } if (version_compare(PHP_VERSION, "5.5.0-dev") < 0) { $this->_fmt = "a100filename/a8mode/a8uid/a8gid/a12size/a12mtime/" . "a8checksum/a1typeflag/a100link/a6magic/a2version/" . "a32uname/a32gname/a8devmajor/a8devminor/a131prefix"; } else { $this->_fmt = "Z100filename/Z8mode/Z8uid/Z8gid/Z12size/Z12mtime/" . "Z8checksum/Z1typeflag/Z100link/Z6magic/Z2version/" . "Z32uname/Z32gname/Z8devmajor/Z8devminor/Z131prefix"; } $this->buffer_length = $buffer_length; } public function __destruct() { $this->_close(); // ----- Look for a local copy to delete if ($this->_temp_tarname != '' && (bool) preg_match('/^tar[[:alnum:]]*\.tmp$/', $this->_temp_tarname)) { @unlink($this->_temp_tarname); } } /** * This method creates the archive file and add the files / directories * that are listed in $p_filelist. * If a file with the same name exist and is writable, it is replaced * by the new tar. * The method return false and a PEAR error text. * The $p_filelist parameter can be an array of string, each string * representing a filename or a directory name with their path if * needed. It can also be a single string with names separated by a * single blank. * For each directory added in the archive, the files and * sub-directories are also added. * See also createModify() method for more details. * * @param array $p_filelist An array of filenames and directory names, or a * single string with names separated by a single * blank space. * * @return true on success, false on error. * @see createModify() */ public function create($p_filelist) { return $this->createModify($p_filelist, '', ''); } /** * This method add the files / directories that are listed in $p_filelist in * the archive. If the archive does not exist it is created. * The method return false and a PEAR error text. * The files and directories listed are only added at the end of the archive, * even if a file with the same name is already archived. * See also createModify() method for more details. * * @param array $p_filelist An array of filenames and directory names, or a * single string with names separated by a single * blank space. * * @return true on success, false on error. * @see createModify() * @access public */ public function add($p_filelist) { return $this->addModify($p_filelist, '', ''); } /** * @param string $p_path * @param bool $p_preserve * @param bool $p_symlinks * @return bool */ public function extract($p_path = '', $p_preserve = false, $p_symlinks = true) { return $this->extractModify($p_path, '', $p_preserve, $p_symlinks); } /** * @return array|int */ public function listContent() { $v_list_detail = array(); if ($this->_openRead()) { if (!$this->_extractList('', $v_list_detail, "list", '', '')) { unset($v_list_detail); $v_list_detail = 0; } $this->_close(); } return $v_list_detail; } /** * This method creates the archive file and add the files / directories * that are listed in $p_filelist. * If the file already exists and is writable, it is replaced by the * new tar. It is a create and not an add. If the file exists and is * read-only or is a directory it is not replaced. The method return * false and a PEAR error text. * The $p_filelist parameter can be an array of string, each string * representing a filename or a directory name with their path if * needed. It can also be a single string with names separated by a * single blank. * The path indicated in $p_remove_dir will be removed from the * memorized path of each file / directory listed when this path * exists. By default nothing is removed (empty path '') * The path indicated in $p_add_dir will be added at the beginning of * the memorized path of each file / directory listed. However it can * be set to empty ''. The adding of a path is done after the removing * of path. * The path add/remove ability enables the user to prepare an archive * for extraction in a different path than the origin files are. * See also addModify() method for file adding properties. * * @param array $p_filelist An array of filenames and directory names, * or a single string with names separated by * a single blank space. * @param string $p_add_dir A string which contains a path to be added * to the memorized path of each element in * the list. * @param string $p_remove_dir A string which contains a path to be * removed from the memorized path of each * element in the list, when relevant. * * @return boolean true on success, false on error. * @see addModify() */ public function createModify($p_filelist, $p_add_dir, $p_remove_dir = '') { $v_result = true; if (!$this->_openWrite()) { return false; } if ($p_filelist != '') { if (is_array($p_filelist)) { $v_list = $p_filelist; } elseif (is_string($p_filelist)) { $v_list = explode($this->_separator, $p_filelist); } else { $this->_cleanFile(); $this->_error('Invalid file list'); return false; } $v_result = $this->_addList($v_list, $p_add_dir, $p_remove_dir); } if ($v_result) { $this->_writeFooter(); $this->_close(); } else { $this->_cleanFile(); } return $v_result; } /** * This method add the files / directories listed in $p_filelist at the * end of the existing archive. If the archive does not yet exists it * is created. * The $p_filelist parameter can be an array of string, each string * representing a filename or a directory name with their path if * needed. It can also be a single string with names separated by a * single blank. * The path indicated in $p_remove_dir will be removed from the * memorized path of each file / directory listed when this path * exists. By default nothing is removed (empty path '') * The path indicated in $p_add_dir will be added at the beginning of * the memorized path of each file / directory listed. However it can * be set to empty ''. The adding of a path is done after the removing * of path. * The path add/remove ability enables the user to prepare an archive * for extraction in a different path than the origin files are. * If a file/dir is already in the archive it will only be added at the * end of the archive. There is no update of the existing archived * file/dir. However while extracting the archive, the last file will * replace the first one. This results in a none optimization of the * archive size. * If a file/dir does not exist the file/dir is ignored. However an * error text is send to PEAR error. * If a file/dir is not readable the file/dir is ignored. However an * error text is send to PEAR error. * * @param array $p_filelist An array of filenames and directory * names, or a single string with names * separated by a single blank space. * @param string $p_add_dir A string which contains a path to be * added to the memorized path of each * element in the list. * @param string $p_remove_dir A string which contains a path to be * removed from the memorized path of * each element in the list, when * relevant. * * @return true on success, false on error. */ public function addModify($p_filelist, $p_add_dir, $p_remove_dir = '') { $v_result = true; if (!$this->_isArchive()) { $v_result = $this->createModify( $p_filelist, $p_add_dir, $p_remove_dir ); } else { if (is_array($p_filelist)) { $v_list = $p_filelist; } elseif (is_string($p_filelist)) { $v_list = explode($this->_separator, $p_filelist); } else { $this->_error('Invalid file list'); return false; } $v_result = $this->_append($v_list, $p_add_dir, $p_remove_dir); } return $v_result; } /** * This method add a single string as a file at the * end of the existing archive. If the archive does not yet exists it * is created. * * @param string $p_filename A string which contains the full * filename path that will be associated * with the string. * @param string $p_string The content of the file added in * the archive. * @param bool|int $p_datetime A custom date/time (unix timestamp) * for the file (optional). * @param array $p_params An array of optional params: * stamp => the datetime (replaces * datetime above if it exists) * mode => the permissions on the * file (600 by default) * type => is this a link? See the * tar specification for details. * (default = regular file) * uid => the user ID of the file * (default = 0 = root) * gid => the group ID of the file * (default = 0 = root) * * @return true on success, false on error. */ public function addString($p_filename, $p_string, $p_datetime = false, $p_params = array()) { $p_stamp = @$p_params["stamp"] ? $p_params["stamp"] : ($p_datetime ? $p_datetime : time()); $p_mode = @$p_params["mode"] ? $p_params["mode"] : 0600; $p_type = @$p_params["type"] ? $p_params["type"] : ""; $p_uid = @$p_params["uid"] ? $p_params["uid"] : ""; $p_gid = @$p_params["gid"] ? $p_params["gid"] : ""; $v_result = true; if (!$this->_isArchive()) { if (!$this->_openWrite()) { return false; } $this->_close(); } if (!$this->_openAppend()) { return false; } // Need to check the get back to the temporary file ? .... $v_result = $this->_addString($p_filename, $p_string, $p_datetime, $p_params); $this->_writeFooter(); $this->_close(); return $v_result; } /** * This method extract all the content of the archive in the directory * indicated by $p_path. When relevant the memorized path of the * files/dir can be modified by removing the $p_remove_path path at the * beginning of the file/dir path. * While extracting a file, if the directory path does not exists it is * created. * While extracting a file, if the file already exists it is replaced * without looking for last modification date. * While extracting a file, if the file already exists and is write * protected, the extraction is aborted. * While extracting a file, if a directory with the same name already * exists, the extraction is aborted. * While extracting a directory, if a file with the same name already * exists, the extraction is aborted. * While extracting a file/directory if the destination directory exist * and is write protected, or does not exist but can not be created, * the extraction is aborted. * If after extraction an extracted file does not show the correct * stored file size, the extraction is aborted. * When the extraction is aborted, a PEAR error text is set and false * is returned. However the result can be a partial extraction that may * need to be manually cleaned. * * @param string $p_path The path of the directory where the * files/dir need to by extracted. * @param string $p_remove_path Part of the memorized path that can be * removed if present at the beginning of * the file/dir path. * @param boolean $p_preserve Preserve user/group ownership of files * @param boolean $p_symlinks Allow symlinks. * * @return boolean true on success, false on error. * @see extractList() */ public function extractModify($p_path, $p_remove_path, $p_preserve = false, $p_symlinks = true) { $v_result = true; $v_list_detail = array(); if ($v_result = $this->_openRead()) { $v_result = $this->_extractList( $p_path, $v_list_detail, "complete", 0, $p_remove_path, $p_preserve, $p_symlinks ); $this->_close(); } return $v_result; } /** * This method extract from the archive one file identified by $p_filename. * The return value is a string with the file content, or NULL on error. * * @param string $p_filename The path of the file to extract in a string. * * @return a string with the file content or NULL. */ public function extractInString($p_filename) { if ($this->_openRead()) { $v_result = $this->_extractInString($p_filename); $this->_close(); } else { $v_result = null; } return $v_result; } /** * This method extract from the archive only the files indicated in the * $p_filelist. These files are extracted in the current directory or * in the directory indicated by the optional $p_path parameter. * If indicated the $p_remove_path can be used in the same way as it is * used in extractModify() method. * * @param array $p_filelist An array of filenames and directory names, * or a single string with names separated * by a single blank space. * @param string $p_path The path of the directory where the * files/dir need to by extracted. * @param string $p_remove_path Part of the memorized path that can be * removed if present at the beginning of * the file/dir path. * @param boolean $p_preserve Preserve user/group ownership of files * @param boolean $p_symlinks Allow symlinks. * * @return true on success, false on error. * @see extractModify() */ public function extractList($p_filelist, $p_path = '', $p_remove_path = '', $p_preserve = false, $p_symlinks = true) { $v_result = true; $v_list_detail = array(); if (is_array($p_filelist)) { $v_list = $p_filelist; } elseif (is_string($p_filelist)) { $v_list = explode($this->_separator, $p_filelist); } else { $this->_error('Invalid string list'); return false; } if ($v_result = $this->_openRead()) { $v_result = $this->_extractList( $p_path, $v_list_detail, "partial", $v_list, $p_remove_path, $p_preserve, $p_symlinks ); $this->_close(); } return $v_result; } /** * This method set specific attributes of the archive. It uses a variable * list of parameters, in the format attribute code + attribute values : * $arch->setAttribute(ARCHIVE_TAR_ATT_SEPARATOR, ','); * * @return true on success, false on error. */ public function setAttribute() { $v_result = true; // ----- Get the number of variable list of arguments if (($v_size = func_num_args()) == 0) { return true; } // ----- Get the arguments $v_att_list = func_get_args(); // ----- Read the attributes $i = 0; while ($i < $v_size) { // ----- Look for next option switch ($v_att_list[$i]) { // ----- Look for options that request a string value case ARCHIVE_TAR_ATT_SEPARATOR : // ----- Check the number of parameters if (($i + 1) >= $v_size) { $this->_error( 'Invalid number of parameters for ' . 'attribute ARCHIVE_TAR_ATT_SEPARATOR' ); return false; } // ----- Get the value $this->_separator = $v_att_list[$i + 1]; $i++; break; default : $this->_error('Unknown attribute code ' . $v_att_list[$i] . ''); return false; } // ----- Next attribute $i++; } return $v_result; } /** * This method sets the regular expression for ignoring files and directories * at import, for example: * $arch->setIgnoreRegexp("#CVS|\.svn#"); * * @param string $regexp regular expression defining which files or directories to ignore */ public function setIgnoreRegexp($regexp) { $this->_ignore_regexp = $regexp; } /** * This method sets the regular expression for ignoring all files and directories * matching the filenames in the array list at import, for example: * $arch->setIgnoreList(array('CVS', '.svn', 'bin/tool')); * * @param array $list a list of file or directory names to ignore * * @access public */ public function setIgnoreList($list) { $list = str_replace(array('#', '.', '^', '$'), array('\#', '\.', '\^', '\$'), $list); $regexp = '#/' . join('$|/', $list) . '#'; $this->setIgnoreRegexp($regexp); } /** * @param string $p_message */ public function _error($p_message) { $this->error_object = $this->raiseError($p_message); } /** * @param string $p_message */ public function _warning($p_message) { $this->error_object = $this->raiseError($p_message); } /** * @param string $p_filename * @return bool */ public function _isArchive($p_filename = null) { if ($p_filename == null) { $p_filename = $this->_tarname; } clearstatcache(); return @is_file($p_filename) && !@is_link($p_filename); } /** * @return bool */ public function _openWrite() { if ($this->_compress_type == 'gz' && function_exists('gzopen')) { $this->_file = @gzopen($this->_tarname, "wb9"); } else { if ($this->_compress_type == 'bz2' && function_exists('bzopen')) { $this->_file = @bzopen($this->_tarname, "w"); } else { if ($this->_compress_type == 'lzma2' && function_exists('xzopen')) { $this->_file = @xzopen($this->_tarname, 'w'); } else { if ($this->_compress_type == 'none') { $this->_file = @fopen($this->_tarname, "wb"); } else { $this->_error( 'Unknown or missing compression type (' . $this->_compress_type . ')' ); return false; } } } } if ($this->_file == 0) { $this->_error( 'Unable to open in write mode \'' . $this->_tarname . '\'' ); return false; } return true; } /** * @return bool */ public function _openRead() { if (strtolower(substr($this->_tarname, 0, 7)) == 'http://') { // ----- Look if a local copy need to be done if ($this->_temp_tarname == '') { $this->_temp_tarname = uniqid('tar') . '.tmp'; if (!$v_file_from = @fopen($this->_tarname, 'rb')) { $this->_error( 'Unable to open in read mode \'' . $this->_tarname . '\'' ); $this->_temp_tarname = ''; return false; } if (!$v_file_to = @fopen($this->_temp_tarname, 'wb')) { $this->_error( 'Unable to open in write mode \'' . $this->_temp_tarname . '\'' ); $this->_temp_tarname = ''; return false; } while ($v_data = @fread($v_file_from, 1024)) { @fwrite($v_file_to, $v_data); } @fclose($v_file_from); @fclose($v_file_to); } // ----- File to open if the local copy $v_filename = $this->_temp_tarname; } else { // ----- File to open if the normal Tar file $v_filename = $this->_tarname; } if ($this->_compress_type == 'gz' && function_exists('gzopen')) { $this->_file = @gzopen($v_filename, "rb"); } else { if ($this->_compress_type == 'bz2' && function_exists('bzopen')) { $this->_file = @bzopen($v_filename, "r"); } else { if ($this->_compress_type == 'lzma2' && function_exists('xzopen')) { $this->_file = @xzopen($v_filename, "r"); } else { if ($this->_compress_type == 'none') { $this->_file = @fopen($v_filename, "rb"); } else { $this->_error( 'Unknown or missing compression type (' . $this->_compress_type . ')' ); return false; } } } } if ($this->_file == 0) { $this->_error('Unable to open in read mode \'' . $v_filename . '\''); return false; } return true; } /** * @return bool */ public function _openReadWrite() { if ($this->_compress_type == 'gz') { $this->_file = @gzopen($this->_tarname, "r+b"); } else { if ($this->_compress_type == 'bz2') { $this->_error( 'Unable to open bz2 in read/write mode \'' . $this->_tarname . '\' (limitation of bz2 extension)' ); return false; } else { if ($this->_compress_type == 'lzma2') { $this->_error( 'Unable to open lzma2 in read/write mode \'' . $this->_tarname . '\' (limitation of lzma2 extension)' ); return false; } else { if ($this->_compress_type == 'none') { $this->_file = @fopen($this->_tarname, "r+b"); } else { $this->_error( 'Unknown or missing compression type (' . $this->_compress_type . ')' ); return false; } } } } if ($this->_file == 0) { $this->_error( 'Unable to open in read/write mode \'' . $this->_tarname . '\'' ); return false; } return true; } /** * @return bool */ public function _close() { //if (isset($this->_file)) { if (is_resource($this->_file)) { if ($this->_compress_type == 'gz') { @gzclose($this->_file); } else { if ($this->_compress_type == 'bz2') { @bzclose($this->_file); } else { if ($this->_compress_type == 'lzma2') { @xzclose($this->_file); } else { if ($this->_compress_type == 'none') { @fclose($this->_file); } else { $this->_error( 'Unknown or missing compression type (' . $this->_compress_type . ')' ); } } } } $this->_file = 0; } // ----- Look if a local copy need to be erase // Note that it might be interesting to keep the url for a time : ToDo if ($this->_temp_tarname != '') { @unlink($this->_temp_tarname); $this->_temp_tarname = ''; } return true; } /** * @return bool */ public function _cleanFile() { $this->_close(); // ----- Look for a local copy if ($this->_temp_tarname != '') { // ----- Remove the local copy but not the remote tarname @unlink($this->_temp_tarname); $this->_temp_tarname = ''; } else { // ----- Remove the local tarname file @unlink($this->_tarname); } $this->_tarname = ''; return true; } /** * @param mixed $p_binary_data * @param integer $p_len * @return bool */ public function _writeBlock($p_binary_data, $p_len = null) { if (is_resource($this->_file)) { if ($p_len === null) { if ($this->_compress_type == 'gz') { @gzputs($this->_file, $p_binary_data); } else { if ($this->_compress_type == 'bz2') { @bzwrite($this->_file, $p_binary_data); } else { if ($this->_compress_type == 'lzma2') { @xzwrite($this->_file, $p_binary_data); } else { if ($this->_compress_type == 'none') { @fputs($this->_file, $p_binary_data); } else { $this->_error( 'Unknown or missing compression type (' . $this->_compress_type . ')' ); } } } } } else { if ($this->_compress_type == 'gz') { @gzputs($this->_file, $p_binary_data, $p_len); } else { if ($this->_compress_type == 'bz2') { @bzwrite($this->_file, $p_binary_data, $p_len); } else { if ($this->_compress_type == 'lzma2') { @xzwrite($this->_file, $p_binary_data, $p_len); } else { if ($this->_compress_type == 'none') { @fputs($this->_file, $p_binary_data, $p_len); } else { $this->_error( 'Unknown or missing compression type (' . $this->_compress_type . ')' ); } } } } } } return true; } /** * @return null|string */ public function _readBlock() { $v_block = null; if (is_resource($this->_file)) { if ($this->_compress_type == 'gz') { $v_block = @gzread($this->_file, 512); } else { if ($this->_compress_type == 'bz2') { $v_block = @bzread($this->_file, 512); } else { if ($this->_compress_type == 'lzma2') { $v_block = @xzread($this->_file, 512); } else { if ($this->_compress_type == 'none') { $v_block = @fread($this->_file, 512); } else { $this->_error( 'Unknown or missing compression type (' . $this->_compress_type . ')' ); } } } } } return $v_block; } /** * @param null $p_len * @return bool */ public function _jumpBlock($p_len = null) { if (is_resource($this->_file)) { if ($p_len === null) { $p_len = 1; } if ($this->_compress_type == 'gz') { @gzseek($this->_file, gztell($this->_file) + ($p_len * 512)); } else { if ($this->_compress_type == 'bz2') { // ----- Replace missing bztell() and bzseek() for ($i = 0; $i < $p_len; $i++) { $this->_readBlock(); } } else { if ($this->_compress_type == 'lzma2') { // ----- Replace missing xztell() and xzseek() for ($i = 0; $i < $p_len; $i++) { $this->_readBlock(); } } else { if ($this->_compress_type == 'none') { @fseek($this->_file, $p_len * 512, SEEK_CUR); } else { $this->_error( 'Unknown or missing compression type (' . $this->_compress_type . ')' ); } } } } } return true; } /** * @return bool */ public function _writeFooter() { if (is_resource($this->_file)) { // ----- Write the last 0 filled block for end of archive $v_binary_data = pack('a1024', ''); $this->_writeBlock($v_binary_data); } return true; } /** * @param array $p_list * @param string $p_add_dir * @param string $p_remove_dir * @return bool */ public function _addList($p_list, $p_add_dir, $p_remove_dir) { $v_result = true; $v_header = array(); // ----- Remove potential windows directory separator $p_add_dir = $this->_translateWinPath($p_add_dir); $p_remove_dir = $this->_translateWinPath($p_remove_dir, false); if (!$this->_file) { $this->_error('Invalid file descriptor'); return false; } if (sizeof($p_list) == 0) { return true; } foreach ($p_list as $v_filename) { if (!$v_result) { break; } // ----- Skip the current tar name if ($v_filename == $this->_tarname) { continue; } if ($v_filename == '') { continue; } // ----- ignore files and directories matching the ignore regular expression if ($this->_ignore_regexp && preg_match($this->_ignore_regexp, '/' . $v_filename)) { $this->_warning("File '$v_filename' ignored"); continue; } if (!file_exists($v_filename) && !is_link($v_filename)) { $this->_warning("File '$v_filename' does not exist"); continue; } // ----- Add the file or directory header if (!$this->_addFile($v_filename, $v_header, $p_add_dir, $p_remove_dir)) { return false; } if (@is_dir($v_filename) && !@is_link($v_filename)) { if (!($p_hdir = opendir($v_filename))) { $this->_warning("Directory '$v_filename' can not be read"); continue; } while (false !== ($p_hitem = readdir($p_hdir))) { if (($p_hitem != '.') && ($p_hitem != '..')) { if ($v_filename != ".") { $p_temp_list[0] = $v_filename . '/' . $p_hitem; } else { $p_temp_list[0] = $p_hitem; } $v_result = $this->_addList( $p_temp_list, $p_add_dir, $p_remove_dir ); } } unset($p_temp_list); unset($p_hdir); unset($p_hitem); } } return $v_result; } /** * @param string $p_filename * @param mixed $p_header * @param string $p_add_dir * @param string $p_remove_dir * @param null $v_stored_filename * @return bool */ public function _addFile($p_filename, &$p_header, $p_add_dir, $p_remove_dir, $v_stored_filename = null) { if (!$this->_file) { $this->_error('Invalid file descriptor'); return false; } if ($p_filename == '') { $this->_error('Invalid file name'); return false; } if (is_null($v_stored_filename)) { // ----- Calculate the stored filename $p_filename = $this->_translateWinPath($p_filename, false); $v_stored_filename = $p_filename; if (strcmp($p_filename, $p_remove_dir) == 0) { return true; } if ($p_remove_dir != '') { if (substr($p_remove_dir, -1) != '/') { $p_remove_dir .= '/'; } if (substr($p_filename, 0, strlen($p_remove_dir)) == $p_remove_dir) { $v_stored_filename = substr($p_filename, strlen($p_remove_dir)); } } $v_stored_filename = $this->_translateWinPath($v_stored_filename); if ($p_add_dir != '') { if (substr($p_add_dir, -1) == '/') { $v_stored_filename = $p_add_dir . $v_stored_filename; } else { $v_stored_filename = $p_add_dir . '/' . $v_stored_filename; } } $v_stored_filename = $this->_pathReduction($v_stored_filename); } if ($this->_isArchive($p_filename)) { if (($v_file = @fopen($p_filename, "rb")) == 0) { $this->_warning( "Unable to open file '" . $p_filename . "' in binary read mode" ); return true; } if (!$this->_writeHeader($p_filename, $v_stored_filename)) { return false; } while (($v_buffer = fread($v_file, $this->buffer_length)) != '') { $buffer_length = strlen("$v_buffer"); if ($buffer_length != $this->buffer_length) { $pack_size = ((int)($buffer_length / 512) + ($buffer_length % 512 !== 0 ? 1 : 0)) * 512; $pack_format = sprintf('a%d', $pack_size); } else { $pack_format = sprintf('a%d', $this->buffer_length); } $v_binary_data = pack($pack_format, "$v_buffer"); $this->_writeBlock($v_binary_data); } fclose($v_file); } else { // ----- Only header for dir if (!$this->_writeHeader($p_filename, $v_stored_filename)) { return false; } } return true; } /** * @param string $p_filename * @param string $p_string * @param bool $p_datetime * @param array $p_params * @return bool */ public function _addString($p_filename, $p_string, $p_datetime = false, $p_params = array()) { $p_stamp = @$p_params["stamp"] ? $p_params["stamp"] : ($p_datetime ? $p_datetime : time()); $p_mode = @$p_params["mode"] ? $p_params["mode"] : 0600; $p_type = @$p_params["type"] ? $p_params["type"] : ""; $p_uid = @$p_params["uid"] ? $p_params["uid"] : 0; $p_gid = @$p_params["gid"] ? $p_params["gid"] : 0; if (!$this->_file) { $this->_error('Invalid file descriptor'); return false; } if ($p_filename == '') { $this->_error('Invalid file name'); return false; } // ----- Calculate the stored filename $p_filename = $this->_translateWinPath($p_filename, false); // ----- If datetime is not specified, set current time if ($p_datetime === false) { $p_datetime = time(); } if (!$this->_writeHeaderBlock( $p_filename, strlen($p_string), $p_stamp, $p_mode, $p_type, $p_uid, $p_gid ) ) { return false; } $i = 0; while (($v_buffer = substr($p_string, (($i++) * 512), 512)) != '') { $v_binary_data = pack("a512", $v_buffer); $this->_writeBlock($v_binary_data); } return true; } /** * @param string $p_filename * @param string $p_stored_filename * @return bool */ public function _writeHeader($p_filename, $p_stored_filename) { if ($p_stored_filename == '') { $p_stored_filename = $p_filename; } $v_reduced_filename = $this->_pathReduction($p_stored_filename); if (strlen($v_reduced_filename) > 99) { if (!$this->_writeLongHeader($v_reduced_filename, false)) { return false; } } $v_linkname = ''; if (@is_link($p_filename)) { $v_linkname = readlink($p_filename); } if (strlen($v_linkname) > 99) { if (!$this->_writeLongHeader($v_linkname, true)) { return false; } } $v_info = lstat($p_filename); $v_uid = sprintf("%07s", DecOct($v_info[4])); $v_gid = sprintf("%07s", DecOct($v_info[5])); $v_perms = sprintf("%07s", DecOct($v_info['mode'] & 000777)); $v_mtime = sprintf("%011s", DecOct($v_info['mtime'])); if (@is_link($p_filename)) { $v_typeflag = '2'; $v_size = sprintf("%011s", DecOct(0)); } elseif (@is_dir($p_filename)) { $v_typeflag = "5"; $v_size = sprintf("%011s", DecOct(0)); } else { $v_typeflag = '0'; clearstatcache(); $v_size = sprintf("%011s", DecOct($v_info['size'])); } $v_magic = 'ustar '; $v_version = ' '; $v_uname = ''; $v_gname = ''; if (function_exists('posix_getpwuid')) { $userinfo = posix_getpwuid($v_info[4]); $groupinfo = posix_getgrgid($v_info[5]); if (isset($userinfo['name'])) { $v_uname = $userinfo['name']; } if (isset($groupinfo['name'])) { $v_gname = $groupinfo['name']; } } $v_devmajor = ''; $v_devminor = ''; $v_prefix = ''; $v_binary_data_first = pack( "a100a8a8a8a12a12", $v_reduced_filename, $v_perms, $v_uid, $v_gid, $v_size, $v_mtime ); $v_binary_data_last = pack( "a1a100a6a2a32a32a8a8a155a12", $v_typeflag, $v_linkname, $v_magic, $v_version, $v_uname, $v_gname, $v_devmajor, $v_devminor, $v_prefix, '' ); // ----- Calculate the checksum $v_checksum = 0; // ..... First part of the header for ($i = 0; $i < 148; $i++) { $v_checksum += ord(substr($v_binary_data_first, $i, 1)); } // ..... Ignore the checksum value and replace it by ' ' (space) for ($i = 148; $i < 156; $i++) { $v_checksum += ord(' '); } // ..... Last part of the header for ($i = 156, $j = 0; $i < 512; $i++, $j++) { $v_checksum += ord(substr($v_binary_data_last, $j, 1)); } // ----- Write the first 148 bytes of the header in the archive $this->_writeBlock($v_binary_data_first, 148); // ----- Write the calculated checksum $v_checksum = sprintf("%06s\0 ", DecOct($v_checksum)); $v_binary_data = pack("a8", $v_checksum); $this->_writeBlock($v_binary_data, 8); // ----- Write the last 356 bytes of the header in the archive $this->_writeBlock($v_binary_data_last, 356); return true; } /** * @param string $p_filename * @param int $p_size * @param int $p_mtime * @param int $p_perms * @param string $p_type * @param int $p_uid * @param int $p_gid * @return bool */ public function _writeHeaderBlock( $p_filename, $p_size, $p_mtime = 0, $p_perms = 0, $p_type = '', $p_uid = 0, $p_gid = 0 ) { $p_filename = $this->_pathReduction($p_filename); if (strlen($p_filename) > 99) { if (!$this->_writeLongHeader($p_filename, false)) { return false; } } if ($p_type == "5") { $v_size = sprintf("%011s", DecOct(0)); } else { $v_size = sprintf("%011s", DecOct($p_size)); } $v_uid = sprintf("%07s", DecOct($p_uid)); $v_gid = sprintf("%07s", DecOct($p_gid)); $v_perms = sprintf("%07s", DecOct($p_perms & 000777)); $v_mtime = sprintf("%11s", DecOct($p_mtime)); $v_linkname = ''; $v_magic = 'ustar '; $v_version = ' '; if (function_exists('posix_getpwuid')) { $userinfo = posix_getpwuid($p_uid); $groupinfo = posix_getgrgid($p_gid); if ($userinfo === false || $groupinfo === false) { $v_uname = ''; $v_gname = ''; } else { $v_uname = $userinfo['name']; $v_gname = $groupinfo['name']; } } else { $v_uname = ''; $v_gname = ''; } $v_devmajor = ''; $v_devminor = ''; $v_prefix = ''; $v_binary_data_first = pack( "a100a8a8a8a12A12", $p_filename, $v_perms, $v_uid, $v_gid, $v_size, $v_mtime ); $v_binary_data_last = pack( "a1a100a6a2a32a32a8a8a155a12", $p_type, $v_linkname, $v_magic, $v_version, $v_uname, $v_gname, $v_devmajor, $v_devminor, $v_prefix, '' ); // ----- Calculate the checksum $v_checksum = 0; // ..... First part of the header for ($i = 0; $i < 148; $i++) { $v_checksum += ord(substr($v_binary_data_first, $i, 1)); } // ..... Ignore the checksum value and replace it by ' ' (space) for ($i = 148; $i < 156; $i++) { $v_checksum += ord(' '); } // ..... Last part of the header for ($i = 156, $j = 0; $i < 512; $i++, $j++) { $v_checksum += ord(substr($v_binary_data_last, $j, 1)); } // ----- Write the first 148 bytes of the header in the archive $this->_writeBlock($v_binary_data_first, 148); // ----- Write the calculated checksum $v_checksum = sprintf("%06s ", DecOct($v_checksum)); $v_binary_data = pack("a8", $v_checksum); $this->_writeBlock($v_binary_data, 8); // ----- Write the last 356 bytes of the header in the archive $this->_writeBlock($v_binary_data_last, 356); return true; } /** * @param string $p_filename * @return bool */ public function _writeLongHeader($p_filename, $is_link = false) { $v_uid = sprintf("%07s", 0); $v_gid = sprintf("%07s", 0); $v_perms = sprintf("%07s", 0); $v_size = sprintf("%'011s", DecOct(strlen($p_filename))); $v_mtime = sprintf("%011s", 0); $v_typeflag = ($is_link ? 'K' : 'L'); $v_linkname = ''; $v_magic = 'ustar '; $v_version = ' '; $v_uname = ''; $v_gname = ''; $v_devmajor = ''; $v_devminor = ''; $v_prefix = ''; $v_binary_data_first = pack( "a100a8a8a8a12a12", '././@LongLink', $v_perms, $v_uid, $v_gid, $v_size, $v_mtime ); $v_binary_data_last = pack( "a1a100a6a2a32a32a8a8a155a12", $v_typeflag, $v_linkname, $v_magic, $v_version, $v_uname, $v_gname, $v_devmajor, $v_devminor, $v_prefix, '' ); // ----- Calculate the checksum $v_checksum = 0; // ..... First part of the header for ($i = 0; $i < 148; $i++) { $v_checksum += ord(substr($v_binary_data_first, $i, 1)); } // ..... Ignore the checksum value and replace it by ' ' (space) for ($i = 148; $i < 156; $i++) { $v_checksum += ord(' '); } // ..... Last part of the header for ($i = 156, $j = 0; $i < 512; $i++, $j++) { $v_checksum += ord(substr($v_binary_data_last, $j, 1)); } // ----- Write the first 148 bytes of the header in the archive $this->_writeBlock($v_binary_data_first, 148); // ----- Write the calculated checksum $v_checksum = sprintf("%06s\0 ", DecOct($v_checksum)); $v_binary_data = pack("a8", $v_checksum); $this->_writeBlock($v_binary_data, 8); // ----- Write the last 356 bytes of the header in the archive $this->_writeBlock($v_binary_data_last, 356); // ----- Write the filename as content of the block $i = 0; while (($v_buffer = substr($p_filename, (($i++) * 512), 512)) != '') { $v_binary_data = pack("a512", "$v_buffer"); $this->_writeBlock($v_binary_data); } return true; } /** * @param mixed $v_binary_data * @param mixed $v_header * @return bool */ public function _readHeader($v_binary_data, &$v_header) { if (strlen($v_binary_data) == 0) { $v_header['filename'] = ''; return true; } if (strlen($v_binary_data) != 512) { $v_header['filename'] = ''; $this->_error('Invalid block size : ' . strlen($v_binary_data)); return false; } if (!is_array($v_header)) { $v_header = array(); } // ----- Calculate the checksum $v_checksum = 0; // ..... First part of the header $v_binary_split = str_split($v_binary_data); $v_checksum += array_sum(array_map('ord', array_slice($v_binary_split, 0, 148))); $v_checksum += array_sum(array_map('ord', array(' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',))); $v_checksum += array_sum(array_map('ord', array_slice($v_binary_split, 156, 512))); $v_data = unpack($this->_fmt, $v_binary_data); if (strlen($v_data["prefix"]) > 0) { $v_data["filename"] = "$v_data[prefix]/$v_data[filename]"; } // ----- Extract the checksum $v_data_checksum = trim($v_data['checksum']); if (!preg_match('/^[0-7]*$/', $v_data_checksum)) { $this->_error( 'Invalid checksum for file "' . $v_data['filename'] . '" : ' . $v_data_checksum . ' extracted' ); return false; } $v_header['checksum'] = OctDec($v_data_checksum); if ($v_header['checksum'] != $v_checksum) { $v_header['filename'] = ''; // ----- Look for last block (empty block) if (($v_checksum == 256) && ($v_header['checksum'] == 0)) { return true; } $this->_error( 'Invalid checksum for file "' . $v_data['filename'] . '" : ' . $v_checksum . ' calculated, ' . $v_header['checksum'] . ' expected' ); return false; } // ----- Extract the properties $v_header['filename'] = rtrim($v_data['filename'], "\0"); if ($this->_isMaliciousFilename($v_header['filename'])) { $this->_error( 'Malicious .tar detected, file "' . $v_header['filename'] . '" will not install in desired directory tree' ); return false; } $v_header['mode'] = OctDec(trim($v_data['mode'])); $v_header['uid'] = OctDec(trim($v_data['uid'])); $v_header['gid'] = OctDec(trim($v_data['gid'])); $v_header['size'] = $this->_tarRecToSize($v_data['size']); $v_header['mtime'] = OctDec(trim($v_data['mtime'])); if (($v_header['typeflag'] = $v_data['typeflag']) == "5") { $v_header['size'] = 0; } $v_header['link'] = trim($v_data['link']); /* ----- All these fields are removed form the header because they do not carry interesting info $v_header[magic] = trim($v_data[magic]); $v_header[version] = trim($v_data[version]); $v_header[uname] = trim($v_data[uname]); $v_header[gname] = trim($v_data[gname]); $v_header[devmajor] = trim($v_data[devmajor]); $v_header[devminor] = trim($v_data[devminor]); */ return true; } /** * Convert Tar record size to actual size * * @param string $tar_size * @return size of tar record in bytes */ private function _tarRecToSize($tar_size) { /* * First byte of size has a special meaning if bit 7 is set. * * Bit 7 indicates base-256 encoding if set. * Bit 6 is the sign bit. * Bits 5:0 are most significant value bits. */ $ch = ord($tar_size[0]); if ($ch & 0x80) { // Full 12-bytes record is required. $rec_str = $tar_size . "\x00"; $size = ($ch & 0x40) ? -1 : 0; $size = ($size << 6) | ($ch & 0x3f); for ($num_ch = 1; $num_ch < 12; ++$num_ch) { $size = ($size * 256) + ord($rec_str[$num_ch]); } return $size; } else { return OctDec(trim($tar_size)); } } /** * Detect and report a malicious file name * * @param string $file * * @return bool */ private function _isMaliciousFilename($file) { if (strpos($file, '://') !== false) { return true; } if (strpos($file, '../') !== false || strpos($file, '..\\') !== false) { return true; } return false; } /** * @param $v_header * @return bool */ public function _readLongHeader(&$v_header) { $v_filename = ''; $v_filesize = $v_header['size']; $n = floor($v_header['size'] / 512); for ($i = 0; $i < $n; $i++) { $v_content = $this->_readBlock(); $v_filename .= $v_content; } if (($v_header['size'] % 512) != 0) { $v_content = $this->_readBlock(); $v_filename .= $v_content; } // ----- Read the next header $v_binary_data = $this->_readBlock(); if (!$this->_readHeader($v_binary_data, $v_header)) { return false; } $v_filename = rtrim(substr($v_filename, 0, $v_filesize), "\0"); $v_header['filename'] = $v_filename; if ($this->_isMaliciousFilename($v_filename)) { $this->_error( 'Malicious .tar detected, file "' . $v_filename . '" will not install in desired directory tree' ); return false; } return true; } /** * This method extract from the archive one file identified by $p_filename. * The return value is a string with the file content, or null on error. * * @param string $p_filename The path of the file to extract in a string. * * @return a string with the file content or null. */ private function _extractInString($p_filename) { $v_result_str = ""; while (strlen($v_binary_data = $this->_readBlock()) != 0) { if (!$this->_readHeader($v_binary_data, $v_header)) { return null; } if ($v_header['filename'] == '') { continue; } switch ($v_header['typeflag']) { case 'L': { if (!$this->_readLongHeader($v_header)) { return null; } } break; case 'K': { $v_link_header = $v_header; if (!$this->_readLongHeader($v_link_header)) { return null; } $v_header['link'] = $v_link_header['filename']; } break; } if ($v_header['filename'] == $p_filename) { if ($v_header['typeflag'] == "5") { $this->_error( 'Unable to extract in string a directory ' . 'entry {' . $v_header['filename'] . '}' ); return null; } else { $n = floor($v_header['size'] / 512); for ($i = 0; $i < $n; $i++) { $v_result_str .= $this->_readBlock(); } if (($v_header['size'] % 512) != 0) { $v_content = $this->_readBlock(); $v_result_str .= substr( $v_content, 0, ($v_header['size'] % 512) ); } return $v_result_str; } } else { $this->_jumpBlock(ceil(($v_header['size'] / 512))); } } return null; } /** * @param string $p_path * @param string $p_list_detail * @param string $p_mode * @param string $p_file_list * @param string $p_remove_path * @param bool $p_preserve * @param bool $p_symlinks * @return bool */ public function _extractList( $p_path, &$p_list_detail, $p_mode, $p_file_list, $p_remove_path, $p_preserve = false, $p_symlinks = true ) { $v_result = true; $v_nb = 0; $v_extract_all = true; $v_listing = false; $p_path = $this->_translateWinPath($p_path, false); if ($p_path == '' || (substr($p_path, 0, 1) != '/' && substr($p_path, 0, 3) != "../" && !strpos($p_path, ':')) ) { $p_path = "./" . $p_path; } $p_remove_path = $this->_translateWinPath($p_remove_path); // ----- Look for path to remove format (should end by /) if (($p_remove_path != '') && (substr($p_remove_path, -1) != '/')) { $p_remove_path .= '/'; } $p_remove_path_size = strlen($p_remove_path); switch ($p_mode) { case "complete" : $v_extract_all = true; $v_listing = false; break; case "partial" : $v_extract_all = false; $v_listing = false; break; case "list" : $v_extract_all = false; $v_listing = true; break; default : $this->_error('Invalid extract mode (' . $p_mode . ')'); return false; } clearstatcache(); while (strlen($v_binary_data = $this->_readBlock()) != 0) { $v_extract_file = false; $v_extraction_stopped = 0; if (!$this->_readHeader($v_binary_data, $v_header)) { return false; } if ($v_header['filename'] == '') { continue; } switch ($v_header['typeflag']) { case 'L': { if (!$this->_readLongHeader($v_header)) { return null; } } break; case 'K': { $v_link_header = $v_header; if (!$this->_readLongHeader($v_link_header)) { return null; } $v_header['link'] = $v_link_header['filename']; } break; } // ignore extended / pax headers if ($v_header['typeflag'] == 'x' || $v_header['typeflag'] == 'g') { $this->_jumpBlock(ceil(($v_header['size'] / 512))); continue; } if ((!$v_extract_all) && (is_array($p_file_list))) { // ----- By default no unzip if the file is not found $v_extract_file = false; for ($i = 0; $i < sizeof($p_file_list); $i++) { // ----- Look if it is a directory if (substr($p_file_list[$i], -1) == '/') { // ----- Look if the directory is in the filename path if ((strlen($v_header['filename']) > strlen($p_file_list[$i])) && (substr($v_header['filename'], 0, strlen($p_file_list[$i])) == $p_file_list[$i]) ) { $v_extract_file = true; break; } } // ----- It is a file, so compare the file names elseif ($p_file_list[$i] == $v_header['filename']) { $v_extract_file = true; break; } } } else { $v_extract_file = true; } // ----- Look if this file need to be extracted if (($v_extract_file) && (!$v_listing)) { if (($p_remove_path != '') && (substr($v_header['filename'] . '/', 0, $p_remove_path_size) == $p_remove_path) ) { $v_header['filename'] = substr( $v_header['filename'], $p_remove_path_size ); if ($v_header['filename'] == '') { continue; } } if (($p_path != './') && ($p_path != '/')) { while (substr($p_path, -1) == '/') { $p_path = substr($p_path, 0, strlen($p_path) - 1); } if (substr($v_header['filename'], 0, 1) == '/') { $v_header['filename'] = $p_path . $v_header['filename']; } else { $v_header['filename'] = $p_path . '/' . $v_header['filename']; } } if (file_exists($v_header['filename'])) { if ((@is_dir($v_header['filename'])) && ($v_header['typeflag'] == '') ) { $this->_error( 'File ' . $v_header['filename'] . ' already exists as a directory' ); return false; } if (($this->_isArchive($v_header['filename'])) && ($v_header['typeflag'] == "5") ) { $this->_error( 'Directory ' . $v_header['filename'] . ' already exists as a file' ); return false; } if (!is_writeable($v_header['filename'])) { $this->_error( 'File ' . $v_header['filename'] . ' already exists and is write protected' ); return false; } if (filemtime($v_header['filename']) > $v_header['mtime']) { // To be completed : An error or silent no replace ? } } // ----- Check the directory availability and create it if necessary elseif (($v_result = $this->_dirCheck( ($v_header['typeflag'] == "5" ? $v_header['filename'] : dirname($v_header['filename'])) )) != 1 ) { $this->_error('Unable to create path for ' . $v_header['filename']); return false; } if ($v_extract_file) { if ($v_header['typeflag'] == "5") { if (!@file_exists($v_header['filename'])) { if (!@mkdir($v_header['filename'], 0777)) { $this->_error( 'Unable to create directory {' . $v_header['filename'] . '}' ); return false; } } } elseif ($v_header['typeflag'] == "2") { if (!$p_symlinks) { $this->_warning('Symbolic links are not allowed. ' . 'Unable to extract {' . $v_header['filename'] . '}' ); return false; } $absolute_link = FALSE; $link_depth = 0; if (strpos($v_header['link'], "/") === 0 || strpos($v_header['link'], ':') !== FALSE) { $absolute_link = TRUE; } else { $s_filename = preg_replace('@^' . preg_quote($p_path) . '@', "", $v_header['filename']); $s_linkname = str_replace('\\', '/', $v_header['link']); foreach (explode("/", $s_filename) as $dir) { if ($dir === "..") { $link_depth--; } elseif ($dir !== "" && $dir !== "." ) { $link_depth++; } } foreach (explode("/", $s_linkname) as $dir){ if ($link_depth <= 0) { break; } if ($dir === "..") { $link_depth--; } elseif ($dir !== "" && $dir !== ".") { $link_depth++; } } } if ($absolute_link || $link_depth <= 0) { $this->_error( 'Out-of-path file extraction {' . $v_header['filename'] . ' --> ' . $v_header['link'] . '}' ); return false; } if (@file_exists($v_header['filename'])) { @unlink($v_header['filename']); } if (!@symlink($v_header['link'], $v_header['filename'])) { $this->_error( 'Unable to extract symbolic link {' . $v_header['filename'] . '}' ); return false; } } else { if (($v_dest_file = @fopen($v_header['filename'], "wb")) == 0) { $this->_error( 'Error while opening {' . $v_header['filename'] . '} in write binary mode' ); return false; } else { $n = floor($v_header['size'] / 512); for ($i = 0; $i < $n; $i++) { $v_content = $this->_readBlock(); fwrite($v_dest_file, $v_content, 512); } if (($v_header['size'] % 512) != 0) { $v_content = $this->_readBlock(); fwrite($v_dest_file, $v_content, ($v_header['size'] % 512)); } @fclose($v_dest_file); if ($p_preserve) { @chown($v_header['filename'], $v_header['uid']); @chgrp($v_header['filename'], $v_header['gid']); } // ----- Change the file mode, mtime @touch($v_header['filename'], $v_header['mtime']); if ($v_header['mode'] & 0111) { // make file executable, obey umask $mode = fileperms($v_header['filename']) | (~umask() & 0111); @chmod($v_header['filename'], $mode); } } // ----- Check the file size clearstatcache(); if (!is_file($v_header['filename'])) { $this->_error( 'Extracted file ' . $v_header['filename'] . 'does not exist. Archive may be corrupted.' ); return false; } $filesize = filesize($v_header['filename']); if ($filesize != $v_header['size']) { $this->_error( 'Extracted file ' . $v_header['filename'] . ' does not have the correct file size \'' . $filesize . '\' (' . $v_header['size'] . ' expected). Archive may be corrupted.' ); return false; } } } else { $this->_jumpBlock(ceil(($v_header['size'] / 512))); } } else { $this->_jumpBlock(ceil(($v_header['size'] / 512))); } /* TBC : Seems to be unused ... if ($this->_compress) $v_end_of_file = @gzeof($this->_file); else $v_end_of_file = @feof($this->_file); */ if ($v_listing || $v_extract_file || $v_extraction_stopped) { // ----- Log extracted files if (($v_file_dir = dirname($v_header['filename'])) == $v_header['filename'] ) { $v_file_dir = ''; } if ((substr($v_header['filename'], 0, 1) == '/') && ($v_file_dir == '')) { $v_file_dir = '/'; } $p_list_detail[$v_nb++] = $v_header; if (is_array($p_file_list) && (count($p_list_detail) == count($p_file_list))) { return true; } } } return true; } /** * @return bool */ public function _openAppend() { if (filesize($this->_tarname) == 0) { return $this->_openWrite(); } if ($this->_compress) { $this->_close(); if (!@rename($this->_tarname, $this->_tarname . ".tmp")) { $this->_error( 'Error while renaming \'' . $this->_tarname . '\' to temporary file \'' . $this->_tarname . '.tmp\'' ); return false; } if ($this->_compress_type == 'gz') { $v_temp_tar = @gzopen($this->_tarname . ".tmp", "rb"); } elseif ($this->_compress_type == 'bz2') { $v_temp_tar = @bzopen($this->_tarname . ".tmp", "r"); } elseif ($this->_compress_type == 'lzma2') { $v_temp_tar = @xzopen($this->_tarname . ".tmp", "r"); } if ($v_temp_tar == 0) { $this->_error( 'Unable to open file \'' . $this->_tarname . '.tmp\' in binary read mode' ); @rename($this->_tarname . ".tmp", $this->_tarname); return false; } if (!$this->_openWrite()) { @rename($this->_tarname . ".tmp", $this->_tarname); return false; } if ($this->_compress_type == 'gz') { $end_blocks = 0; while (!@gzeof($v_temp_tar)) { $v_buffer = @gzread($v_temp_tar, 512); if ($v_buffer == ARCHIVE_TAR_END_BLOCK || strlen($v_buffer) == 0) { $end_blocks++; // do not copy end blocks, we will re-make them // after appending continue; } elseif ($end_blocks > 0) { for ($i = 0; $i < $end_blocks; $i++) { $this->_writeBlock(ARCHIVE_TAR_END_BLOCK); } $end_blocks = 0; } $v_binary_data = pack("a512", $v_buffer); $this->_writeBlock($v_binary_data); } @gzclose($v_temp_tar); } elseif ($this->_compress_type == 'bz2') { $end_blocks = 0; while (strlen($v_buffer = @bzread($v_temp_tar, 512)) > 0) { if ($v_buffer == ARCHIVE_TAR_END_BLOCK || strlen($v_buffer) == 0) { $end_blocks++; // do not copy end blocks, we will re-make them // after appending continue; } elseif ($end_blocks > 0) { for ($i = 0; $i < $end_blocks; $i++) { $this->_writeBlock(ARCHIVE_TAR_END_BLOCK); } $end_blocks = 0; } $v_binary_data = pack("a512", $v_buffer); $this->_writeBlock($v_binary_data); } @bzclose($v_temp_tar); } elseif ($this->_compress_type == 'lzma2') { $end_blocks = 0; while (strlen($v_buffer = @xzread($v_temp_tar, 512)) > 0) { if ($v_buffer == ARCHIVE_TAR_END_BLOCK || strlen($v_buffer) == 0) { $end_blocks++; // do not copy end blocks, we will re-make them // after appending continue; } elseif ($end_blocks > 0) { for ($i = 0; $i < $end_blocks; $i++) { $this->_writeBlock(ARCHIVE_TAR_END_BLOCK); } $end_blocks = 0; } $v_binary_data = pack("a512", $v_buffer); $this->_writeBlock($v_binary_data); } @xzclose($v_temp_tar); } if (!@unlink($this->_tarname . ".tmp")) { $this->_error( 'Error while deleting temporary file \'' . $this->_tarname . '.tmp\'' ); } } else { // ----- For not compressed tar, just add files before the last // one or two 512 bytes block if (!$this->_openReadWrite()) { return false; } clearstatcache(); $v_size = filesize($this->_tarname); // We might have zero, one or two end blocks. // The standard is two, but we should try to handle // other cases. fseek($this->_file, $v_size - 1024); if (fread($this->_file, 512) == ARCHIVE_TAR_END_BLOCK) { fseek($this->_file, $v_size - 1024); } elseif (fread($this->_file, 512) == ARCHIVE_TAR_END_BLOCK) { fseek($this->_file, $v_size - 512); } } return true; } /** * @param $p_filelist * @param string $p_add_dir * @param string $p_remove_dir * @return bool */ public function _append($p_filelist, $p_add_dir = '', $p_remove_dir = '') { if (!$this->_openAppend()) { return false; } if ($this->_addList($p_filelist, $p_add_dir, $p_remove_dir)) { $this->_writeFooter(); } $this->_close(); return true; } /** * Check if a directory exists and create it (including parent * dirs) if not. * * @param string $p_dir directory to check * * @return bool true if the directory exists or was created */ public function _dirCheck($p_dir) { clearstatcache(); if ((@is_dir($p_dir)) || ($p_dir == '')) { return true; } $p_parent_dir = dirname($p_dir); if (($p_parent_dir != $p_dir) && ($p_parent_dir != '') && (!$this->_dirCheck($p_parent_dir)) ) { return false; } if (!@mkdir($p_dir, 0777)) { $this->_error("Unable to create directory '$p_dir'"); return false; } return true; } /** * Compress path by changing for example "/dir/foo/../bar" to "/dir/bar", * rand emove double slashes. * * @param string $p_dir path to reduce * * @return string reduced path */ private function _pathReduction($p_dir) { $v_result = ''; // ----- Look for not empty path if ($p_dir != '') { // ----- Explode path by directory names $v_list = explode('/', $p_dir); // ----- Study directories from last to first for ($i = sizeof($v_list) - 1; $i >= 0; $i--) { // ----- Look for current path if ($v_list[$i] == ".") { // ----- Ignore this directory // Should be the first $i=0, but no check is done } else { if ($v_list[$i] == "..") { // ----- Ignore it and ignore the $i-1 $i--; } else { if (($v_list[$i] == '') && ($i != (sizeof($v_list) - 1)) && ($i != 0) ) { // ----- Ignore only the double '//' in path, // but not the first and last / } else { $v_result = $v_list[$i] . ($i != (sizeof($v_list) - 1) ? '/' . $v_result : ''); } } } } } if (defined('OS_WINDOWS') && OS_WINDOWS) { $v_result = strtr($v_result, '\\', '/'); } return $v_result; } /** * @param $p_path * @param bool $p_remove_disk_letter * @return string */ public function _translateWinPath($p_path, $p_remove_disk_letter = true) { if (defined('OS_WINDOWS') && OS_WINDOWS) { // ----- Look for potential disk letter if (($p_remove_disk_letter) && (($v_position = strpos($p_path, ':')) != false) ) { $p_path = substr($p_path, $v_position + 1); } // ----- Change potential windows directory separator if ((strpos($p_path, '\\') > 0) || (substr($p_path, 0, 1) == '\\')) { $p_path = strtr($p_path, '\\', '/'); } } return $p_path; } } PK�����u]p0 �� ����.registry/net_idna2.regnu�[��������a:22:{s:7:"attribs";a:6:{s:15:"packagerversion";s:6:"1.10.3";s:7:"version";s:3:"2.0";s:5:"xmlns";s:36:"https://pear.php.net/dtd/package-2.0";s:11:"xmlns:tasks";s:34:"https://pear.php.net/dtd/tasks-1.0";s:9:"xmlns:xsi";s:42:"https://www.w3.org/2001/XMLSchema-instance";s:18:"xsi:schemaLocation";s:151:"https://pear.php.net/dtd/tasks-1.0 https://pear.php.net/dtd/tasks-1.0.xsd https://pear.php.net/dtd/package-2.0 https://pear.php.net/dtd/package-2.0.xsd";}s:4:"name";s:9:"Net_IDNA2";s:7:"channel";s:12:"pear.php.net";s:7:"summary";s:31:"Punycode encoding and decoding.";s:11:"description";s:68:"This package helps you to encode and decode punycode strings easily.";s:4:"lead";a:2:{i:0;a:4:{s:4:"name";s:15:"Stefan Neufeind";s:4:"user";s:8:"neufeind";s:5:"email";s:29:"pear.neufeind@speedpartner.de";s:6:"active";s:3:"yes";}i:1;a:4:{s:4:"name";s:15:"Daniel O'Connor";s:4:"user";s:8:"doconnor";s:5:"email";s:24:"daniel.oconnor@gmail.com";s:6:"active";s:2:"no";}}s:4:"date";s:10:"2017-03-06";s:4:"time";s:8:"20:40:58";s:7:"version";a:2:{s:7:"release";s:5:"0.2.0";s:3:"api";s:5:"0.2.0";}s:9:"stability";a:2:{s:7:"release";s:4:"beta";s:3:"api";s:4:"beta";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:40:"https://www.gnu.org/copyleft/lesser.html";}s:8:"_content";s:4:"LGPL";}s:5:"notes";s:165:"* Set minimum PHP version to 5.4.0 * Set minimum PEAR version to 1.10.1 * Bug #19375: Add static to the fuction getInstance * Bug #21123: Signing the source package";s:8:"contents";a:1:{s:3:"dir";a:2:{s:7:"attribs";a:2:{s:14:"baseinstalldir";s:1:"/";s:4:"name";s:1:"/";}s:4:"file";a:5:{i:0;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"41766020ff8f63f695c9bf7e86040e70";s:4:"name";s:13:"Net/IDNA2.php";s:4:"role";s:3:"php";}}i:1;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"72f605f2f6d9d56e07bb6bcec099d03a";s:4:"name";s:23:"Net/IDNA2/Exception.php";s:4:"role";s:3:"php";}}i:2;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"06c4217024082f0f3b6c5a7e61ac7130";s:4:"name";s:32:"Net/IDNA2/Exception/Nameprep.php";s:4:"role";s:3:"php";}}i:3;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"999210e6bd489aba06e5121a2788956f";s:4:"name";s:23:"tests/Net_IDNA2Test.php";s:4:"role";s:4:"test";}}i:4;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"2996ea57df9e5e3153da8a94fbb3c603";s:4:"name";s:42:"tests/draft-josefsson-idn-test-vectors.php";s:4:"role";s:4:"test";}}}}}s:12:"dependencies";a:1:{s:8:"required";a:2:{s:3:"php";a:1:{s:3:"min";s:5:"5.4.0";}s:13:"pearinstaller";a:1:{s:3:"min";s:6:"1.10.1";}}}s:10:"phprelease";s:0:"";s:9:"changelog";a:1:{s:7:"release";a:2:{i:0;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"0.1.0";s:3:"api";s:5:"0.1.0";}s:9:"stability";a:2:{s:7:"release";s:4:"beta";s:3:"api";s:4:"beta";}s:4:"date";s:10:"2010-06-03";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:40:"https://www.gnu.org/copyleft/lesser.html";}s:8:"_content";s:4:"LGPL";}s:5:"notes";s:139:"QA Release Bug #17430 Multiple Net_IDNA class declarations Warning: This package is now split between Net_IDNA (php4) and Net_IDNA2 (php5)";}i:1;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"0.2.0";s:3:"api";s:5:"0.2.0";}s:9:"stability";a:2:{s:7:"release";s:4:"beta";s:3:"api";s:4:"beta";}s:4:"date";s:10:"2017-03-06";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:40:"https://www.gnu.org/copyleft/lesser.html";}s:8:"_content";s:4:"LGPL";}s:5:"notes";s:165:"* Set minimum PHP version to 5.4.0 * Set minimum PEAR version to 1.10.1 * Bug #19375: Add static to the fuction getInstance * Bug #21123: Signing the source package";}}}s:8:"filelist";a:5:{s:13:"Net/IDNA2.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"41766020ff8f63f695c9bf7e86040e70";s:4:"name";s:13:"Net/IDNA2.php";s:4:"role";s:3:"php";s:12:"installed_as";s:43:"/opt/alt/php56/usr/share/pear/Net/IDNA2.php";}s:23:"Net/IDNA2/Exception.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"72f605f2f6d9d56e07bb6bcec099d03a";s:4:"name";s:23:"Net/IDNA2/Exception.php";s:4:"role";s:3:"php";s:12:"installed_as";s:53:"/opt/alt/php56/usr/share/pear/Net/IDNA2/Exception.php";}s:32:"Net/IDNA2/Exception/Nameprep.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"06c4217024082f0f3b6c5a7e61ac7130";s:4:"name";s:32:"Net/IDNA2/Exception/Nameprep.php";s:4:"role";s:3:"php";s:12:"installed_as";s:62:"/opt/alt/php56/usr/share/pear/Net/IDNA2/Exception/Nameprep.php";}s:23:"tests/Net_IDNA2Test.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"999210e6bd489aba06e5121a2788956f";s:4:"name";s:23:"tests/Net_IDNA2Test.php";s:4:"role";s:4:"test";s:12:"installed_as";s:68:"/opt/alt/php56/usr/share/pear/test/Net_IDNA2/tests/Net_IDNA2Test.php";}s:42:"tests/draft-josefsson-idn-test-vectors.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"2996ea57df9e5e3153da8a94fbb3c603";s:4:"name";s:42:"tests/draft-josefsson-idn-test-vectors.php";s:4:"role";s:4:"test";s:12:"installed_as";s:87:"/opt/alt/php56/usr/share/pear/test/Net_IDNA2/tests/draft-josefsson-idn-test-vectors.php";}}s:12:"_lastversion";N;s:7:"dirtree";a:5:{s:33:"/opt/alt/php56/usr/share/pear/Net";b:1;s:39:"/opt/alt/php56/usr/share/pear/Net/IDNA2";b:1;s:49:"/opt/alt/php56/usr/share/pear/Net/IDNA2/Exception";b:1;s:50:"/opt/alt/php56/usr/share/pear/test/Net_IDNA2/tests";b:1;s:44:"/opt/alt/php56/usr/share/pear/test/Net_IDNA2";b:1;}s:3:"old";a:7:{s:7:"version";s:5:"0.2.0";s:12:"release_date";s:10:"2017-03-06";s:13:"release_state";s:4:"beta";s:15:"release_license";s:4:"LGPL";s:13:"release_notes";s:165:"* Set minimum PHP version to 5.4.0 * Set minimum PEAR version to 1.10.1 * Bug #19375: Add static to the fuction getInstance * Bug #21123: Signing the source package";s:12:"release_deps";a:2:{i:0;a:4:{s:4:"type";s:3:"php";s:3:"rel";s:2:"ge";s:7:"version";s:5:"5.4.0";s:8:"optional";s:2:"no";}i:1;a:6:{s:4:"type";s:3:"pkg";s:7:"channel";s:12:"pear.php.net";s:4:"name";s:4:"PEAR";s:3:"rel";s:2:"ge";s:7:"version";s:6:"1.10.1";s:8:"optional";s:2:"no";}}s:11:"maintainers";a:2:{i:0;a:5:{s:4:"name";s:15:"Stefan Neufeind";s:5:"email";s:29:"pear.neufeind@speedpartner.de";s:6:"active";s:3:"yes";s:6:"handle";s:8:"neufeind";s:4:"role";s:4:"lead";}i:1;a:5:{s:4:"name";s:15:"Daniel O'Connor";s:5:"email";s:24:"daniel.oconnor@gmail.com";s:6:"active";s:2:"no";s:6:"handle";s:8:"doconnor";s:4:"role";s:4:"lead";}}}s:10:"xsdversion";s:3:"2.0";s:13:"_lastmodified";i:1669631553;}PK�����u]Jv~������.registry/net_socket.regnu�[��������a:21:{s:7:"attribs";a:6:{s:15:"packagerversion";s:6:"1.10.3";s:7:"version";s:3:"2.0";s:5:"xmlns";s:35:"http://pear.php.net/dtd/package-2.0";s:11:"xmlns:tasks";s:33:"http://pear.php.net/dtd/tasks-1.0";s:9:"xmlns:xsi";s:41:"http://www.w3.org/2001/XMLSchema-instance";s:18:"xsi:schemaLocation";s:147:"http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd";}s:4:"name";s:10:"Net_Socket";s:7:"channel";s:12:"pear.php.net";s:7:"summary";s:24:"Network Socket Interface";s:11:"description";s:237:"Net_Socket is a class interface to TCP sockets. It provides blocking and non-blocking operation, with different reading and writing modes (byte-wise, block-wise, line-wise and special formats like network byte-order ip addresses).";s:4:"lead";a:3:{i:0;a:4:{s:4:"name";s:15:"Chuck Hagenbuch";s:4:"user";s:8:"chagenbu";s:5:"email";s:15:"chuck@horde.org";s:6:"active";s:2:"no";}i:1;a:4:{s:4:"name";s:11:"Stig Bakken";s:4:"user";s:3:"ssb";s:5:"email";s:12:"stig@php.net";s:6:"active";s:2:"no";}i:2;a:4:{s:4:"name";s:19:"Aleksander Machniak";s:4:"user";s:4:"alec";s:5:"email";s:12:"alec@php.net";s:6:"active";s:2:"no";}}s:4:"date";s:10:"2017-04-13";s:4:"time";s:8:"17:15:33";s:7:"version";a:2:{s:7:"release";s:5:"1.2.2";s:3:"api";s:5:"1.2.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:12:"BSD-2-Clause";}s:5:"notes";s:52:"* Bug #21178: $php_errormsg is deprecated in PHP 7.2";s:8:"contents";a:1:{s:3:"dir";a:2:{s:7:"attribs";a:2:{s:14:"baseinstalldir";s:1:"/";s:4:"name";s:1:"/";}s:4:"file";a:3:{i:0;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"f99081ef3a69bcc1faa0d90a9a616788";s:4:"name";s:14:"Net/Socket.php";s:4:"role";s:3:"php";}}i:1;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"61a9ed8d1604a739e6997149ea34e701";s:4:"name";s:9:"README.md";s:4:"role";s:3:"doc";}}i:2;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"28575b04f4f2014316245d83e27343e1";s:4:"name";s:7:"LICENSE";s:4:"role";s:3:"doc";}}}}}s:12:"dependencies";a:1:{s:8:"required";a:2:{s:3:"php";a:1:{s:3:"min";s:5:"5.4.0";}s:13:"pearinstaller";a:1:{s:3:"min";s:6:"1.10.1";}}}s:10:"phprelease";s:0:"";s:8:"filelist";a:3:{s:14:"Net/Socket.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"f99081ef3a69bcc1faa0d90a9a616788";s:4:"name";s:14:"Net/Socket.php";s:4:"role";s:3:"php";s:12:"installed_as";s:44:"/opt/alt/php56/usr/share/pear/Net/Socket.php";}s:9:"README.md";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"61a9ed8d1604a739e6997149ea34e701";s:4:"name";s:9:"README.md";s:4:"role";s:3:"doc";s:12:"installed_as";s:54:"/opt/alt/php56/usr/share/doc/pear/Net_Socket/README.md";}s:7:"LICENSE";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"28575b04f4f2014316245d83e27343e1";s:4:"name";s:7:"LICENSE";s:4:"role";s:3:"doc";s:12:"installed_as";s:52:"/opt/alt/php56/usr/share/doc/pear/Net_Socket/LICENSE";}}s:12:"_lastversion";N;s:7:"dirtree";a:2:{s:33:"/opt/alt/php56/usr/share/pear/Net";b:1;s:44:"/opt/alt/php56/usr/share/doc/pear/Net_Socket";b:1;}s:3:"old";a:7:{s:7:"version";s:5:"1.2.2";s:12:"release_date";s:10:"2017-04-13";s:13:"release_state";s:6:"stable";s:15:"release_license";s:12:"BSD-2-Clause";s:13:"release_notes";s:52:"* Bug #21178: $php_errormsg is deprecated in PHP 7.2";s:12:"release_deps";a:2:{i:0;a:4:{s:4:"type";s:3:"php";s:3:"rel";s:2:"ge";s:7:"version";s:5:"5.4.0";s:8:"optional";s:2:"no";}i:1;a:6:{s:4:"type";s:3:"pkg";s:7:"channel";s:12:"pear.php.net";s:4:"name";s:4:"PEAR";s:3:"rel";s:2:"ge";s:7:"version";s:6:"1.10.1";s:8:"optional";s:2:"no";}}s:11:"maintainers";a:3:{i:0;a:5:{s:4:"name";s:15:"Chuck Hagenbuch";s:5:"email";s:15:"chuck@horde.org";s:6:"active";s:2:"no";s:6:"handle";s:8:"chagenbu";s:4:"role";s:4:"lead";}i:1;a:5:{s:4:"name";s:11:"Stig Bakken";s:5:"email";s:12:"stig@php.net";s:6:"active";s:2:"no";s:6:"handle";s:3:"ssb";s:4:"role";s:4:"lead";}i:2;a:5:{s:4:"name";s:19:"Aleksander Machniak";s:5:"email";s:12:"alec@php.net";s:6:"active";s:2:"no";s:6:"handle";s:4:"alec";s:4:"role";s:4:"lead";}}}s:10:"xsdversion";s:3:"2.0";s:13:"_lastmodified";i:1669631553;}PK�����u]rXS)��S)����.registry/mail.regnu�[��������a:22:{s:7:"attribs";a:6:{s:15:"packagerversion";s:6:"1.10.3";s:7:"version";s:3:"2.0";s:5:"xmlns";s:35:"http://pear.php.net/dtd/package-2.0";s:11:"xmlns:tasks";s:33:"http://pear.php.net/dtd/tasks-1.0";s:9:"xmlns:xsi";s:41:"http://www.w3.org/2001/XMLSchema-instance";s:18:"xsi:schemaLocation";s:147:"http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd";}s:4:"name";s:4:"Mail";s:7:"channel";s:12:"pear.php.net";s:7:"summary";s:58:"Class that provides multiple interfaces for sending emails";s:11:"description";s:337:"PEAR's Mail package defines an interface for implementing mailers under the PEAR hierarchy. It also provides supporting functions useful to multiple mailer backends. Currently supported backends include: PHP's native mail() function, sendmail, and SMTP. This package also provides a RFC822 email address list validation utility class.";s:4:"lead";a:4:{s:4:"name";s:15:"Chuck Hagenbuch";s:4:"user";s:8:"chagenbu";s:5:"email";s:15:"chuck@horde.org";s:6:"active";s:2:"no";}s:9:"developer";a:2:{i:0;a:4:{s:4:"name";s:13:"Richard Heyes";s:4:"user";s:7:"richard";s:5:"email";s:19:"richard@phpguru.org";s:6:"active";s:2:"no";}i:1;a:4:{s:4:"name";s:19:"Aleksander Machniak";s:4:"user";s:4:"alec";s:5:"email";s:12:"alec@alec.pl";s:6:"active";s:3:"yes";}}s:4:"date";s:10:"2017-04-11";s:4:"time";s:8:"17:26:44";s:7:"version";a:2:{s:7:"release";s:5:"1.4.1";s:3:"api";s:5:"1.3.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:44:"https://opensource.org/licenses/BSD-3-Clause";}s:8:"_content";s:15:"New BSD License";}s:5:"notes";s:177:"* Loosen recognition of "queued as" server response (PR #10) * Bug #20463: domain-literal parsing error * Bug #20513: Mail_smtp::send() doesn't close socket for smtp connection";s:8:"contents";a:1:{s:3:"dir";a:2:{s:7:"attribs";a:2:{s:14:"baseinstalldir";s:1:"/";s:4:"name";s:1:"/";}s:4:"file";a:16:{i:0;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"8210c33901d415a2692944291632bf34";s:4:"name";s:7:"LICENSE";s:4:"role";s:3:"doc";}}i:1;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"4e86cd3b980f73ef320988a1b299ee07";s:4:"name";s:13:"Mail/mail.php";s:4:"role";s:3:"php";}}i:2;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"360b7b613c98c7703151c50a6e74c367";s:4:"name";s:13:"Mail/mock.php";s:4:"role";s:3:"php";}}i:3;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"30ce63a4a2c4558b3752b1c302e6e508";s:4:"name";s:13:"Mail/null.php";s:4:"role";s:3:"php";}}i:4;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"7199f4e7b07919082a804edb8680c811";s:4:"name";s:15:"Mail/RFC822.php";s:4:"role";s:3:"php";}}i:5;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"5dd0b6ff126608818f44f5866b61b3d0";s:4:"name";s:17:"Mail/sendmail.php";s:4:"role";s:3:"php";}}i:6;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"1d236356d52f3dfa13b740a48a821586";s:4:"name";s:13:"Mail/smtp.php";s:4:"role";s:3:"php";}}i:7;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"853b55cf4803df8caaaa0dca363971ff";s:4:"name";s:15:"Mail/smtpmx.php";s:4:"role";s:3:"php";}}i:8;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"3077f0c01f72cc29a6f8f0175e7fc8a7";s:4:"name";s:8:"Mail.php";s:4:"role";s:3:"php";}}i:9;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"d66aa2a2f0bfe33f8a67d749a1a4d345";s:4:"name";s:15:"tests/9137.phpt";s:4:"role";s:4:"test";}}i:10;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"75d10361f686f1cc16637a9364e3eab7";s:4:"name";s:17:"tests/9137_2.phpt";s:4:"role";s:4:"test";}}i:11;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"63715aad2b5b3ae35c6b05acf04d9ad7";s:4:"name";s:16:"tests/13659.phpt";s:4:"role";s:4:"test";}}i:12;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"e99f00d8f07232e0f129dd77ae9699c7";s:4:"name";s:19:"tests/bug17178.phpt";s:4:"role";s:4:"test";}}i:13;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"c2036980390981cd6b89c1e5c903913e";s:4:"name";s:19:"tests/bug17317.phpt";s:4:"role";s:4:"test";}}i:14;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"7b0eae971fe7595e7c1a563fbfcfee90";s:4:"name";s:17:"tests/rfc822.phpt";s:4:"role";s:4:"test";}}i:15;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"67becdb1027cefcb8dff1b691da630ab";s:4:"name";s:21:"tests/smtp_error.phpt";s:4:"role";s:4:"test";}}}}}s:12:"dependencies";a:2:{s:8:"required";a:2:{s:3:"php";a:1:{s:3:"min";s:5:"5.2.1";}s:13:"pearinstaller";a:1:{s:3:"min";s:5:"1.5.6";}}s:8:"optional";a:1:{s:7:"package";a:3:{s:4:"name";s:8:"Net_SMTP";s:7:"channel";s:12:"pear.php.net";s:3:"min";s:5:"1.4.1";}}}s:10:"phprelease";s:0:"";s:8:"filelist";a:16:{s:7:"LICENSE";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"8210c33901d415a2692944291632bf34";s:4:"name";s:7:"LICENSE";s:4:"role";s:3:"doc";s:12:"installed_as";s:46:"/opt/alt/php56/usr/share/doc/pear/Mail/LICENSE";}s:13:"Mail/mail.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"4e86cd3b980f73ef320988a1b299ee07";s:4:"name";s:13:"Mail/mail.php";s:4:"role";s:3:"php";s:12:"installed_as";s:43:"/opt/alt/php56/usr/share/pear/Mail/mail.php";}s:13:"Mail/mock.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"360b7b613c98c7703151c50a6e74c367";s:4:"name";s:13:"Mail/mock.php";s:4:"role";s:3:"php";s:12:"installed_as";s:43:"/opt/alt/php56/usr/share/pear/Mail/mock.php";}s:13:"Mail/null.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"30ce63a4a2c4558b3752b1c302e6e508";s:4:"name";s:13:"Mail/null.php";s:4:"role";s:3:"php";s:12:"installed_as";s:43:"/opt/alt/php56/usr/share/pear/Mail/null.php";}s:15:"Mail/RFC822.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"7199f4e7b07919082a804edb8680c811";s:4:"name";s:15:"Mail/RFC822.php";s:4:"role";s:3:"php";s:12:"installed_as";s:45:"/opt/alt/php56/usr/share/pear/Mail/RFC822.php";}s:17:"Mail/sendmail.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"5dd0b6ff126608818f44f5866b61b3d0";s:4:"name";s:17:"Mail/sendmail.php";s:4:"role";s:3:"php";s:12:"installed_as";s:47:"/opt/alt/php56/usr/share/pear/Mail/sendmail.php";}s:13:"Mail/smtp.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"1d236356d52f3dfa13b740a48a821586";s:4:"name";s:13:"Mail/smtp.php";s:4:"role";s:3:"php";s:12:"installed_as";s:43:"/opt/alt/php56/usr/share/pear/Mail/smtp.php";}s:15:"Mail/smtpmx.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"853b55cf4803df8caaaa0dca363971ff";s:4:"name";s:15:"Mail/smtpmx.php";s:4:"role";s:3:"php";s:12:"installed_as";s:45:"/opt/alt/php56/usr/share/pear/Mail/smtpmx.php";}s:8:"Mail.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"3077f0c01f72cc29a6f8f0175e7fc8a7";s:4:"name";s:8:"Mail.php";s:4:"role";s:3:"php";s:12:"installed_as";s:38:"/opt/alt/php56/usr/share/pear/Mail.php";}s:15:"tests/9137.phpt";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"d66aa2a2f0bfe33f8a67d749a1a4d345";s:4:"name";s:15:"tests/9137.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:55:"/opt/alt/php56/usr/share/pear/test/Mail/tests/9137.phpt";}s:17:"tests/9137_2.phpt";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"75d10361f686f1cc16637a9364e3eab7";s:4:"name";s:17:"tests/9137_2.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:57:"/opt/alt/php56/usr/share/pear/test/Mail/tests/9137_2.phpt";}s:16:"tests/13659.phpt";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"63715aad2b5b3ae35c6b05acf04d9ad7";s:4:"name";s:16:"tests/13659.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:56:"/opt/alt/php56/usr/share/pear/test/Mail/tests/13659.phpt";}s:19:"tests/bug17178.phpt";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"e99f00d8f07232e0f129dd77ae9699c7";s:4:"name";s:19:"tests/bug17178.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:59:"/opt/alt/php56/usr/share/pear/test/Mail/tests/bug17178.phpt";}s:19:"tests/bug17317.phpt";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"c2036980390981cd6b89c1e5c903913e";s:4:"name";s:19:"tests/bug17317.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:59:"/opt/alt/php56/usr/share/pear/test/Mail/tests/bug17317.phpt";}s:17:"tests/rfc822.phpt";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"7b0eae971fe7595e7c1a563fbfcfee90";s:4:"name";s:17:"tests/rfc822.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:57:"/opt/alt/php56/usr/share/pear/test/Mail/tests/rfc822.phpt";}s:21:"tests/smtp_error.phpt";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"67becdb1027cefcb8dff1b691da630ab";s:4:"name";s:21:"tests/smtp_error.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:61:"/opt/alt/php56/usr/share/pear/test/Mail/tests/smtp_error.phpt";}}s:12:"_lastversion";N;s:7:"dirtree";a:5:{s:38:"/opt/alt/php56/usr/share/doc/pear/Mail";b:1;s:34:"/opt/alt/php56/usr/share/pear/Mail";b:1;s:29:"/opt/alt/php56/usr/share/pear";b:1;s:45:"/opt/alt/php56/usr/share/pear/test/Mail/tests";b:1;s:39:"/opt/alt/php56/usr/share/pear/test/Mail";b:1;}s:3:"old";a:7:{s:7:"version";s:5:"1.4.1";s:12:"release_date";s:10:"2017-04-11";s:13:"release_state";s:6:"stable";s:15:"release_license";s:15:"New BSD License";s:13:"release_notes";s:177:"* Loosen recognition of "queued as" server response (PR #10) * Bug #20463: domain-literal parsing error * Bug #20513: Mail_smtp::send() doesn't close socket for smtp connection";s:12:"release_deps";a:3:{i:0;a:4:{s:4:"type";s:3:"php";s:3:"rel";s:2:"ge";s:7:"version";s:5:"5.2.1";s:8:"optional";s:2:"no";}i:1;a:6:{s:4:"type";s:3:"pkg";s:7:"channel";s:12:"pear.php.net";s:4:"name";s:4:"PEAR";s:3:"rel";s:2:"ge";s:7:"version";s:5:"1.5.6";s:8:"optional";s:2:"no";}i:2;a:6:{s:4:"type";s:3:"pkg";s:7:"channel";s:12:"pear.php.net";s:4:"name";s:8:"Net_SMTP";s:3:"rel";s:2:"ge";s:7:"version";s:5:"1.4.1";s:8:"optional";s:3:"yes";}}s:11:"maintainers";a:3:{i:0;a:5:{s:4:"name";s:15:"Chuck Hagenbuch";s:5:"email";s:15:"chuck@horde.org";s:6:"active";s:2:"no";s:6:"handle";s:8:"chagenbu";s:4:"role";s:4:"lead";}i:1;a:5:{s:4:"name";s:13:"Richard Heyes";s:5:"email";s:19:"richard@phpguru.org";s:6:"active";s:2:"no";s:6:"handle";s:7:"richard";s:4:"role";s:9:"developer";}i:2;a:5:{s:4:"name";s:19:"Aleksander Machniak";s:5:"email";s:12:"alec@alec.pl";s:6:"active";s:3:"yes";s:6:"handle";s:4:"alec";s:4:"role";s:9:"developer";}}}s:10:"xsdversion";s:3:"2.0";s:13:"_lastmodified";i:1669631553;}PK�����u]i:+��:+����.registry/mail_mimedecode.regnu�[��������a:23:{s:7:"attribs";a:6:{s:15:"packagerversion";s:6:"1.10.1";s:7:"version";s:3:"2.0";s:5:"xmlns";s:35:"http://pear.php.net/dtd/package-2.0";s:11:"xmlns:tasks";s:33:"http://pear.php.net/dtd/tasks-1.0";s:9:"xmlns:xsi";s:41:"http://www.w3.org/2001/XMLSchema-instance";s:18:"xsi:schemaLocation";s:160:"http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd";}s:4:"name";s:15:"Mail_mimeDecode";s:7:"channel";s:12:"pear.php.net";s:7:"summary";s:41:"Provides a class to decode mime messages.";s:11:"description";s:157:"Provides a class to deal with the decoding and interpreting of mime messages. This package used to be part of the Mail_Mime package, but has been split off.";s:4:"lead";a:2:{i:0;a:4:{s:4:"name";s:19:"Cipriano Groenendal";s:4:"user";s:5:"cipri";s:5:"email";s:13:"cipri@php.net";s:6:"active";s:3:"yes";}i:1;a:4:{s:4:"name";s:12:"Alan Knowles";s:4:"user";s:6:"alan_k";s:5:"email";s:17:"alan@akbkhome.com";s:6:"active";s:3:"yes";}}s:9:"developer";a:4:{s:4:"name";s:19:"George Schlossnagle";s:4:"user";s:13:"gschlossnagle";s:5:"email";s:17:"george@omniti.com";s:6:"active";s:2:"no";}s:4:"date";s:10:"2016-08-29";s:4:"time";s:8:"03:04:25";s:7:"version";a:2:{s:7:"release";s:5:"1.5.6";s:3:"api";s:5:"1.3.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:9:"BSD Style";}s:5:"notes";s:245:"Minor Bug fix release. #20431 - support for android #19762 - multipart signed not split correctly on line breaks #20027 - replace /e with preg_replace_callback #19762 - multipart/signed eating of new line, and expose sig_hdr etc.";s:8:"contents";a:1:{s:3:"dir";a:2:{s:7:"attribs";a:2:{s:14:"baseinstalldir";s:1:"/";s:4:"name";s:1:"/";}s:4:"file";a:5:{i:0;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"05c45d0b58718ebe73860ebfe494dcef";s:4:"name";s:19:"Mail/mimeDecode.php";s:4:"role";s:3:"php";}}i:1;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"642acc06cdb217b6e64506182449d8f8";s:4:"name";s:29:"tests/parse_header_value.phpt";s:4:"role";s:4:"test";}}i:2;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"a0bc0c9b68e62a19202bd8fb26104f3c";s:4:"name";s:41:"tests/semicolon_content_type_bug1724.phpt";s:4:"role";s:4:"test";}}i:3;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"194810c478066eaeb28f51116b88e25a";s:4:"name";s:9:"xmail.dtd";s:4:"role";s:4:"data";}}i:4;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"61cea06fb6b4bd3a4b5e2d37384e14a9";s:4:"name";s:9:"xmail.xsl";s:4:"role";s:4:"data";}}}}}s:12:"dependencies";a:1:{s:8:"required";a:3:{s:3:"php";a:1:{s:3:"min";s:5:"4.3.0";}s:13:"pearinstaller";a:1:{s:3:"min";s:5:"1.6.0";}s:7:"package";a:4:{s:4:"name";s:9:"Mail_Mime";s:7:"channel";s:12:"pear.php.net";s:3:"min";s:5:"1.4.0";s:7:"exclude";s:5:"1.4.0";}}}s:10:"phprelease";s:0:"";s:9:"changelog";a:1:{s:7:"release";a:8:{i:0;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"0.1.0";s:3:"api";s:5:"1.3.1";}s:9:"stability";a:2:{s:7:"release";s:5:"alpha";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2007-06-10";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:9:"BSD Style";}s:5:"notes";s:15:"Initial Release";}i:1;a:5:{s:7:"version";a:2:{s:7:"release";s:8:"1.0.0RC1";s:3:"api";s:5:"1.3.1";}s:9:"stability";a:2:{s:7:"release";s:4:"beta";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2007-06-10";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:9:"BSD Style";}s:5:"notes";s:15:"Initial Release";}i:2;a:6:{s:4:"date";s:10:"2007-06-17";s:4:"time";s:8:"17:20:44";s:7:"version";a:2:{s:7:"release";s:5:"1.5.0";s:3:"api";s:5:"1.3.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:9:"BSD Style";}s:5:"notes";s:55:"First release of mail_mimeDecode as a seperate package.";}i:3;a:5:{s:4:"date";s:10:"2009-12-03";s:7:"version";a:2:{s:7:"release";s:5:"1.5.1";s:3:"api";s:5:"1.3.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:9:"BSD Style";}s:5:"notes";s:245:"Minor Bugfix release. Bug Fixes #----- - fix bug in getSendArray() - not handling multiple recipents #14129 - E_NOTICE fixes Requests #12365 - Add option to also include raw attached messages patched on the request of till";}i:4;a:5:{s:4:"date";s:10:"2010-09-02";s:7:"version";a:2:{s:7:"release";s:5:"1.5.2";s:3:"api";s:5:"1.3.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:9:"BSD Style";}s:5:"notes";s:271:"Minor Bugfix release. Bug Fixes #4739 - regexp parsing of header values does not balance quoting correctly - Fix sponsored by http://webyog.com #17325 - empty body messages are valid messages #17276 - remove &new usage which throws errors now";}i:5;a:5:{s:4:"date";s:10:"2010-09-05";s:7:"version";a:2:{s:7:"release";s:5:"1.5.3";s:3:"api";s:5:"1.3.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:9:"BSD Style";}s:5:"notes";s:919:"Major Bugfix release. Apart from a major cleanout of the bug tracker for this package, this release includes a revamped parseHeaderValue which removes the rather flakey regex, with a real parser, which should be considerably more robust. Bug Fixes #17844 - all regression tests fixed - remove the last of the while list each() .. this is 2010 ;)... #11410 - support wap multipart #9616 - long strings as filename etc.. aaa*0=.... aaa*1=.... aaa*2=.... (merged into aaa=.....) #9100 - change to preg_split for mime boundary detection , in theory should catch boundaries in nested situations better... #7709 - check for last element on boundary split to see if its usable #7065 - wrapped header lines with encoding should be concated without spaces #6495 - missing body in decoded object #11537 - better decode and multi-line support";}i:6;a:5:{s:4:"date";s:10:"2010-09-14";s:7:"version";a:2:{s:7:"release";s:5:"1.5.4";s:3:"api";s:5:"1.3.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:9:"BSD Style";}s:5:"notes";s:268:"Critical Security release. It is highly recommended that users of 1.5.3 upgrade to this release, a change in the boundary detection code introduced a potential denial of service attack. Bug Fixes #17862 - quote boundary preg_split code";}i:7;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.5.5";s:3:"api";s:5:"1.3.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2011-11-16";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:9:"BSD Style";}s:5:"notes";s:287:"Minor Bug fix release. #17959 - Boundaries ending with non-word characters - patch by Alex Adriaanese ------ - ignore whitespace and trailing cr/lf in last section of split ------ - correct spacing on multi-line headers. now only striped for encoded data. (on previous line)";}}}s:8:"filelist";a:5:{s:19:"Mail/mimeDecode.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"05c45d0b58718ebe73860ebfe494dcef";s:4:"name";s:19:"Mail/mimeDecode.php";s:4:"role";s:3:"php";s:12:"installed_as";s:49:"/opt/alt/php56/usr/share/pear/Mail/mimeDecode.php";}s:29:"tests/parse_header_value.phpt";a:5:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"642acc06cdb217b6e64506182449d8f8";s:4:"name";s:29:"tests/parse_header_value.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:80:"/opt/alt/php56/usr/share/pear/test/Mail_mimeDecode/tests/parse_header_value.phpt";}s:41:"tests/semicolon_content_type_bug1724.phpt";a:5:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"a0bc0c9b68e62a19202bd8fb26104f3c";s:4:"name";s:41:"tests/semicolon_content_type_bug1724.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:92:"/opt/alt/php56/usr/share/pear/test/Mail_mimeDecode/tests/semicolon_content_type_bug1724.phpt";}s:9:"xmail.dtd";a:5:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"194810c478066eaeb28f51116b88e25a";s:4:"name";s:9:"xmail.dtd";s:4:"role";s:4:"data";s:12:"installed_as";s:60:"/opt/alt/php56/usr/share/pear/data/Mail_mimeDecode/xmail.dtd";}s:9:"xmail.xsl";a:5:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"61cea06fb6b4bd3a4b5e2d37384e14a9";s:4:"name";s:9:"xmail.xsl";s:4:"role";s:4:"data";s:12:"installed_as";s:60:"/opt/alt/php56/usr/share/pear/data/Mail_mimeDecode/xmail.xsl";}}s:12:"_lastversion";N;s:7:"dirtree";a:4:{s:34:"/opt/alt/php56/usr/share/pear/Mail";b:1;s:56:"/opt/alt/php56/usr/share/pear/test/Mail_mimeDecode/tests";b:1;s:50:"/opt/alt/php56/usr/share/pear/test/Mail_mimeDecode";b:1;s:50:"/opt/alt/php56/usr/share/pear/data/Mail_mimeDecode";b:1;}s:3:"old";a:7:{s:7:"version";s:5:"1.5.6";s:12:"release_date";s:10:"2016-08-29";s:13:"release_state";s:6:"stable";s:15:"release_license";s:9:"BSD Style";s:13:"release_notes";s:245:"Minor Bug fix release. #20431 - support for android #19762 - multipart signed not split correctly on line breaks #20027 - replace /e with preg_replace_callback #19762 - multipart/signed eating of new line, and expose sig_hdr etc.";s:12:"release_deps";a:3:{i:0;a:4:{s:4:"type";s:3:"php";s:3:"rel";s:2:"ge";s:7:"version";s:5:"4.3.0";s:8:"optional";s:2:"no";}i:1;a:6:{s:4:"type";s:3:"pkg";s:7:"channel";s:12:"pear.php.net";s:4:"name";s:4:"PEAR";s:3:"rel";s:2:"ge";s:7:"version";s:5:"1.6.0";s:8:"optional";s:2:"no";}i:2;a:6:{s:4:"type";s:3:"pkg";s:7:"channel";s:12:"pear.php.net";s:4:"name";s:9:"Mail_Mime";s:3:"rel";s:2:"gt";s:7:"version";s:5:"1.4.0";s:8:"optional";s:2:"no";}}s:11:"maintainers";a:3:{i:0;a:5:{s:4:"name";s:19:"Cipriano Groenendal";s:5:"email";s:13:"cipri@php.net";s:6:"active";s:3:"yes";s:6:"handle";s:5:"cipri";s:4:"role";s:4:"lead";}i:1;a:5:{s:4:"name";s:12:"Alan Knowles";s:5:"email";s:17:"alan@akbkhome.com";s:6:"active";s:3:"yes";s:6:"handle";s:6:"alan_k";s:4:"role";s:4:"lead";}i:2;a:5:{s:4:"name";s:19:"George Schlossnagle";s:5:"email";s:17:"george@omniti.com";s:6:"active";s:2:"no";s:6:"handle";s:13:"gschlossnagle";s:4:"role";s:9:"developer";}}}s:10:"xsdversion";s:3:"2.0";s:13:"_lastmodified";i:1669631553;}PK�����u]n`I��I����.registry/net_smtp.regnu�[��������a:21:{s:7:"attribs";a:6:{s:15:"packagerversion";s:7:"1.10.12";s:7:"version";s:3:"2.0";s:5:"xmlns";s:35:"http://pear.php.net/dtd/package-2.0";s:11:"xmlns:tasks";s:33:"http://pear.php.net/dtd/tasks-1.0";s:9:"xmlns:xsi";s:41:"http://www.w3.org/2001/XMLSchema-instance";s:18:"xsi:schemaLocation";s:147:"http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd";}s:4:"name";s:8:"Net_SMTP";s:7:"channel";s:12:"pear.php.net";s:7:"summary";s:38:"An implementation of the SMTP protocol";s:11:"description";s:78:"Provides an implementation of the SMTP protocol using PEAR's Net_Socket class.";s:4:"lead";a:2:{i:0;a:4:{s:4:"name";s:10:"Jon Parise";s:4:"user";s:3:"jon";s:5:"email";s:11:"jon@php.net";s:6:"active";s:3:"yes";}i:1;a:4:{s:4:"name";s:15:"Chuck Hagenbuch";s:4:"user";s:8:"chagenbu";s:5:"email";s:15:"chuck@horde.org";s:6:"active";s:3:"yes";}}s:4:"date";s:10:"2021-03-19";s:4:"time";s:8:"18:39:33";s:7:"version";a:2:{s:7:"release";s:6:"1.10.0";s:3:"api";s:5:"1.4.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:47:"https://opensource.org/licenses/bsd-license.php";}s:8:"_content";s:12:"BSD-2-Clause";}s:5:"notes";s:27:"* Add the starttls() method";s:8:"contents";a:1:{s:3:"dir";a:2:{s:7:"attribs";a:2:{s:14:"baseinstalldir";s:1:"/";s:4:"name";s:1:"/";}s:4:"file";a:8:{i:0;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"5ef820d1bc73898b55a153576953fe70";s:4:"name";s:18:"examples/basic.php";s:4:"role";s:3:"doc";}}i:1;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"0cd9a0c35d1ea17d46de9b5a39fb771d";s:4:"name";s:15:"tests/auth.phpt";s:4:"role";s:4:"test";}}i:2;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"89135826a107455d336071f3570ccd13";s:4:"name";s:16:"tests/basic.phpt";s:4:"role";s:4:"test";}}i:3;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"8517c458ae5094ee3c31a545d51c69c8";s:4:"name";s:21:"tests/config.php.dist";s:4:"role";s:4:"test";}}i:4;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"15c9cb4ef93e0aee232b503e12fc21ee";s:4:"name";s:20:"tests/quotedata.phpt";s:4:"role";s:4:"test";}}i:5;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"00f931f5dd61430e6057f895decdb6af";s:4:"name";s:7:"LICENSE";s:4:"role";s:3:"doc";}}i:6;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"9ddd7d9135cfe6e573cd757edf6855f2";s:4:"name";s:10:"README.rst";s:4:"role";s:3:"doc";}}i:7;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"a157897ae2efc43eabd961597557243a";s:4:"name";s:12:"Net/SMTP.php";s:4:"role";s:3:"php";}}}}}s:12:"dependencies";a:2:{s:8:"required";a:3:{s:3:"php";a:1:{s:3:"min";s:5:"5.4.0";}s:13:"pearinstaller";a:1:{s:3:"min";s:6:"1.10.1";}s:7:"package";a:3:{s:4:"name";s:10:"Net_Socket";s:7:"channel";s:12:"pear.php.net";s:3:"min";s:5:"1.0.7";}}s:8:"optional";a:1:{s:7:"package";a:3:{s:4:"name";s:9:"Auth_SASL";s:7:"channel";s:12:"pear.php.net";s:3:"min";s:5:"1.0.5";}}}s:10:"phprelease";s:0:"";s:8:"filelist";a:8:{s:18:"examples/basic.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"5ef820d1bc73898b55a153576953fe70";s:4:"name";s:18:"examples/basic.php";s:4:"role";s:3:"doc";s:12:"installed_as";s:61:"/opt/alt/php56/usr/share/doc/pear/Net_SMTP/examples/basic.php";}s:15:"tests/auth.phpt";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"0cd9a0c35d1ea17d46de9b5a39fb771d";s:4:"name";s:15:"tests/auth.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:59:"/opt/alt/php56/usr/share/pear/test/Net_SMTP/tests/auth.phpt";}s:16:"tests/basic.phpt";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"89135826a107455d336071f3570ccd13";s:4:"name";s:16:"tests/basic.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:60:"/opt/alt/php56/usr/share/pear/test/Net_SMTP/tests/basic.phpt";}s:21:"tests/config.php.dist";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"8517c458ae5094ee3c31a545d51c69c8";s:4:"name";s:21:"tests/config.php.dist";s:4:"role";s:4:"test";s:12:"installed_as";s:65:"/opt/alt/php56/usr/share/pear/test/Net_SMTP/tests/config.php.dist";}s:20:"tests/quotedata.phpt";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"15c9cb4ef93e0aee232b503e12fc21ee";s:4:"name";s:20:"tests/quotedata.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:64:"/opt/alt/php56/usr/share/pear/test/Net_SMTP/tests/quotedata.phpt";}s:7:"LICENSE";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"00f931f5dd61430e6057f895decdb6af";s:4:"name";s:7:"LICENSE";s:4:"role";s:3:"doc";s:12:"installed_as";s:50:"/opt/alt/php56/usr/share/doc/pear/Net_SMTP/LICENSE";}s:10:"README.rst";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"9ddd7d9135cfe6e573cd757edf6855f2";s:4:"name";s:10:"README.rst";s:4:"role";s:3:"doc";s:12:"installed_as";s:53:"/opt/alt/php56/usr/share/doc/pear/Net_SMTP/README.rst";}s:12:"Net/SMTP.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"a157897ae2efc43eabd961597557243a";s:4:"name";s:12:"Net/SMTP.php";s:4:"role";s:3:"php";s:12:"installed_as";s:42:"/opt/alt/php56/usr/share/pear/Net/SMTP.php";}}s:12:"_lastversion";N;s:7:"dirtree";a:5:{s:51:"/opt/alt/php56/usr/share/doc/pear/Net_SMTP/examples";b:1;s:42:"/opt/alt/php56/usr/share/doc/pear/Net_SMTP";b:1;s:49:"/opt/alt/php56/usr/share/pear/test/Net_SMTP/tests";b:1;s:43:"/opt/alt/php56/usr/share/pear/test/Net_SMTP";b:1;s:33:"/opt/alt/php56/usr/share/pear/Net";b:1;}s:3:"old";a:7:{s:7:"version";s:6:"1.10.0";s:12:"release_date";s:10:"2021-03-19";s:13:"release_state";s:6:"stable";s:15:"release_license";s:12:"BSD-2-Clause";s:13:"release_notes";s:27:"* Add the starttls() method";s:12:"release_deps";a:4:{i:0;a:4:{s:4:"type";s:3:"php";s:3:"rel";s:2:"ge";s:7:"version";s:5:"5.4.0";s:8:"optional";s:2:"no";}i:1;a:6:{s:4:"type";s:3:"pkg";s:7:"channel";s:12:"pear.php.net";s:4:"name";s:4:"PEAR";s:3:"rel";s:2:"ge";s:7:"version";s:6:"1.10.1";s:8:"optional";s:2:"no";}i:2;a:6:{s:4:"type";s:3:"pkg";s:7:"channel";s:12:"pear.php.net";s:4:"name";s:10:"Net_Socket";s:3:"rel";s:2:"ge";s:7:"version";s:5:"1.0.7";s:8:"optional";s:2:"no";}i:3;a:6:{s:4:"type";s:3:"pkg";s:7:"channel";s:12:"pear.php.net";s:4:"name";s:9:"Auth_SASL";s:3:"rel";s:2:"ge";s:7:"version";s:5:"1.0.5";s:8:"optional";s:3:"yes";}}s:11:"maintainers";a:2:{i:0;a:5:{s:4:"name";s:10:"Jon Parise";s:5:"email";s:11:"jon@php.net";s:6:"active";s:3:"yes";s:6:"handle";s:3:"jon";s:4:"role";s:4:"lead";}i:1;a:5:{s:4:"name";s:15:"Chuck Hagenbuch";s:5:"email";s:15:"chuck@horde.org";s:6:"active";s:3:"yes";s:6:"handle";s:8:"chagenbu";s:4:"role";s:4:"lead";}}}s:10:"xsdversion";s:3:"2.0";s:13:"_lastmodified";i:1669631553;}PK�����u]-P)��)����.registry/console_getopt.regnu�[��������a:25:{s:7:"attribs";a:6:{s:15:"packagerversion";s:7:"1.10.10";s:7:"version";s:3:"2.0";s:5:"xmlns";s:35:"http://pear.php.net/dtd/package-2.0";s:11:"xmlns:tasks";s:33:"http://pear.php.net/dtd/tasks-1.0";s:9:"xmlns:xsi";s:41:"http://www.w3.org/2001/XMLSchema-instance";s:18:"xsi:schemaLocation";s:147:"http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd";}s:4:"name";s:14:"Console_Getopt";s:7:"channel";s:12:"pear.php.net";s:7:"summary";s:26:"Command-line option parser";s:11:"description";s:80:"This is a PHP implementation of "getopt" supporting both short and long options.";s:4:"lead";a:4:{s:4:"name";s:15:"Andrei Zmievski";s:4:"user";s:6:"andrei";s:5:"email";s:14:"andrei@php.net";s:6:"active";s:2:"no";}s:9:"developer";a:4:{s:4:"name";s:11:"Stig Bakken";s:4:"user";s:3:"ssb";s:5:"email";s:12:"stig@php.net";s:6:"active";s:2:"no";}s:6:"helper";a:4:{s:4:"name";s:11:"Greg Beaver";s:4:"user";s:6:"cellog";s:5:"email";s:14:"cellog@php.net";s:6:"active";s:2:"no";}s:4:"date";s:10:"2019-11-20";s:4:"time";s:8:"18:27:07";s:7:"version";a:2:{s:7:"release";s:5:"1.4.3";s:3:"api";s:5:"1.4.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:46:"http://opensource.org/licenses/bsd-license.php";}s:8:"_content";s:12:"BSD-2-Clause";}s:5:"notes";s:98:"* PR #4: Fix PHP 7.4 deprecation: array/string curly braces access * PR #5: fix phplint warnings";s:8:"contents";a:1:{s:3:"dir";a:2:{s:7:"attribs";a:1:{s:4:"name";s:1:"/";}s:4:"file";a:5:{i:0;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"63da5909aa85a0eb76e0ad0b5e00811a";s:4:"name";s:18:"Console/Getopt.php";s:4:"role";s:3:"php";}}i:1;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"5a6fa63ce6f2370cdad11dc24a5addd0";s:4:"name";s:21:"tests/001-getopt.phpt";s:4:"role";s:4:"test";}}i:2;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"7540b630cb8e7bfd8bb06fb65a010ae9";s:4:"name";s:19:"tests/bug10557.phpt";s:4:"role";s:4:"test";}}i:3;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"e469de3628de85779118103b3248a44f";s:4:"name";s:19:"tests/bug11068.phpt";s:4:"role";s:4:"test";}}i:4;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"cdc108b084ad8e82eeb2417f04b49ec8";s:4:"name";s:19:"tests/bug13140.phpt";s:4:"role";s:4:"test";}}}}}s:10:"compatible";a:4:{s:4:"name";s:4:"PEAR";s:7:"channel";s:12:"pear.php.net";s:3:"min";s:5:"1.4.0";s:3:"max";s:9:"1.999.999";}s:12:"dependencies";a:1:{s:8:"required";a:2:{s:3:"php";a:1:{s:3:"min";s:5:"5.4.0";}s:13:"pearinstaller";a:1:{s:3:"min";s:5:"1.8.0";}}}s:10:"phprelease";s:0:"";s:9:"changelog";a:1:{s:7:"release";a:14:{i:0;a:5:{s:4:"date";s:10:"2019-11-20";s:7:"version";a:2:{s:7:"release";s:5:"1.4.3";s:3:"api";s:5:"1.4.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:46:"http://opensource.org/licenses/bsd-license.php";}s:8:"_content";s:12:"BSD-2-Clause";}s:5:"notes";s:98:"* PR #4: Fix PHP 7.4 deprecation: array/string curly braces access * PR #5: fix phplint warnings";}i:1;a:5:{s:4:"date";s:10:"2019-02-06";s:7:"version";a:2:{s:7:"release";s:5:"1.4.2";s:3:"api";s:5:"1.4.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:46:"http://opensource.org/licenses/bsd-license.php";}s:8:"_content";s:12:"BSD-2-Clause";}s:5:"notes";s:49:"* Remove use of each(), which is removed in PHP 8";}i:2;a:5:{s:4:"date";s:10:"2015-07-20";s:7:"version";a:2:{s:7:"release";s:5:"1.4.1";s:3:"api";s:5:"1.4.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:46:"http://opensource.org/licenses/bsd-license.php";}s:8:"_content";s:12:"BSD-2-Clause";}s:5:"notes";s:34:"* Fix unit test on PHP 7 [cweiske]";}i:3;a:5:{s:4:"date";s:10:"2015-02-22";s:7:"version";a:2:{s:7:"release";s:5:"1.4.0";s:3:"api";s:5:"1.4.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:46:"http://opensource.org/licenses/bsd-license.php";}s:8:"_content";s:12:"BSD-2-Clause";}s:5:"notes";s:111:"* Change license to BSD-2-Clause * Set minimum PHP version to 5.4.0 * Mark static methods with "static" keyword";}i:4;a:5:{s:4:"date";s:10:"2011-03-07";s:7:"version";a:2:{s:7:"release";s:5:"1.3.1";s:3:"api";s:5:"1.3.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:26:"http://www.php.net/license";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:51:"* Change the minimum PEAR installer dep to be lower";}i:5;a:6:{s:4:"date";s:10:"2010-12-11";s:4:"time";s:8:"20:20:13";s:7:"version";a:2:{s:7:"release";s:5:"1.3.0";s:3:"api";s:5:"1.3.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:26:"http://www.php.net/license";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:106:"* Implement Request #13140: [PATCH] to skip unknown parameters. [patch by rquadling, improved on by dufuz]";}i:6;a:5:{s:4:"date";s:10:"2007-06-12";s:7:"version";a:2:{s:7:"release";s:5:"1.2.3";s:3:"api";s:5:"1.2.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:26:"http://www.php.net/license";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:58:"* fix Bug #11068: No way to read plain "-" option [cardoe]";}i:7;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.2.2";s:3:"api";s:5:"1.2.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2007-02-17";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:26:"http://www.php.net/license";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:165:"* fix Bug #4475: An ambiguous error occurred when specifying similar longoption name. * fix Bug #10055: Not failing properly on short options missing required values";}i:8;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.2.1";s:3:"api";s:5:"1.2.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2006-12-08";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:26:"http://www.php.net/license";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:126:"Fixed bugs #4448 (Long parameter values truncated with longoption parameter) and #7444 (Trailing spaces after php closing tag)";}i:9;a:5:{s:7:"version";a:2:{s:7:"release";s:3:"1.2";s:3:"api";s:3:"1.2";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2003-12-11";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:26:"http://www.php.net/license";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:69:"Fix to preserve BC with 1.0 and allow correct behaviour for new users";}i:10;a:5:{s:7:"version";a:2:{s:7:"release";s:3:"1.0";s:3:"api";s:3:"1.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2002-09-13";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:26:"http://www.php.net/license";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:14:"Stable release";}i:11;a:5:{s:7:"version";a:2:{s:7:"release";s:4:"0.11";s:3:"api";s:4:"0.11";}s:9:"stability";a:2:{s:7:"release";s:4:"beta";s:3:"api";s:4:"beta";}s:4:"date";s:10:"2002-05-26";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:26:"http://www.php.net/license";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:89:"POSIX getopt compatibility fix: treat first element of args array as command name";}i:12;a:5:{s:7:"version";a:2:{s:7:"release";s:4:"0.10";s:3:"api";s:4:"0.10";}s:9:"stability";a:2:{s:7:"release";s:4:"beta";s:3:"api";s:4:"beta";}s:4:"date";s:10:"2002-05-12";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:26:"http://www.php.net/license";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:13:"Packaging fix";}i:13;a:5:{s:7:"version";a:2:{s:7:"release";s:3:"0.9";s:3:"api";s:3:"0.9";}s:9:"stability";a:2:{s:7:"release";s:4:"beta";s:3:"api";s:4:"beta";}s:4:"date";s:10:"2002-05-12";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:26:"http://www.php.net/license";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:15:"Initial release";}}}s:8:"filelist";a:5:{s:18:"Console/Getopt.php";a:4:{s:6:"md5sum";s:32:"63da5909aa85a0eb76e0ad0b5e00811a";s:4:"name";s:18:"Console/Getopt.php";s:4:"role";s:3:"php";s:12:"installed_as";s:48:"/opt/alt/php56/usr/share/pear/Console/Getopt.php";}s:21:"tests/001-getopt.phpt";a:4:{s:6:"md5sum";s:32:"5a6fa63ce6f2370cdad11dc24a5addd0";s:4:"name";s:21:"tests/001-getopt.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:71:"/opt/alt/php56/usr/share/pear/test/Console_Getopt/tests/001-getopt.phpt";}s:19:"tests/bug10557.phpt";a:4:{s:6:"md5sum";s:32:"7540b630cb8e7bfd8bb06fb65a010ae9";s:4:"name";s:19:"tests/bug10557.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:69:"/opt/alt/php56/usr/share/pear/test/Console_Getopt/tests/bug10557.phpt";}s:19:"tests/bug11068.phpt";a:4:{s:6:"md5sum";s:32:"e469de3628de85779118103b3248a44f";s:4:"name";s:19:"tests/bug11068.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:69:"/opt/alt/php56/usr/share/pear/test/Console_Getopt/tests/bug11068.phpt";}s:19:"tests/bug13140.phpt";a:4:{s:6:"md5sum";s:32:"cdc108b084ad8e82eeb2417f04b49ec8";s:4:"name";s:19:"tests/bug13140.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:69:"/opt/alt/php56/usr/share/pear/test/Console_Getopt/tests/bug13140.phpt";}}s:12:"_lastversion";N;s:7:"dirtree";a:3:{s:37:"/opt/alt/php56/usr/share/pear/Console";b:1;s:55:"/opt/alt/php56/usr/share/pear/test/Console_Getopt/tests";b:1;s:49:"/opt/alt/php56/usr/share/pear/test/Console_Getopt";b:1;}s:3:"old";a:7:{s:7:"version";s:5:"1.4.3";s:12:"release_date";s:10:"2019-11-20";s:13:"release_state";s:6:"stable";s:15:"release_license";s:12:"BSD-2-Clause";s:13:"release_notes";s:98:"* PR #4: Fix PHP 7.4 deprecation: array/string curly braces access * PR #5: fix phplint warnings";s:12:"release_deps";a:2:{i:0;a:4:{s:4:"type";s:3:"php";s:3:"rel";s:2:"ge";s:7:"version";s:5:"5.4.0";s:8:"optional";s:2:"no";}i:1;a:6:{s:4:"type";s:3:"pkg";s:7:"channel";s:12:"pear.php.net";s:4:"name";s:4:"PEAR";s:3:"rel";s:2:"ge";s:7:"version";s:5:"1.8.0";s:8:"optional";s:2:"no";}}s:11:"maintainers";a:3:{i:0;a:5:{s:4:"name";s:15:"Andrei Zmievski";s:5:"email";s:14:"andrei@php.net";s:6:"active";s:2:"no";s:6:"handle";s:6:"andrei";s:4:"role";s:4:"lead";}i:1;a:5:{s:4:"name";s:11:"Stig Bakken";s:5:"email";s:12:"stig@php.net";s:6:"active";s:2:"no";s:6:"handle";s:3:"ssb";s:4:"role";s:9:"developer";}i:2;a:5:{s:4:"name";s:11:"Greg Beaver";s:5:"email";s:14:"cellog@php.net";s:6:"active";s:2:"no";s:6:"handle";s:6:"cellog";s:4:"role";s:6:"helper";}}}s:10:"xsdversion";s:3:"2.0";s:13:"_lastmodified";i:1747068539;}PK�����u]8m|&��|&����.registry/auth_sasl.regnu�[��������a:22:{s:7:"attribs";a:6:{s:15:"packagerversion";s:6:"1.10.3";s:7:"version";s:3:"2.0";s:5:"xmlns";s:35:"http://pear.php.net/dtd/package-2.0";s:11:"xmlns:tasks";s:33:"http://pear.php.net/dtd/tasks-1.0";s:9:"xmlns:xsi";s:41:"http://www.w3.org/2001/XMLSchema-instance";s:18:"xsi:schemaLocation";s:153:"http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd";}s:4:"name";s:9:"Auth_SASL";s:7:"channel";s:12:"pear.php.net";s:7:"summary";s:47:"Abstraction of various SASL mechanism responses";s:11:"description";s:152:"Provides code to generate responses to common SASL mechanisms, including: - Digest-MD5 - Cram-MD5 - Plain - Anonymous - Login (Pseudo mechanism) - SCRAM";s:4:"lead";a:3:{i:0;a:4:{s:4:"name";s:12:"Anish Mistry";s:4:"user";s:7:"amistry";s:5:"email";s:26:"amistry@am-productions.biz";s:6:"active";s:2:"no";}i:1;a:4:{s:4:"name";s:13:"Richard Heyes";s:4:"user";s:7:"richard";s:5:"email";s:15:"richard@php.net";s:6:"active";s:2:"no";}i:2;a:4:{s:4:"name";s:22:"Michael Bretterklieber";s:4:"user";s:8:"mbretter";s:5:"email";s:26:"michael@bretterklieber.com";s:6:"active";s:2:"no";}}s:4:"date";s:10:"2017-03-07";s:4:"time";s:8:"14:04:34";s:7:"version";a:2:{s:7:"release";s:5:"1.1.0";s:3:"api";s:5:"1.1.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:3:"BSD";}s:5:"notes";s:114:"* Set minimum PHP version to 5.4.0 * Set minimum PEAR version to 1.10.1 * Request #21033: PHP warning depreciated";s:8:"contents";a:1:{s:3:"dir";a:2:{s:7:"attribs";a:1:{s:4:"name";s:1:"/";}s:4:"file";a:9:{i:0;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"60f7b5ba4d05fe0e518292963b14bddb";s:4:"name";s:23:"Auth/SASL/Anonymous.php";s:4:"role";s:3:"php";}}i:1;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"c2c817e4775b6f63f07ddb0c9cbd88b5";s:4:"name";s:20:"Auth/SASL/Common.php";s:4:"role";s:3:"php";}}i:2;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"c6b3b3a4e0aec6a4e0728732ef6babc9";s:4:"name";s:21:"Auth/SASL/CramMD5.php";s:4:"role";s:3:"php";}}i:3;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"509e431141489a77a991401d64f15e9e";s:4:"name";s:23:"Auth/SASL/DigestMD5.php";s:4:"role";s:3:"php";}}i:4;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"1d7478dd9dc5734ec9e16c158dcb6f76";s:4:"name";s:22:"Auth/SASL/External.php";s:4:"role";s:3:"php";}}i:5;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"3a0abcf277374b24262807150451b55e";s:4:"name";s:19:"Auth/SASL/Login.php";s:4:"role";s:3:"php";}}i:6;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"bde1dcf2780d042c1de12e20a696e945";s:4:"name";s:19:"Auth/SASL/Plain.php";s:4:"role";s:3:"php";}}i:7;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"e99f9f71abc36d64ca8e17ad6e5e7631";s:4:"name";s:19:"Auth/SASL/SCRAM.php";s:4:"role";s:3:"php";}}i:8;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"b93e37947e1dd90e5fb639a1734f7a71";s:4:"name";s:13:"Auth/SASL.php";s:4:"role";s:3:"php";}}}}}s:12:"dependencies";a:1:{s:8:"required";a:2:{s:3:"php";a:1:{s:3:"min";s:5:"5.4.0";}s:13:"pearinstaller";a:1:{s:3:"min";s:6:"1.10.1";}}}s:10:"phprelease";s:0:"";s:9:"changelog";a:1:{s:7:"release";a:7:{i:0;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.1.0";s:3:"api";s:5:"1.1.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2017-03-07";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:3:"BSD";}s:5:"notes";s:114:"* Set minimum PHP version to 5.4.0 * Set minimum PEAR version to 1.10.1 * Request #21033: PHP warning depreciated";}i:1;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.0.6";s:3:"api";s:5:"1.0.3";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2011-09-27";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:3:"BSD";}s:5:"notes";s:102:"QA release * Bug #18856: Authentication warnings because of wrong Auth_SASL::factory argument [kguest]";}i:2;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.0.5";s:3:"api";s:5:"1.0.3";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2011-09-04";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:3:"BSD";}s:5:"notes";s:256:"QA release * Added support for any mechanism of the SCRAM family; with thanks to Jehan Pagès. [kguest] * crammd5 and digestmd5 mechanisms name deprecated in favour of IANA registered names 'cram-md5' and 'digest-md5'; with thanks to Jehan Pagès. [kguest]";}i:3;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.0.4";s:3:"api";s:5:"1.0.3";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2010-02-07";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:3:"BSD";}s:5:"notes";s:85:"QA release * Fix bug #16624: open_basedir restriction warning in DigestMD5.php [till]";}i:4;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.0.3";s:3:"api";s:5:"1.0.3";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2009-08-05";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:3:"BSD";}s:5:"notes";s:181:"QA release * Move SVN to proper directory structure [cweiske] * Fix Bug #8775: Error in package.xml * Fix Bug #14671: Security issue due to seeding random number generator [cweiske]";}i:5;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.0.2";s:3:"api";s:5:"1.0.2";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2006-05-21";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:3:"BSD";}s:5:"notes";s:179:"* Fixed Bug #2143 Auth_SASL_DigestMD5::getResponse() generates invalid response * Fixed Bug #6611 Suppress PHP 5 Notice Errors * Fixed Bug #2154 realm isn't contained in challange";}i:6;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.0.1";s:3:"api";s:5:"1.0.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2003-09-11";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:3:"BSD";}s:5:"notes";s:59:"* Added authcid/authzid separation in PLAIN and DIGEST-MD5.";}}}s:8:"filelist";a:9:{s:23:"Auth/SASL/Anonymous.php";a:4:{s:6:"md5sum";s:32:"60f7b5ba4d05fe0e518292963b14bddb";s:4:"name";s:23:"Auth/SASL/Anonymous.php";s:4:"role";s:3:"php";s:12:"installed_as";s:53:"/opt/alt/php56/usr/share/pear/Auth/SASL/Anonymous.php";}s:20:"Auth/SASL/Common.php";a:4:{s:6:"md5sum";s:32:"c2c817e4775b6f63f07ddb0c9cbd88b5";s:4:"name";s:20:"Auth/SASL/Common.php";s:4:"role";s:3:"php";s:12:"installed_as";s:50:"/opt/alt/php56/usr/share/pear/Auth/SASL/Common.php";}s:21:"Auth/SASL/CramMD5.php";a:4:{s:6:"md5sum";s:32:"c6b3b3a4e0aec6a4e0728732ef6babc9";s:4:"name";s:21:"Auth/SASL/CramMD5.php";s:4:"role";s:3:"php";s:12:"installed_as";s:51:"/opt/alt/php56/usr/share/pear/Auth/SASL/CramMD5.php";}s:23:"Auth/SASL/DigestMD5.php";a:4:{s:6:"md5sum";s:32:"509e431141489a77a991401d64f15e9e";s:4:"name";s:23:"Auth/SASL/DigestMD5.php";s:4:"role";s:3:"php";s:12:"installed_as";s:53:"/opt/alt/php56/usr/share/pear/Auth/SASL/DigestMD5.php";}s:22:"Auth/SASL/External.php";a:4:{s:6:"md5sum";s:32:"1d7478dd9dc5734ec9e16c158dcb6f76";s:4:"name";s:22:"Auth/SASL/External.php";s:4:"role";s:3:"php";s:12:"installed_as";s:52:"/opt/alt/php56/usr/share/pear/Auth/SASL/External.php";}s:19:"Auth/SASL/Login.php";a:4:{s:6:"md5sum";s:32:"3a0abcf277374b24262807150451b55e";s:4:"name";s:19:"Auth/SASL/Login.php";s:4:"role";s:3:"php";s:12:"installed_as";s:49:"/opt/alt/php56/usr/share/pear/Auth/SASL/Login.php";}s:19:"Auth/SASL/Plain.php";a:4:{s:6:"md5sum";s:32:"bde1dcf2780d042c1de12e20a696e945";s:4:"name";s:19:"Auth/SASL/Plain.php";s:4:"role";s:3:"php";s:12:"installed_as";s:49:"/opt/alt/php56/usr/share/pear/Auth/SASL/Plain.php";}s:19:"Auth/SASL/SCRAM.php";a:4:{s:6:"md5sum";s:32:"e99f9f71abc36d64ca8e17ad6e5e7631";s:4:"name";s:19:"Auth/SASL/SCRAM.php";s:4:"role";s:3:"php";s:12:"installed_as";s:49:"/opt/alt/php56/usr/share/pear/Auth/SASL/SCRAM.php";}s:13:"Auth/SASL.php";a:4:{s:6:"md5sum";s:32:"b93e37947e1dd90e5fb639a1734f7a71";s:4:"name";s:13:"Auth/SASL.php";s:4:"role";s:3:"php";s:12:"installed_as";s:43:"/opt/alt/php56/usr/share/pear/Auth/SASL.php";}}s:12:"_lastversion";N;s:7:"dirtree";a:2:{s:39:"/opt/alt/php56/usr/share/pear/Auth/SASL";b:1;s:34:"/opt/alt/php56/usr/share/pear/Auth";b:1;}s:3:"old";a:7:{s:7:"version";s:5:"1.1.0";s:12:"release_date";s:10:"2017-03-07";s:13:"release_state";s:6:"stable";s:15:"release_license";s:3:"BSD";s:13:"release_notes";s:114:"* Set minimum PHP version to 5.4.0 * Set minimum PEAR version to 1.10.1 * Request #21033: PHP warning depreciated";s:12:"release_deps";a:2:{i:0;a:4:{s:4:"type";s:3:"php";s:3:"rel";s:2:"ge";s:7:"version";s:5:"5.4.0";s:8:"optional";s:2:"no";}i:1;a:6:{s:4:"type";s:3:"pkg";s:7:"channel";s:12:"pear.php.net";s:4:"name";s:4:"PEAR";s:3:"rel";s:2:"ge";s:7:"version";s:6:"1.10.1";s:8:"optional";s:2:"no";}}s:11:"maintainers";a:3:{i:0;a:5:{s:4:"name";s:12:"Anish Mistry";s:5:"email";s:26:"amistry@am-productions.biz";s:6:"active";s:2:"no";s:6:"handle";s:7:"amistry";s:4:"role";s:4:"lead";}i:1;a:5:{s:4:"name";s:13:"Richard Heyes";s:5:"email";s:15:"richard@php.net";s:6:"active";s:2:"no";s:6:"handle";s:7:"richard";s:4:"role";s:4:"lead";}i:2;a:5:{s:4:"name";s:22:"Michael Bretterklieber";s:5:"email";s:26:"michael@bretterklieber.com";s:6:"active";s:2:"no";s:6:"handle";s:8:"mbretter";s:4:"role";s:4:"lead";}}}s:10:"xsdversion";s:3:"2.0";s:13:"_lastmodified";i:1669631553;}PK�����u]r}.��.����.registry/mail_mime.regnu�[��������a:22:{s:7:"attribs";a:6:{s:15:"packagerversion";s:7:"1.10.12";s:7:"version";s:3:"2.0";s:5:"xmlns";s:35:"http://pear.php.net/dtd/package-2.0";s:11:"xmlns:tasks";s:33:"http://pear.php.net/dtd/tasks-1.0";s:9:"xmlns:xsi";s:41:"http://www.w3.org/2001/XMLSchema-instance";s:18:"xsi:schemaLocation";s:159:"http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd";}s:4:"name";s:9:"Mail_Mime";s:7:"channel";s:12:"pear.php.net";s:7:"summary";s:51:"Mail_Mime provides classes to create MIME messages.";s:11:"description";s:395:"Mail_Mime provides classes to deal with the creation and manipulation of MIME messages. It allows people to create e-mail messages consisting of: * Text Parts * HTML Parts * Inline HTML Images * Attachments * Attached messages It supports big messages, base64 and quoted-printable encodings and non-ASCII characters in filenames, subjects, recipients, etc. encoded using RFC2047 and/or RFC2231.";s:4:"lead";a:2:{i:0;a:4:{s:4:"name";s:19:"Cipriano Groenendal";s:4:"user";s:5:"cipri";s:5:"email";s:13:"cipri@php.net";s:6:"active";s:2:"no";}i:1;a:4:{s:4:"name";s:19:"Aleksander Machniak";s:4:"user";s:4:"alec";s:5:"email";s:12:"alec@php.net";s:6:"active";s:3:"yes";}}s:4:"date";s:10:"2021-09-05";s:4:"time";s:8:"08:43:21";s:7:"version";a:2:{s:7:"release";s:7:"1.10.11";s:3:"api";s:6:"1.10.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:9:"BSD Style";}s:5:"notes";s:246:"* Fix PHP 8.1: strlen(): Passing null to parameter #1 ($string) of type string is deprecated [alec] * Fix encoding recipient names with @ character and no space between name and address [alec] * Fix the license label in composer.json [jnkowa-gfk]";s:8:"contents";a:1:{s:3:"dir";a:2:{s:7:"attribs";a:1:{s:4:"name";s:1:"/";}s:4:"file";a:53:{i:0;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"edd138f6c5497ae2b5d63620a67a931e";s:4:"name";s:25:"tests/class-filename.phpt";s:4:"role";s:4:"test";}}i:1;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"7ec986391d0af058316f66e5a507e059";s:4:"name";s:36:"tests/content_transfer_encoding.phpt";s:4:"role";s:4:"test";}}i:2;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"c1a43360d9b2cb5f9542503a4355c277";s:4:"name";s:24:"tests/encoding_case.phpt";s:4:"role";s:4:"test";}}i:3;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"bf50a200190cad5e2d4aae4e120ea09f";s:4:"name";s:32:"tests/headers_with_mbstring.phpt";s:4:"role";s:4:"test";}}i:4;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"9a2d207f873317125ff43c092f3f0d25";s:4:"name";s:35:"tests/headers_without_mbstring.phpt";s:4:"role";s:4:"test";}}i:5;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"25d4c5b9fdeaabc7810c26e6f89e95ca";s:4:"name";s:27:"tests/qp_encoding_test.phpt";s:4:"role";s:4:"test";}}i:6;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"958197f31b4a20c91dd42662595e7516";s:4:"name";s:41:"tests/sleep_wakeup_EOL-bug3488-part1.phpt";s:4:"role";s:4:"test";}}i:7;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"46675529f1f021b51a1aa0ae6c971cd2";s:4:"name";s:41:"tests/sleep_wakeup_EOL-bug3488-part2.phpt";s:4:"role";s:4:"test";}}i:8;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"f8c05910737e451c7a9d4737b8d9f095";s:4:"name";s:26:"tests/test_Bug_3513_1.phpt";s:4:"role";s:4:"test";}}i:9;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"edb467a375ddf09e777a9388e2e8cbb5";s:4:"name";s:26:"tests/test_Bug_3513_2.phpt";s:4:"role";s:4:"test";}}i:10;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"70c2456445eaaa80779206e9e245d685";s:4:"name";s:26:"tests/test_Bug_3513_3.phpt";s:4:"role";s:4:"test";}}i:11;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"4cda500d0d7925e81a299f1d3db132a9";s:4:"name";s:26:"tests/test_Bug_7561_1.phpt";s:4:"role";s:4:"test";}}i:12;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"42a214e7e3d3afa07f8996b235222611";s:4:"name";s:26:"tests/test_Bug_8386_1.phpt";s:4:"role";s:4:"test";}}i:13;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"ed78099563499f60386a128cb7b96925";s:4:"name";s:26:"tests/test_Bug_8541_1.phpt";s:4:"role";s:4:"test";}}i:14;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"5250a0693599b945e8642a1a289d7275";s:4:"name";s:26:"tests/test_Bug_9722_1.phpt";s:4:"role";s:4:"test";}}i:15;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"b7f58f54e1485c23a60c83cd3cc5563e";s:4:"name";s:27:"tests/test_Bug_10596_1.phpt";s:4:"role";s:4:"test";}}i:16;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"ccb53d80e7f5c9f28b11abce5fe5d490";s:4:"name";s:27:"tests/test_Bug_10816_1.phpt";s:4:"role";s:4:"test";}}i:17;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"f3d92a1fff099173b8600fb3646d0614";s:4:"name";s:27:"tests/test_Bug_10999_1.phpt";s:4:"role";s:4:"test";}}i:18;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"3f2757d5db43abd8f177f094f4d53625";s:4:"name";s:25:"tests/test_Bug_11381.phpt";s:4:"role";s:4:"test";}}i:19;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"c64d675e73bc02fc94f5d03b3117cfa0";s:4:"name";s:25:"tests/test_Bug_11731.phpt";s:4:"role";s:4:"test";}}i:20;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"8c9305ca05f5ed2d7cd7e31e4836f17a";s:4:"name";s:25:"tests/test_Bug_12165.phpt";s:4:"role";s:4:"test";}}i:21;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"2aa2c3dfbe44500809e79da994272611";s:4:"name";s:27:"tests/test_Bug_12385_1.phpt";s:4:"role";s:4:"test";}}i:22;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"ef1d726233dbd3360c540fd6a959b0d0";s:4:"name";s:25:"tests/test_Bug_12411.phpt";s:4:"role";s:4:"test";}}i:23;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"a862a57ff622fcbb2328be6c805e2d05";s:4:"name";s:25:"tests/test_Bug_12466.phpt";s:4:"role";s:4:"test";}}i:24;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"4eddeeac08f351feb147ab6fda439526";s:4:"name";s:25:"tests/test_Bug_13032.phpt";s:4:"role";s:4:"test";}}i:25;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"de15a0657a83694bc6991c4184ccf9bd";s:4:"name";s:25:"tests/test_Bug_13444.phpt";s:4:"role";s:4:"test";}}i:26;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"80afe9fced03288884e9d302d1e65b2d";s:4:"name";s:25:"tests/test_Bug_13962.phpt";s:4:"role";s:4:"test";}}i:27;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"89bf87e798f4a149a150d4c2a505f976";s:4:"name";s:25:"tests/test_Bug_14529.phpt";s:4:"role";s:4:"test";}}i:28;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"5f9100adb1c609110ed495fafa819975";s:4:"name";s:25:"tests/test_Bug_14779.phpt";s:4:"role";s:4:"test";}}i:29;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"45eb42fe4e325da64f1ae8f149e2a396";s:4:"name";s:25:"tests/test_Bug_14780.phpt";s:4:"role";s:4:"test";}}i:30;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"609dad2083c54ba56ea691c488ca20e2";s:4:"name";s:25:"tests/test_Bug_15320.phpt";s:4:"role";s:4:"test";}}i:31;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"f4ef08e416e775558e8075b531bbc814";s:4:"name";s:25:"tests/test_Bug_16539.phpt";s:4:"role";s:4:"test";}}i:32;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"ed1bd0fc9067b3fb8b95808bfa315916";s:4:"name";s:25:"tests/test_Bug_17025.phpt";s:4:"role";s:4:"test";}}i:33;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"8a37de74fb39fed4566617a7ea38bb69";s:4:"name";s:25:"tests/test_Bug_17175.phpt";s:4:"role";s:4:"test";}}i:34;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"b9dee3c7c45d8c6c22f860e93c3769b9";s:4:"name";s:25:"tests/test_Bug_18083.phpt";s:4:"role";s:4:"test";}}i:35;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"96ce23ad1a1d6417facfcdd2baa9c8eb";s:4:"name";s:25:"tests/test_Bug_18772.phpt";s:4:"role";s:4:"test";}}i:36;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"dd98307b3224b173f7b54f7e403865a4";s:4:"name";s:25:"tests/test_Bug_19497.phpt";s:4:"role";s:4:"test";}}i:37;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"e1194180cb6a218fab69db90f88d1cb2";s:4:"name";s:25:"tests/test_Bug_20226.phpt";s:4:"role";s:4:"test";}}i:38;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"1b7919174edcd1cf5d5fd5a622fdac9b";s:4:"name";s:25:"tests/test_Bug_20273.phpt";s:4:"role";s:4:"test";}}i:39;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"6513c4b0c9e962c900d020124752333e";s:4:"name";s:25:"tests/test_Bug_20563.phpt";s:4:"role";s:4:"test";}}i:40;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"7c7a00818cb0f01fa6c52c920b9e76c6";s:4:"name";s:25:"tests/test_Bug_20564.phpt";s:4:"role";s:4:"test";}}i:41;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"b9e31a9c24b05dfb6166512e04e2f056";s:4:"name";s:25:"tests/test_Bug_21027.phpt";s:4:"role";s:4:"test";}}i:42;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"b634a5e99aa26a8b6df8fcfae07051b4";s:4:"name";s:25:"tests/test_Bug_21098.phpt";s:4:"role";s:4:"test";}}i:43;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"b21be5b099a69428bd37e60589cdd485";s:4:"name";s:25:"tests/test_Bug_21205.phpt";s:4:"role";s:4:"test";}}i:44;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"bc152c12839964fba15da5673d25c4db";s:4:"name";s:25:"tests/test_Bug_21206.phpt";s:4:"role";s:4:"test";}}i:45;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"ccf732525be42c955eea18e78490c3e1";s:4:"name";s:25:"tests/test_Bug_21255.phpt";s:4:"role";s:4:"test";}}i:46;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"579f1e11da6c8074dbf508dc1f1dedfa";s:4:"name";s:24:"tests/test_Bug_GH16.phpt";s:4:"role";s:4:"test";}}i:47;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"df32d66d9fccf7a0956422811283272a";s:4:"name";s:24:"tests/test_Bug_GH19.phpt";s:4:"role";s:4:"test";}}i:48;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"b7b5b5bacc6a599cfaece35ad202ad1a";s:4:"name";s:24:"tests/test_Bug_GH26.phpt";s:4:"role";s:4:"test";}}i:49;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"e08958f1bb60561f072a3508b8fd3e2e";s:4:"name";s:29:"tests/test_linebreak_dot.phpt";s:4:"role";s:4:"test";}}i:50;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"8398e9bfea0bc7c4ff0770ae3d6279fe";s:4:"name";s:35:"tests/test_linebreak_larger_76.phpt";s:4:"role";s:4:"test";}}i:51;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"e5c9ac7f32e53afdeafd1a84343a89ae";s:4:"name";s:13:"Mail/mime.php";s:4:"role";s:3:"php";}}i:52;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"36128789ad1101d39d13b06ca2585576";s:4:"name";s:17:"Mail/mimePart.php";s:4:"role";s:3:"php";}}}}}s:12:"dependencies";a:1:{s:8:"required";a:2:{s:3:"php";a:1:{s:3:"min";s:5:"5.2.0";}s:13:"pearinstaller";a:1:{s:3:"min";s:5:"1.6.0";}}}s:10:"phprelease";s:0:"";s:9:"changelog";a:1:{s:7:"release";a:48:{i:0;a:5:{s:7:"version";a:2:{s:7:"release";s:3:"1.0";s:3:"api";s:3:"1.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2001-12-28";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:26:"http://www.php.net/license";}s:8:"_content";s:3:"PHP";}s:5:"notes";s:53:"This is the initial release of the Mime_Mail package.";}i:1;a:5:{s:7:"version";a:2:{s:7:"release";s:3:"1.1";s:3:"api";s:3:"1.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2002-04-03";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:26:"http://www.php.net/license";}s:8:"_content";s:3:"PHP";}s:5:"notes";s:75:"This is a maintenance release with various bugfixes and minor enhancements.";}i:2;a:5:{s:7:"version";a:2:{s:7:"release";s:3:"1.2";s:3:"api";s:3:"1.2";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2002-07-14";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:26:"http://www.php.net/license";}s:8:"_content";s:3:"PHP";}s:5:"notes";s:180:"* Added header encoding * Altered mimePart to put boundary parameter on newline * Changed addFrom() to setFrom() * Added setSubject() * Made mimePart inherit crlf setting from mime";}i:3;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.2.1";s:3:"api";s:5:"1.2.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2002-07-27";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:26:"http://www.php.net/license";}s:8:"_content";s:3:"PHP";}s:5:"notes";s:62:"* License change * Applied a few changes From Ilia Alshanetsky";}i:4;a:5:{s:7:"version";a:2:{s:7:"release";s:8:"1.3.0RC1";s:3:"api";s:8:"1.3.0RC1";}s:9:"stability";a:2:{s:7:"release";s:4:"beta";s:3:"api";s:4:"beta";}s:4:"date";s:10:"2005-03-20";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:26:"http://www.php.net/license";}s:8:"_content";s:3:"PHP";}s:5:"notes";s:94:"* First release in over 2.5 years (!) * MANY bugfixes (see the bugtracker) * added a few tests";}i:5;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.3.0";s:3:"api";s:5:"1.3.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2005-04-01";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:26:"http://www.php.net/license";}s:8:"_content";s:3:"PHP";}s:5:"notes";s:141:"* First (stable) release in over 2.5 years (!) * MANY bugfixes (see the bugtracker) * added a few tests * one small fix after RC1 (bug #3940)";}i:6;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.3.1";s:3:"api";s:5:"1.3.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2005-07-13";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:26:"http://www.php.net/license";}s:8:"_content";s:3:"PHP";}s:5:"notes";s:0:"";}i:7;a:5:{s:7:"version";a:2:{s:7:"release";s:7:"1.4.0a1";s:3:"api";s:5:"1.3.1";}s:9:"stability";a:2:{s:7:"release";s:5:"alpha";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2007-03-08";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:9:"bsd style";}s:5:"notes";s:1481:"* Changed License to BSD Style license, as that's what the code was since the beginning [cipri] * Fix Bug #30: Mail_Mime: _encodeHeaders is not RFC-2047 compliant. [cipri] * Fix Bug #3513: support of RFC2231 in header fields. [cipri] * Fix Bug #4696: addAttachment crash [cipri] * Fix Bug #5333: Only variables should be returned by reference; triggers notices since php 4.4.0 [cipri] * Fix Bug #7561: Mail_mimePart::_quotedPrintableEncode() misbehavior with mbstring overload [cipri] * Fix Bug #8223: Incorrectly encoded quoted-printable headers [cipri] * Fix Bug #8386: HTML body not correctly encoded if attachments present [cipri] * Fix Bug #8541: mimePart.php line delimiter is \r [cipri] * Fix Bug #9347: Notices about references [cweiske] * Fix Bug #9558: Broken multiline headers [cipri] * Fix Bug #9956: Notices being thrown [cipri] * Fix Bug #9976: Subject encoded twice [cipri] * Implement Feature #2952: Mail_mime::headers() saves extra headers [cipri] * Implement Feature #3636: Allow specification of charsets and encoding [cipri] * Implement Feature #4057: Mail_Mime: Add name parameter for Content-Type [cipri] * Implement Feature #4504: addHTMLImage does not work in cases when filename contains a path [cipri] * Implement Feature #5837: Mail_Mime: Build message for Net_SMTP [cipri] * Implement Feature #5934: Mail_Mime: choice for content disposition [cipri] * Implement Feature #6568: Mail_Mime: inline images referenced in CSS definitions not replaced. [cipri]";}i:8;a:5:{s:7:"version";a:2:{s:7:"release";s:7:"1.4.0a2";s:3:"api";s:5:"1.3.1";}s:9:"stability";a:2:{s:7:"release";s:5:"alpha";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2007-04-05";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:9:"bsd style";}s:5:"notes";s:553:"* Fix Bug #9722: _quotedPrintableEncode does not encode dot at start of line on Windows platform [cipri] * Fix Bug #9725: multipart/related & alternative wrong order [cipri] * Fix Bug #10146: mbstring fails to recognize encodings. [cipri] * Fix Bug #10158: Inline images not displayed on Mozilla Thunderbird [cipri] * Fix Bug #10298: Mail_mime, double Quotes and Specialchars in from and to Adress [cipri] * Fix Bug #10306: Strings with Double Quotes get encoded wrongly [cipri] * Fix Bug #10596: Incorrect handling of text and html '0' bodies [cipri]";}i:9;a:5:{s:7:"version";a:2:{s:7:"release";s:7:"1.4.0a3";s:3:"api";s:5:"1.3.1";}s:9:"stability";a:2:{s:7:"release";s:5:"alpha";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2007-04-05";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:9:"bsd style";}s:5:"notes";s:162:"* Fix Bug #10298: Mail_mime, double Quotes and Specialchars in from and to Adress [cipri] * Fix Bug #10306: Strings with Double Quotes get encoded wrongly [cipri]";}i:10;a:5:{s:7:"version";a:2:{s:7:"release";s:8:"1.4.0RC1";s:3:"api";s:5:"1.3.1";}s:9:"stability";a:2:{s:7:"release";s:4:"beta";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2007-04-12";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:9:"bsd style";}s:5:"notes";s:75:"* Fix Bug #10232: Gmail creates double line break when \r\n is used [cipri]";}i:11;a:5:{s:7:"version";a:2:{s:7:"release";s:8:"1.4.0RC2";s:3:"api";s:5:"1.3.1";}s:9:"stability";a:2:{s:7:"release";s:4:"beta";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2007-04-22";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:9:"bsd style";}s:5:"notes";s:187:"* Fix Bug #10791: Unit tests fail [cipri] * Fix Bug #10792: No unit tests for recently fixed bugs [cipri] * Fix Bug #10793: Long headers don't get wrapped since fix for Bug #10298 [cipri]";}i:12;a:5:{s:7:"version";a:2:{s:7:"release";s:8:"1.4.0RC3";s:3:"api";s:5:"1.3.1";}s:9:"stability";a:2:{s:7:"release";s:4:"beta";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2007-04-24";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:9:"bsd style";}s:5:"notes";s:65:"* Fix Bug #10816: Unwanted linebreak at the end of output [cipri]";}i:13;a:5:{s:7:"version";a:2:{s:7:"release";s:8:"1.4.0RC4";s:3:"api";s:5:"1.3.1";}s:9:"stability";a:2:{s:7:"release";s:4:"beta";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2007-04-28";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:9:"bsd style";}s:5:"notes";s:123:"* Fix Bug #3513: support of RFC2231 in header fields. [cipri] * Fix Bug #10838: bad use of MIME encoding in header. [cipri]";}i:14;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.4.0";s:3:"api";s:5:"1.3.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2007-05-05";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:9:"BSD Style";}s:5:"notes";s:3343:"Release notes: * No more notices in PHP 5 /4.4.0. * Improved inline HTML image function. * Improved header encoding with foreign charsets. * Improved long header rendering. * More control over used Charsets and encoding schemes. * More configurable attachments and inline images. * Full RFC 2047 Support * Full RFC 2231 Support * Unit-tests Fixed bugs: * Fix Bug #30: Mail_Mime: _encodeHeaders is not RFC-2047 compliant. [cipri] * Fix Bug #3513: support of RFC2231 in header fields. [cipri] * Fix Bug #4696: addAttachment crash [cipri] * Fix Bug #5333: Only variables should be returned by reference; triggers notices since php 4.4.0 [cipri] * Fix Bug #5400: Do not return function reference [cipri] * Fix Bug #5710: Little reference bugs [cipri] * Fix Bug #5890: Only variable references should be returned by reference [cipri] * Fix Bug #6260: Just a notice with PHP5 [cipri] * Fix Bug #6261: php 5.1.1 upgrade [cipri] * Fix Bug #6663: Notice about reference passing [cipri] * Fix Bug #7561: Mail_mimePart::_quotedPrintableEncode() misbehavior with mbstring overload [cipri] * Fix Bug #7713: PHP5 Notice: Only variable references should be returned by reference [cipri] * Fix Bug #8223: Incorrectly encoded quoted-printable headers [cipri] * Fix Bug #8386: HTML body not correctly encoded if attachments present [cipri] * Fix Bug #8541: mimePart.php line delimiter is \r [cipri] * Fix Bug #8812: user header updates overwritten [cipri] * Fix Bug #9347: Notices about references [cweiske] * Fix Bug #9558: Broken multiline headers [cipri] * Fix Bug #9722: _quotedPrintableEncode does not encode dot at start of line on Windows platform [cipri] * Fix Bug #9725: multipart/related & alternative wrong order [cipri] * Fix Bug #9956: Notices being thrown [cipri] * Fix Bug #9976: Subject encoded twice [cipri] * Fix Bug #10146: mbstring fails to recognize encodings. [cipri] * Fix Bug #10158: Inline images not displayed on Mozilla Thunderbird [cipri] * Fix Bug #10232: Gmail creates double line break when \r\n is used [cipri] * Fix Bug #10298: Mail_mime, double Quotes and Specialchars in from and to Adress [cipri] * Fix Bug #10306: Strings with Double Quotes get encoded wrongly [cipri] * Fix Bug #10596: Incorrect handling of text and html '0' bodies [cipri] * Fix Bug #10791: Unit tests fail [cipri] * Fix Bug #10792: No unit tests for recently fixed bugs [cipri] * Fix Bug #10793: Long headers don't get wrapped since fix for Bug #10298 [cipri] * Fix Bug #10816: Unwanted linebreak at the end of output [cipri] * Fix Bug #10838: bad use of MIME encoding in header. [cipri] Implemented Features: * Implement Feature #2952: Mail_mime::headers() saves extra headers [cipri] * Implement Feature #3636: Allow specification of charsets and encoding [cipri] * Implement Feature #4057: Mail_Mime: Add name parameter for Content-Type [cipri] * Implement Feature #4504: addHTMLImage does not work in cases when filename contains a path [cipri] * Implement Feature #5837: Mail_Mime: Build message for Net_SMTP [cipri] * Implement Feature #5934: Mail_Mime: choice for content disposition [cipri] * Implement Feature #6568: Mail_Mime: inline images referenced in CSS definitions not replaced. [cipri] * Implement Feature #10604: Put an option to specify Content-Location in the header [cipri]";}i:15;a:5:{s:7:"version";a:2:{s:7:"release";s:7:"1.5.0a1";s:3:"api";s:5:"1.3.1";}s:9:"stability";a:2:{s:7:"release";s:5:"alpha";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2007-06-10";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:9:"BSD Style";}s:5:"notes";s:25:"Split off mail_MimeDecode";}i:16;a:5:{s:7:"version";a:2:{s:7:"release";s:8:"1.5.0RC1";s:3:"api";s:5:"1.3.1";}s:9:"stability";a:2:{s:7:"release";s:4:"beta";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2007-06-10";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:9:"BSD Style";}s:5:"notes";s:25:"Split off mail_MimeDecode";}i:17;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.5.0";s:3:"api";s:5:"1.3.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2007-06-17";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:9:"BSD Style";}s:5:"notes";s:25:"Split off Mail_MimeDecode";}i:18;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.5.1";s:3:"api";s:5:"1.3.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2007-06-20";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:9:"BSD Style";}s:5:"notes";s:55:"* Fix Bug #11344: Error at line 644 in mime.php [cipri]";}i:19;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.5.2";s:3:"api";s:5:"1.3.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2007-06-21";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:9:"BSD Style";}s:5:"notes";s:107:"* Fix Bug #11381: domain name is attached to content-id, trailing greater-than sign is not remove [cipri]";}i:20;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.5.3";s:3:"api";s:5:"1.3.2";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2009-12-29";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:9:"BSD Style";}s:5:"notes";s:1264:"Fixed bugs: * Fix Bug #14678: srand() lowers security [clockwerx] * Fix Bug #12921: _file2str not binary safe [walter] * Fix Bug #12385: Bad regex when replacing css style attachments [cipri] * Fix Bug #16911: Excessive semicolon in MIME header [alec] * Fix Bug #15320: Attachment charset is not set in Content-Type header [alec] * Fix Bug #16911: Lack of semicolon separator for MIME header parameters [alec] * Fix Bug #16846: Use preg_replace_callback() instead of /e modifier [alec] * Fix Bug #14779: Problem with an empty attachment [alec] * Fix Bug #15913: Optimize the memory used by Mail_mimePart::encode. Avoid having attachments data duplicated in memory [alec] * Fix Bug #16539: Headers longer than 998 characters aren't wrapped [alec] * Fix Bug #11238: Wrong encoding of structured headers [alec] * Fix Bug #13641: iconv_mime_encode() seems to work different/errorious than the build in logic. Removed 'ignore_iconv' param. [alec] * Fix Bug #16706: Incorrect double-quotes RFC 2231-encoded parameter values [alec] * Fix Bug #14232: RFC2231: tspecials encoding in _buildHeaderParam() [alec] Implemented Features: * Implement Feature #10438: Function (encodeHeader) for encoding of given header [alec]";}i:21;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.6.0";s:3:"api";s:5:"1.4.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2010-01-27";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:9:"BSD Style";}s:5:"notes";s:540:"Bugs Fixed: * Don't break specified headers folding [alec] * Bug #17025: Wrong headers() result for long unwrapable header value [alec] Implemented Features: * Allow setting Content-ID for HTML Images [alec] * Added one setParam() in place of many set*() functions [alec] * Added getParam(), getTXTBody(), getHTMLBody() [alec] * Skip RFC2231's charset if filename contains only ASCII characters [alec] * Make sure that Received: headers are returned on the top [alec] * Added saveMessageBody() and getMessageBody() functions [alec]";}i:22;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.6.1";s:3:"api";s:5:"1.4.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2010-03-08";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:9:"BSD Style";}s:5:"notes";s:262:"Bugs Fixed: * Fix encoding of Return-Receipt-To and Disposition-Notification-To headers [alec] Implemented Features: * Implement Feature #12466: Build parameters validation [alec] * Implement Feature #17175: Content-Description support for attachments [alec]";}i:23;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.6.2";s:3:"api";s:5:"1.4.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2010-03-23";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:9:"BSD Style";}s:5:"notes";s:103:"Bugs Fixed: * Fix Bug #17226: Non RFC-compliant quoted-printable encoding of structured headers [alec]";}i:24;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.7.0";s:3:"api";s:5:"1.4.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2010-04-12";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:9:"BSD Style";}s:5:"notes";s:233:"Implemented Features: * Added Mail_mime::setContentType() function with possibility to set various types in Content-Type header (also fixes problem with boundary parameter when Content-Type header was specified by user) [alec]";}i:25;a:5:{s:4:"date";s:10:"2010-07-29";s:7:"version";a:2:{s:7:"release";s:5:"1.8.0";s:3:"api";s:5:"1.4.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:9:"BSD Style";}s:5:"notes";s:314:"Bugs Fixed: * Double-addition of e-mail domain to content ID in HTML images [alec] * #17311: Multi-octet characters are split across adjacent 'encoded-word's [alec] * #17573: Place charset parameter in first line of Content-Type header (if possible) [alec] Implemented Features: * #17518: addTo() method [alec]";}i:26;a:5:{s:4:"date";s:10:"2010-12-01";s:7:"version";a:2:{s:7:"release";s:5:"1.8.1";s:3:"api";s:5:"1.4.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:9:"BSD Style";}s:5:"notes";s:101:"Bugs Fixed: * #18083: Not possible to set separate charset for attachment content and headers [alec]";}i:27;a:5:{s:4:"date";s:10:"2011-08-10";s:7:"version";a:2:{s:7:"release";s:5:"1.8.2";s:3:"api";s:5:"1.4.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:9:"BSD Style";}s:5:"notes";s:207:"Bugs Fixed: * #18426: Fixed backward compatibility for "dfilename" parameter [alec] * Removed xmail.dtd, xmail.xsl from the package [alec] * Fixed handling of email addresses with quoted local part [alec]";}i:28;a:5:{s:4:"date";s:10:"2012-03-12";s:7:"version";a:2:{s:7:"release";s:5:"1.8.3";s:3:"api";s:5:"1.4.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:9:"BSD Style";}s:5:"notes";s:232:"* Request #19009: Remove error_reporting from tests [alec] * Fixed Bug #19094: Email addresses do not have to contain a space between the name and address part [alec] * Fixed Bug #19328: Wrong encoding of filenames with comma [alec]";}i:29;a:5:{s:4:"date";s:10:"2012-05-17";s:7:"version";a:2:{s:7:"release";s:5:"1.8.4";s:3:"api";s:5:"1.4.2";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:9:"BSD Style";}s:5:"notes";s:179:"* Request #19406: Allow to set individual attachment part headers [alec] * Fixed Bug #18982: Non-static method Mail_mimePart::encodeHeader() should not be called statically [alec]";}i:30;a:5:{s:4:"date";s:10:"2012-06-09";s:7:"version";a:2:{s:7:"release";s:5:"1.8.5";s:3:"api";s:5:"1.4.3";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:9:"BSD Style";}s:5:"notes";s:198:"* Added possibility to set additional parameters of message part header, e.g. attachment size [alec] * Added automatic setting of attachment size via Content-Disposition header size parameter [alec]";}i:31;a:5:{s:4:"date";s:10:"2012-10-23";s:7:"version";a:2:{s:7:"release";s:5:"1.8.6";s:3:"api";s:5:"1.4.3";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:9:"BSD Style";}s:5:"notes";s:235:"* Bug #19473: PEAR::isError() compatibility problem with PHP 5.4 [alec] * Bug #19497: Attachment filename is cut on slash character [alec] * Bug #19665: Add Mail-Reply-To and Mail-Followup-To to structured recipient headers list [alec]";}i:32;a:5:{s:4:"date";s:10:"2012-12-25";s:7:"version";a:2:{s:7:"release";s:5:"1.8.7";s:3:"api";s:5:"1.4.3";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:9:"BSD Style";}s:5:"notes";s:104:"* Bug #5333: Fix more return by reference errors [alec] * Bug #19754: Fix compatibility with PHP4 [alec]";}i:33;a:5:{s:4:"date";s:10:"2013-07-05";s:7:"version";a:2:{s:7:"release";s:5:"1.8.8";s:3:"api";s:5:"1.4.3";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:9:"BSD Style";}s:5:"notes";s:294:"* Fixed warning/notice on (static vs. non-static) PEAR::raiseError() usage [alec] * Fixed Bug #19761: PHP5 warnings about return by reference [alec] * Fixed Bug #19770: Make cid generator more unique on Windows [alec] * Fixed Bug #19987: E_STRICT warning when null is passed by reference [alec]";}i:34;a:5:{s:4:"date";s:10:"2014-05-14";s:7:"version";a:2:{s:7:"release";s:5:"1.8.9";s:3:"api";s:5:"1.4.3";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:9:"BSD Style";}s:5:"notes";s:219:"* Fixed Bug #20273: Incorrect handling of HTAB in encodeHeader() [alec] * Fixed Bug #20226: Mail_mimePart::encodeHeader does not encode ISO-2022-JP string [alec] * Fixed Bug #20222: Broken Compatybility with PHP4 [alec]";}i:35;a:6:{s:4:"date";s:10:"2015-07-05";s:4:"time";s:8:"12:50:00";s:7:"version";a:2:{s:7:"release";s:8:"1.9.0RC1";s:3:"api";s:5:"2.0.0";}s:9:"stability";a:2:{s:7:"release";s:4:"beta";s:3:"api";s:4:"beta";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:9:"BSD Style";}s:5:"notes";s:314:"* Drop PHP4 support, Fix warnings on PHP7 [alec] * Request #20564: Added possibility to unset headers [alec] * Request #20563: Added isMultipart() method [alec] * Request #20565: Accept also a file pointer in Mail_mimePart::encodeToFile(), Mail_mime::get() and Mail_mime::saveMessageBody() [alec]";}i:36;a:6:{s:4:"date";s:10:"2015-08-06";s:4:"time";s:8:"12:00:00";s:7:"version";a:2:{s:7:"release";s:5:"1.9.0";s:3:"api";s:5:"1.9.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:9:"BSD Style";}s:5:"notes";s:200:"* Bug #20921: Make Mail_mimePart::encodeHeaderValue() a static method [alec] * Bug #20931: Really remove unset headers [alec] * Request #18772: Added methods for creating text/calendar messages [alec]";}i:37;a:6:{s:4:"date";s:10:"2015-09-13";s:4:"time";s:8:"12:00:00";s:7:"version";a:2:{s:7:"release";s:6:"1.10.0";s:3:"api";s:6:"1.10.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:9:"BSD Style";}s:5:"notes";s:156:"* Add possibility to add externally created Mail_mimePart objects as attachments [alec] * Add possibility to set preamble text for multipart messages [alec]";}i:38;a:6:{s:4:"date";s:10:"2017-05-21";s:4:"time";s:8:"12:00:00";s:7:"version";a:2:{s:7:"release";s:6:"1.10.1";s:3:"api";s:6:"1.10.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:9:"BSD Style";}s:5:"notes";s:286:"* Fix Bug 21206: explodeQuotedString() does not handle quoted strings correctly [dfukagaw28] * Fix Bug 21205: Invalid encoding of headers with quoted multibyte strings in non-unicode charset [dfukagaw28] * Fix Bug 21098: Discrepancy in handling of empty (but set) plain text part [alec]";}i:39;a:6:{s:4:"date";s:10:"2017-11-17";s:4:"time";s:8:"11:00:00";s:7:"version";a:2:{s:7:"release";s:6:"1.10.2";s:3:"api";s:6:"1.10.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:9:"BSD Style";}s:5:"notes";s:115:"* Fix Bug #21255: Boundary gets added twice when using setContentType() [alec] * PHP 7.2 compatibility fixes [alec]";}i:40;a:6:{s:4:"date";s:10:"2019-09-25";s:4:"time";s:8:"08:00:00";s:7:"version";a:2:{s:7:"release";s:6:"1.10.3";s:3:"api";s:6:"1.10.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:9:"BSD Style";}s:5:"notes";s:78:"* Fix deprecation warning for get_magic_quotes_runtime() use on PHP 7.4 [alec]";}i:41;a:6:{s:4:"date";s:10:"2019-10-13";s:4:"time";s:8:"11:00:00";s:7:"version";a:2:{s:7:"release";s:6:"1.10.4";s:3:"api";s:6:"1.10.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:9:"BSD Style";}s:5:"notes";s:63:"* Fix E_STRICT errors introduced in the previous release [alec]";}i:42;a:6:{s:4:"date";s:10:"2020-01-24";s:4:"time";s:8:"19:00:00";s:7:"version";a:2:{s:7:"release";s:6:"1.10.5";s:3:"api";s:6:"1.10.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:9:"BSD Style";}s:5:"notes";s:158:"* Make sure to not set Content-Transfer-Encoding on multipart messages [alec] * Added support for calendar invitations with attachments/html/images [jacalben]";}i:43;a:6:{s:4:"date";s:10:"2020-01-30";s:4:"time";s:8:"08:25:00";s:7:"version";a:2:{s:7:"release";s:6:"1.10.6";s:3:"api";s:6:"1.10.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:9:"BSD Style";}s:5:"notes";s:118:"* Fix different boundary in headers and body when using headers() after get() [alec] * Removed phail.php script [alec]";}i:44;a:6:{s:4:"date";s:10:"2020-03-01";s:4:"time";s:8:"08:50:00";s:7:"version";a:2:{s:7:"release";s:6:"1.10.7";s:3:"api";s:6:"1.10.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:9:"BSD Style";}s:5:"notes";s:84:"* Fix invalid Content-Type for messages with only html part and inline images [alec]";}i:45;a:6:{s:4:"date";s:10:"2020-06-13";s:4:"time";s:8:"08:50:00";s:7:"version";a:2:{s:7:"release";s:6:"1.10.8";s:3:"api";s:6:"1.10.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:9:"BSD Style";}s:5:"notes";s:85:"* Fix encoding issues with ISO-2022-JP-MS input labelled with ISO-2022-JP [shirosaki]";}i:46;a:6:{s:4:"date";s:10:"2020-06-27";s:4:"time";s:8:"10:30:00";s:7:"version";a:2:{s:7:"release";s:6:"1.10.9";s:3:"api";s:6:"1.10.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:9:"BSD Style";}s:5:"notes";s:63:"* Added a workaround for an opcache bug on OpenSuse 15.1 [alec]";}i:47;a:6:{s:4:"date";s:10:"2021-01-17";s:4:"time";s:8:"09:25:00";s:7:"version";a:2:{s:7:"release";s:7:"1.10.10";s:3:"api";s:6:"1.10.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:9:"BSD Style";}s:5:"notes";s:191:"* Compatibility fixes for PHP 5.2 and 5.3 [alec] * Corrected soft line breaks handling to be RFC compliant [ixs] * Corrected line breaks for lines ending in dots and length more than 74 [ixs]";}}}s:8:"filelist";a:53:{s:25:"tests/class-filename.phpt";a:5:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"edd138f6c5497ae2b5d63620a67a931e";s:4:"name";s:25:"tests/class-filename.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:70:"/opt/alt/php56/usr/share/pear/test/Mail_Mime/tests/class-filename.phpt";}s:36:"tests/content_transfer_encoding.phpt";a:5:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"7ec986391d0af058316f66e5a507e059";s:4:"name";s:36:"tests/content_transfer_encoding.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:81:"/opt/alt/php56/usr/share/pear/test/Mail_Mime/tests/content_transfer_encoding.phpt";}s:24:"tests/encoding_case.phpt";a:5:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"c1a43360d9b2cb5f9542503a4355c277";s:4:"name";s:24:"tests/encoding_case.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:69:"/opt/alt/php56/usr/share/pear/test/Mail_Mime/tests/encoding_case.phpt";}s:32:"tests/headers_with_mbstring.phpt";a:5:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"bf50a200190cad5e2d4aae4e120ea09f";s:4:"name";s:32:"tests/headers_with_mbstring.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:77:"/opt/alt/php56/usr/share/pear/test/Mail_Mime/tests/headers_with_mbstring.phpt";}s:35:"tests/headers_without_mbstring.phpt";a:5:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"9a2d207f873317125ff43c092f3f0d25";s:4:"name";s:35:"tests/headers_without_mbstring.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:80:"/opt/alt/php56/usr/share/pear/test/Mail_Mime/tests/headers_without_mbstring.phpt";}s:27:"tests/qp_encoding_test.phpt";a:5:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"25d4c5b9fdeaabc7810c26e6f89e95ca";s:4:"name";s:27:"tests/qp_encoding_test.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:72:"/opt/alt/php56/usr/share/pear/test/Mail_Mime/tests/qp_encoding_test.phpt";}s:41:"tests/sleep_wakeup_EOL-bug3488-part1.phpt";a:5:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"958197f31b4a20c91dd42662595e7516";s:4:"name";s:41:"tests/sleep_wakeup_EOL-bug3488-part1.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:86:"/opt/alt/php56/usr/share/pear/test/Mail_Mime/tests/sleep_wakeup_EOL-bug3488-part1.phpt";}s:41:"tests/sleep_wakeup_EOL-bug3488-part2.phpt";a:5:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"46675529f1f021b51a1aa0ae6c971cd2";s:4:"name";s:41:"tests/sleep_wakeup_EOL-bug3488-part2.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:86:"/opt/alt/php56/usr/share/pear/test/Mail_Mime/tests/sleep_wakeup_EOL-bug3488-part2.phpt";}s:26:"tests/test_Bug_3513_1.phpt";a:5:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"f8c05910737e451c7a9d4737b8d9f095";s:4:"name";s:26:"tests/test_Bug_3513_1.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:71:"/opt/alt/php56/usr/share/pear/test/Mail_Mime/tests/test_Bug_3513_1.phpt";}s:26:"tests/test_Bug_3513_2.phpt";a:5:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"edb467a375ddf09e777a9388e2e8cbb5";s:4:"name";s:26:"tests/test_Bug_3513_2.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:71:"/opt/alt/php56/usr/share/pear/test/Mail_Mime/tests/test_Bug_3513_2.phpt";}s:26:"tests/test_Bug_3513_3.phpt";a:5:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"70c2456445eaaa80779206e9e245d685";s:4:"name";s:26:"tests/test_Bug_3513_3.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:71:"/opt/alt/php56/usr/share/pear/test/Mail_Mime/tests/test_Bug_3513_3.phpt";}s:26:"tests/test_Bug_7561_1.phpt";a:5:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"4cda500d0d7925e81a299f1d3db132a9";s:4:"name";s:26:"tests/test_Bug_7561_1.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:71:"/opt/alt/php56/usr/share/pear/test/Mail_Mime/tests/test_Bug_7561_1.phpt";}s:26:"tests/test_Bug_8386_1.phpt";a:5:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"42a214e7e3d3afa07f8996b235222611";s:4:"name";s:26:"tests/test_Bug_8386_1.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:71:"/opt/alt/php56/usr/share/pear/test/Mail_Mime/tests/test_Bug_8386_1.phpt";}s:26:"tests/test_Bug_8541_1.phpt";a:5:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"ed78099563499f60386a128cb7b96925";s:4:"name";s:26:"tests/test_Bug_8541_1.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:71:"/opt/alt/php56/usr/share/pear/test/Mail_Mime/tests/test_Bug_8541_1.phpt";}s:26:"tests/test_Bug_9722_1.phpt";a:5:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"5250a0693599b945e8642a1a289d7275";s:4:"name";s:26:"tests/test_Bug_9722_1.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:71:"/opt/alt/php56/usr/share/pear/test/Mail_Mime/tests/test_Bug_9722_1.phpt";}s:27:"tests/test_Bug_10596_1.phpt";a:5:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"b7f58f54e1485c23a60c83cd3cc5563e";s:4:"name";s:27:"tests/test_Bug_10596_1.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:72:"/opt/alt/php56/usr/share/pear/test/Mail_Mime/tests/test_Bug_10596_1.phpt";}s:27:"tests/test_Bug_10816_1.phpt";a:5:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"ccb53d80e7f5c9f28b11abce5fe5d490";s:4:"name";s:27:"tests/test_Bug_10816_1.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:72:"/opt/alt/php56/usr/share/pear/test/Mail_Mime/tests/test_Bug_10816_1.phpt";}s:27:"tests/test_Bug_10999_1.phpt";a:5:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"f3d92a1fff099173b8600fb3646d0614";s:4:"name";s:27:"tests/test_Bug_10999_1.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:72:"/opt/alt/php56/usr/share/pear/test/Mail_Mime/tests/test_Bug_10999_1.phpt";}s:25:"tests/test_Bug_11381.phpt";a:5:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"3f2757d5db43abd8f177f094f4d53625";s:4:"name";s:25:"tests/test_Bug_11381.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:70:"/opt/alt/php56/usr/share/pear/test/Mail_Mime/tests/test_Bug_11381.phpt";}s:25:"tests/test_Bug_11731.phpt";a:5:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"c64d675e73bc02fc94f5d03b3117cfa0";s:4:"name";s:25:"tests/test_Bug_11731.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:70:"/opt/alt/php56/usr/share/pear/test/Mail_Mime/tests/test_Bug_11731.phpt";}s:25:"tests/test_Bug_12165.phpt";a:5:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"8c9305ca05f5ed2d7cd7e31e4836f17a";s:4:"name";s:25:"tests/test_Bug_12165.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:70:"/opt/alt/php56/usr/share/pear/test/Mail_Mime/tests/test_Bug_12165.phpt";}s:27:"tests/test_Bug_12385_1.phpt";a:5:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"2aa2c3dfbe44500809e79da994272611";s:4:"name";s:27:"tests/test_Bug_12385_1.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:72:"/opt/alt/php56/usr/share/pear/test/Mail_Mime/tests/test_Bug_12385_1.phpt";}s:25:"tests/test_Bug_12411.phpt";a:5:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"ef1d726233dbd3360c540fd6a959b0d0";s:4:"name";s:25:"tests/test_Bug_12411.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:70:"/opt/alt/php56/usr/share/pear/test/Mail_Mime/tests/test_Bug_12411.phpt";}s:25:"tests/test_Bug_12466.phpt";a:5:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"a862a57ff622fcbb2328be6c805e2d05";s:4:"name";s:25:"tests/test_Bug_12466.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:70:"/opt/alt/php56/usr/share/pear/test/Mail_Mime/tests/test_Bug_12466.phpt";}s:25:"tests/test_Bug_13032.phpt";a:5:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"4eddeeac08f351feb147ab6fda439526";s:4:"name";s:25:"tests/test_Bug_13032.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:70:"/opt/alt/php56/usr/share/pear/test/Mail_Mime/tests/test_Bug_13032.phpt";}s:25:"tests/test_Bug_13444.phpt";a:5:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"de15a0657a83694bc6991c4184ccf9bd";s:4:"name";s:25:"tests/test_Bug_13444.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:70:"/opt/alt/php56/usr/share/pear/test/Mail_Mime/tests/test_Bug_13444.phpt";}s:25:"tests/test_Bug_13962.phpt";a:5:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"80afe9fced03288884e9d302d1e65b2d";s:4:"name";s:25:"tests/test_Bug_13962.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:70:"/opt/alt/php56/usr/share/pear/test/Mail_Mime/tests/test_Bug_13962.phpt";}s:25:"tests/test_Bug_14529.phpt";a:5:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"89bf87e798f4a149a150d4c2a505f976";s:4:"name";s:25:"tests/test_Bug_14529.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:70:"/opt/alt/php56/usr/share/pear/test/Mail_Mime/tests/test_Bug_14529.phpt";}s:25:"tests/test_Bug_14779.phpt";a:5:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"5f9100adb1c609110ed495fafa819975";s:4:"name";s:25:"tests/test_Bug_14779.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:70:"/opt/alt/php56/usr/share/pear/test/Mail_Mime/tests/test_Bug_14779.phpt";}s:25:"tests/test_Bug_14780.phpt";a:5:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"45eb42fe4e325da64f1ae8f149e2a396";s:4:"name";s:25:"tests/test_Bug_14780.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:70:"/opt/alt/php56/usr/share/pear/test/Mail_Mime/tests/test_Bug_14780.phpt";}s:25:"tests/test_Bug_15320.phpt";a:5:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"609dad2083c54ba56ea691c488ca20e2";s:4:"name";s:25:"tests/test_Bug_15320.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:70:"/opt/alt/php56/usr/share/pear/test/Mail_Mime/tests/test_Bug_15320.phpt";}s:25:"tests/test_Bug_16539.phpt";a:5:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"f4ef08e416e775558e8075b531bbc814";s:4:"name";s:25:"tests/test_Bug_16539.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:70:"/opt/alt/php56/usr/share/pear/test/Mail_Mime/tests/test_Bug_16539.phpt";}s:25:"tests/test_Bug_17025.phpt";a:5:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"ed1bd0fc9067b3fb8b95808bfa315916";s:4:"name";s:25:"tests/test_Bug_17025.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:70:"/opt/alt/php56/usr/share/pear/test/Mail_Mime/tests/test_Bug_17025.phpt";}s:25:"tests/test_Bug_17175.phpt";a:5:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"8a37de74fb39fed4566617a7ea38bb69";s:4:"name";s:25:"tests/test_Bug_17175.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:70:"/opt/alt/php56/usr/share/pear/test/Mail_Mime/tests/test_Bug_17175.phpt";}s:25:"tests/test_Bug_18083.phpt";a:5:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"b9dee3c7c45d8c6c22f860e93c3769b9";s:4:"name";s:25:"tests/test_Bug_18083.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:70:"/opt/alt/php56/usr/share/pear/test/Mail_Mime/tests/test_Bug_18083.phpt";}s:25:"tests/test_Bug_18772.phpt";a:5:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"96ce23ad1a1d6417facfcdd2baa9c8eb";s:4:"name";s:25:"tests/test_Bug_18772.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:70:"/opt/alt/php56/usr/share/pear/test/Mail_Mime/tests/test_Bug_18772.phpt";}s:25:"tests/test_Bug_19497.phpt";a:5:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"dd98307b3224b173f7b54f7e403865a4";s:4:"name";s:25:"tests/test_Bug_19497.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:70:"/opt/alt/php56/usr/share/pear/test/Mail_Mime/tests/test_Bug_19497.phpt";}s:25:"tests/test_Bug_20226.phpt";a:5:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"e1194180cb6a218fab69db90f88d1cb2";s:4:"name";s:25:"tests/test_Bug_20226.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:70:"/opt/alt/php56/usr/share/pear/test/Mail_Mime/tests/test_Bug_20226.phpt";}s:25:"tests/test_Bug_20273.phpt";a:5:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"1b7919174edcd1cf5d5fd5a622fdac9b";s:4:"name";s:25:"tests/test_Bug_20273.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:70:"/opt/alt/php56/usr/share/pear/test/Mail_Mime/tests/test_Bug_20273.phpt";}s:25:"tests/test_Bug_20563.phpt";a:5:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"6513c4b0c9e962c900d020124752333e";s:4:"name";s:25:"tests/test_Bug_20563.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:70:"/opt/alt/php56/usr/share/pear/test/Mail_Mime/tests/test_Bug_20563.phpt";}s:25:"tests/test_Bug_20564.phpt";a:5:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"7c7a00818cb0f01fa6c52c920b9e76c6";s:4:"name";s:25:"tests/test_Bug_20564.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:70:"/opt/alt/php56/usr/share/pear/test/Mail_Mime/tests/test_Bug_20564.phpt";}s:25:"tests/test_Bug_21027.phpt";a:5:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"b9e31a9c24b05dfb6166512e04e2f056";s:4:"name";s:25:"tests/test_Bug_21027.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:70:"/opt/alt/php56/usr/share/pear/test/Mail_Mime/tests/test_Bug_21027.phpt";}s:25:"tests/test_Bug_21098.phpt";a:5:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"b634a5e99aa26a8b6df8fcfae07051b4";s:4:"name";s:25:"tests/test_Bug_21098.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:70:"/opt/alt/php56/usr/share/pear/test/Mail_Mime/tests/test_Bug_21098.phpt";}s:25:"tests/test_Bug_21205.phpt";a:5:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"b21be5b099a69428bd37e60589cdd485";s:4:"name";s:25:"tests/test_Bug_21205.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:70:"/opt/alt/php56/usr/share/pear/test/Mail_Mime/tests/test_Bug_21205.phpt";}s:25:"tests/test_Bug_21206.phpt";a:5:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"bc152c12839964fba15da5673d25c4db";s:4:"name";s:25:"tests/test_Bug_21206.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:70:"/opt/alt/php56/usr/share/pear/test/Mail_Mime/tests/test_Bug_21206.phpt";}s:25:"tests/test_Bug_21255.phpt";a:5:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"ccf732525be42c955eea18e78490c3e1";s:4:"name";s:25:"tests/test_Bug_21255.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:70:"/opt/alt/php56/usr/share/pear/test/Mail_Mime/tests/test_Bug_21255.phpt";}s:24:"tests/test_Bug_GH16.phpt";a:5:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"579f1e11da6c8074dbf508dc1f1dedfa";s:4:"name";s:24:"tests/test_Bug_GH16.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:69:"/opt/alt/php56/usr/share/pear/test/Mail_Mime/tests/test_Bug_GH16.phpt";}s:24:"tests/test_Bug_GH19.phpt";a:5:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"df32d66d9fccf7a0956422811283272a";s:4:"name";s:24:"tests/test_Bug_GH19.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:69:"/opt/alt/php56/usr/share/pear/test/Mail_Mime/tests/test_Bug_GH19.phpt";}s:24:"tests/test_Bug_GH26.phpt";a:5:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"b7b5b5bacc6a599cfaece35ad202ad1a";s:4:"name";s:24:"tests/test_Bug_GH26.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:69:"/opt/alt/php56/usr/share/pear/test/Mail_Mime/tests/test_Bug_GH26.phpt";}s:29:"tests/test_linebreak_dot.phpt";a:5:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"e08958f1bb60561f072a3508b8fd3e2e";s:4:"name";s:29:"tests/test_linebreak_dot.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:74:"/opt/alt/php56/usr/share/pear/test/Mail_Mime/tests/test_linebreak_dot.phpt";}s:35:"tests/test_linebreak_larger_76.phpt";a:5:{s:14:"baseinstalldir";s:4:"Mail";s:6:"md5sum";s:32:"8398e9bfea0bc7c4ff0770ae3d6279fe";s:4:"name";s:35:"tests/test_linebreak_larger_76.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:80:"/opt/alt/php56/usr/share/pear/test/Mail_Mime/tests/test_linebreak_larger_76.phpt";}s:13:"Mail/mime.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"e5c9ac7f32e53afdeafd1a84343a89ae";s:4:"name";s:13:"Mail/mime.php";s:4:"role";s:3:"php";s:12:"installed_as";s:43:"/opt/alt/php56/usr/share/pear/Mail/mime.php";}s:17:"Mail/mimePart.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"36128789ad1101d39d13b06ca2585576";s:4:"name";s:17:"Mail/mimePart.php";s:4:"role";s:3:"php";s:12:"installed_as";s:47:"/opt/alt/php56/usr/share/pear/Mail/mimePart.php";}}s:12:"_lastversion";N;s:7:"dirtree";a:3:{s:50:"/opt/alt/php56/usr/share/pear/test/Mail_Mime/tests";b:1;s:44:"/opt/alt/php56/usr/share/pear/test/Mail_Mime";b:1;s:34:"/opt/alt/php56/usr/share/pear/Mail";b:1;}s:3:"old";a:7:{s:7:"version";s:7:"1.10.11";s:12:"release_date";s:10:"2021-09-05";s:13:"release_state";s:6:"stable";s:15:"release_license";s:9:"BSD Style";s:13:"release_notes";s:246:"* Fix PHP 8.1: strlen(): Passing null to parameter #1 ($string) of type string is deprecated [alec] * Fix encoding recipient names with @ character and no space between name and address [alec] * Fix the license label in composer.json [jnkowa-gfk]";s:12:"release_deps";a:2:{i:0;a:4:{s:4:"type";s:3:"php";s:3:"rel";s:2:"ge";s:7:"version";s:5:"5.2.0";s:8:"optional";s:2:"no";}i:1;a:6:{s:4:"type";s:3:"pkg";s:7:"channel";s:12:"pear.php.net";s:4:"name";s:4:"PEAR";s:3:"rel";s:2:"ge";s:7:"version";s:5:"1.6.0";s:8:"optional";s:2:"no";}}s:11:"maintainers";a:2:{i:0;a:5:{s:4:"name";s:19:"Cipriano Groenendal";s:5:"email";s:13:"cipri@php.net";s:6:"active";s:2:"no";s:6:"handle";s:5:"cipri";s:4:"role";s:4:"lead";}i:1;a:5:{s:4:"name";s:19:"Aleksander Machniak";s:5:"email";s:12:"alec@php.net";s:6:"active";s:3:"yes";s:6:"handle";s:4:"alec";s:4:"role";s:4:"lead";}}}s:10:"xsdversion";s:3:"2.0";s:13:"_lastmodified";i:1669631553;}PK�����u]uzuv��uv����.registry/xml_util.regnu�[��������a:23:{s:7:"attribs";a:6:{s:15:"packagerversion";s:6:"1.10.5";s:7:"version";s:3:"2.0";s:5:"xmlns";s:35:"http://pear.php.net/dtd/package-2.0";s:11:"xmlns:tasks";s:33:"http://pear.php.net/dtd/tasks-1.0";s:9:"xmlns:xsi";s:41:"http://www.w3.org/2001/XMLSchema-instance";s:18:"xsi:schemaLocation";s:159:"http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd";}s:4:"name";s:8:"XML_Util";s:7:"channel";s:12:"pear.php.net";s:7:"summary";s:17:"XML utility class";s:11:"description";s:192:"Selection of methods that are often needed when working with XML documents. Functionality includes creating of attribute lists from arrays, creation of tags, validation of XML names and more.";s:4:"lead";a:2:{i:0;a:4:{s:4:"name";s:13:"Chuck Burgess";s:4:"user";s:7:"ashnazg";s:5:"email";s:15:"ashnazg@php.net";s:6:"active";s:3:"yes";}i:1;a:4:{s:4:"name";s:15:"Stephan Schmidt";s:4:"user";s:5:"schst";s:5:"email";s:19:"schst@php-tools.net";s:6:"active";s:2:"no";}}s:6:"helper";a:4:{s:4:"name";s:12:"Davey Shafik";s:4:"user";s:5:"davey";s:5:"email";s:13:"davey@php.net";s:6:"active";s:2:"no";}s:4:"date";s:10:"2020-04-19";s:4:"time";s:8:"14:54:10";s:7:"version";a:2:{s:7:"release";s:5:"1.4.5";s:3:"api";s:5:"1.4.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:42:"http://opensource.org/licenses/bsd-license";}s:8:"_content";s:11:"BSD License";}s:5:"notes";s:64:"* PR #12: fix Trying to access array offset on value of type int";s:8:"contents";a:1:{s:3:"dir";a:2:{s:7:"attribs";a:2:{s:14:"baseinstalldir";s:1:"/";s:4:"name";s:1:"/";}s:4:"file";a:25:{i:0;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"af2746028ae4395f549855a5e444ada7";s:4:"name";s:20:"examples/example.php";s:4:"role";s:3:"doc";}}i:1;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"b9e52f4aa372c4067c609f49c2285b8f";s:4:"name";s:21:"examples/example2.php";s:4:"role";s:3:"doc";}}i:2;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"d0af9354df0962e70e9e2215b5611b9c";s:4:"name";s:27:"tests/AbstractUnitTests.php";s:4:"role";s:4:"test";}}i:3;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"57ce547d64d6e1f2986c313407deffef";s:4:"name";s:25:"tests/ApiVersionTests.php";s:4:"role";s:4:"test";}}i:4;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"2d0427db94790df7ada24a744547edf5";s:4:"name";s:33:"tests/AttributesToStringTests.php";s:4:"role";s:4:"test";}}i:5;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"673d1438c4718a70c5da3fe019027db4";s:4:"name";s:32:"tests/CollapseEmptyTagsTests.php";s:4:"role";s:4:"test";}}i:6;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"46b981f91edd163f1cd021cfef5d1bb1";s:4:"name";s:33:"tests/CreateCDataSectionTests.php";s:4:"role";s:4:"test";}}i:7;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"6aa925b879572e9b3f1885b7cdbb223b";s:4:"name";s:28:"tests/CreateCommentTests.php";s:4:"role";s:4:"test";}}i:8;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"dbc083b62a020fa245fde5a7828a4806";s:4:"name";s:31:"tests/CreateEndElementTests.php";s:4:"role";s:4:"test";}}i:9;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"f58e38343ecf60811c842d4cfc8194ae";s:4:"name";s:33:"tests/CreateStartElementTests.php";s:4:"role";s:4:"test";}}i:10;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"9385fba272f4ebccf4c95d43d16dcff4";s:4:"name";s:24:"tests/CreateTagTests.php";s:4:"role";s:4:"test";}}i:11;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"51e7ba1390e6dadc3c0be0c960bf171d";s:4:"name";s:33:"tests/CreateTagFromArrayTests.php";s:4:"role";s:4:"test";}}i:12;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"6bbb54ef4cf56dc2c0b558b295de5668";s:4:"name";s:36:"tests/GetDocTypeDeclarationTests.php";s:4:"role";s:4:"test";}}i:13;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"825b440b0ee8abd10b4df017c08bf15f";s:4:"name";s:32:"tests/GetXmlDeclarationTests.php";s:4:"role";s:4:"test";}}i:14;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"e6783bb330f8f2ae7225f02d56f194e4";s:4:"name";s:26:"tests/IsValidNameTests.php";s:4:"role";s:4:"test";}}i:15;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"b273525b905ae6d5fc53adcb3ce0b8d9";s:4:"name";s:25:"tests/RaiseErrorTests.php";s:4:"role";s:4:"test";}}i:16;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"20befbef5e55639539336761a17c64f3";s:4:"name";s:30:"tests/ReplaceEntitiesTests.php";s:4:"role";s:4:"test";}}i:17;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"a3ceff3302e31f90130be01c312b33b3";s:4:"name";s:30:"tests/ReverseEntitiesTests.php";s:4:"role";s:4:"test";}}i:18;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"aeb95108896180ef77a7dce3c310a3b8";s:4:"name";s:33:"tests/SplitQualifiedNameTests.php";s:4:"role";s:4:"test";}}i:19;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"e93010b1eff68f889fefcb006bf20b63";s:4:"name";s:22:"tests/Bug4950Tests.php";s:4:"role";s:4:"test";}}i:20;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"748ffb640e13e7b960385c7e12413782";s:4:"name";s:22:"tests/Bug5392Tests.php";s:4:"role";s:4:"test";}}i:21;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"01e68b66e27a6fdb197d572c67ae6bc5";s:4:"name";s:23:"tests/Bug18343Tests.php";s:4:"role";s:4:"test";}}i:22;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"d945220c38344bc773b18244439bb0cc";s:4:"name";s:23:"tests/Bug21177Tests.php";s:4:"role";s:4:"test";}}i:23;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"af2672bb90875c2e00f93f563bfafe70";s:4:"name";s:23:"tests/Bug21184Tests.php";s:4:"role";s:4:"test";}}i:24;a:2:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"0db6fa9c169bf6904aa7e588c2325a13";s:4:"name";s:12:"XML/Util.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:9:"@version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}}}}s:12:"dependencies";a:1:{s:8:"required";a:3:{s:3:"php";a:1:{s:3:"min";s:5:"5.4.0";}s:13:"pearinstaller";a:1:{s:3:"min";s:5:"1.9.0";}s:9:"extension";a:1:{s:4:"name";s:4:"pcre";}}}s:10:"phprelease";s:0:"";s:9:"changelog";a:1:{s:7:"release";a:31:{i:0;a:5:{s:7:"version";a:2:{s:7:"release";s:3:"0.1";s:3:"api";s:3:"0.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2003-08-01";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:26:"http://www.php.net/license";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:14:"inital release";}i:1;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"0.1.1";s:3:"api";s:5:"0.1.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2003-08-02";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:26:"http://www.php.net/license";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:41:"bugfix: removed bug in createTagFromArray";}i:2;a:5:{s:7:"version";a:2:{s:7:"release";s:3:"0.2";s:3:"api";s:3:"0.2";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2003-08-12";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:26:"http://www.php.net/license";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:39:"added XML_Util::getDocTypeDeclaration()";}i:3;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"0.2.1";s:3:"api";s:5:"0.2.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2003-09-05";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:26:"http://www.php.net/license";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:70:"fixed bug with zero as tag content in createTagFromArray and createTag";}i:4;a:5:{s:7:"version";a:2:{s:7:"release";s:3:"0.3";s:3:"api";s:3:"0.3";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2003-09-12";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:26:"http://www.php.net/license";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:49:"added createStartElement() and createEndElement()";}i:5;a:5:{s:7:"version";a:2:{s:7:"release";s:3:"0.4";s:3:"api";s:3:"0.4";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2003-09-21";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:26:"http://www.php.net/license";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:132:"added createCDataSection(), added support for CData sections in createTag* methods, fixed bug #23, fixed bug in splitQualifiedName()";}i:6;a:5:{s:7:"version";a:2:{s:7:"release";s:3:"0.5";s:3:"api";s:3:"0.5";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2003-09-23";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:26:"http://www.php.net/license";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:170:"added support for multiline attributes in attributesToString(), createTag*() and createStartElement (requested by Yavor Shahpasov for XML_Serializer), added createComment";}i:7;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"0.5.1";s:3:"api";s:5:"0.5.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2003-09-26";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:26:"http://www.php.net/license";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:102:"added default namespace parameter (optional) in splitQualifiedName() (requested by Sebastian Bergmann)";}i:8;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"0.5.2";s:3:"api";s:5:"0.5.2";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2003-11-22";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:26:"http://www.php.net/license";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:78:"now creates XHTML compliant empty tags (Davey), minor whitespace fixes (Davey)";}i:9;a:5:{s:7:"version";a:2:{s:7:"release";s:10:"0.6.0beta1";s:3:"api";s:10:"0.6.0beta1";}s:9:"stability";a:2:{s:7:"release";s:4:"beta";s:3:"api";s:4:"beta";}s:4:"date";s:10:"2004-05-24";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:26:"http://www.php.net/license";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:567:"- Fixed bug 1438 (namespaces not accepted for isValidName()) (thanks to davey) - added optional parameter to replaceEntities() to define the set of entities to replace - added optional parameter to attributesToString() to define, whether entities should be replaced (requested by Sebastian Bergmann) - allowed second parameter to XML_Util::attributesToString() to be an array containing options (easier to use, if you only need to set the last parameter) - introduced XML_Util::raiseError() to avoid the necessity of including PEAR.php, will only be included on error";}i:10;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"0.6.0";s:3:"api";s:5:"0.6.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2004-06-07";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:26:"http://www.php.net/license";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:567:"- Fixed bug 1438 (namespaces not accepted for isValidName()) (thanks to davey) - added optional parameter to replaceEntities() to define the set of entities to replace - added optional parameter to attributesToString() to define, whether entities should be replaced (requested by Sebastian Bergmann) - allowed second parameter to XML_Util::attributesToString() to be an array containing options (easier to use, if you only need to set the last parameter) - introduced XML_Util::raiseError() to avoid the necessity of including PEAR.php, will only be included on error";}i:11;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"0.6.1";s:3:"api";s:5:"0.6.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2004-10-28";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:26:"http://www.php.net/license";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:103:"- Added check for tag name (either as local part or qualified name) in createTagFromArray() (bug #1083)";}i:12;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.0.0";s:3:"api";s:5:"1.0.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2004-10-28";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:26:"http://www.php.net/license";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:41:"- Added reverseEntities() (request #2639)";}i:13;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.1.0";s:3:"api";s:5:"1.1.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2004-11-19";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:26:"http://www.php.net/license";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:73:"- Added collapseEmptyTags (patch by Sebastian Bergmann and Thomas Duffey)";}i:14;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.1.1";s:3:"api";s:5:"1.1.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2004-12-23";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:26:"http://www.php.net/license";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:306:"- fixed bug in replaceEntities() and reverseEntities() in conjunction with XML_UTIL_ENTITIES_HTML - createTag() and createTagFromArray() now accept XML_UTIL_ENTITIES_XML, XML_UTIL_ENTITIES_XML_REQUIRED, XML_UTIL_ENTITIES_HTML, XML_UTIL_ENTITIES_NONE and XML_UTIL_CDATA_SECTION as $replaceEntities parameter";}i:15;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.1.2";s:3:"api";s:5:"1.1.2";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2006-12-01";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:26:"http://www.php.net/license";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:207:"- fixed bug #5419: isValidName() now checks for character classes - implemented request #8196: added optional parameter to influence array sorting to createTag() createTagFromArray() and createStartElement()";}i:16;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.1.4";s:3:"api";s:5:"1.1.4";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2006-12-16";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:26:"http://www.php.net/license";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:61:"- Fixed bug #9561: Not allowing underscores in middle of tags";}i:17;a:5:{s:7:"version";a:2:{s:7:"release";s:7:"1.2.0a1";s:3:"api";s:5:"1.2.0";}s:9:"stability";a:2:{s:7:"release";s:5:"alpha";s:3:"api";s:5:"alpha";}s:4:"date";s:10:"2008-05-04";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:42:"http://opensource.org/licenses/bsd-license";}s:8:"_content";s:11:"BSD License";}s:5:"notes";s:208:"Changed license to New BSD License (Req #13826 [ashnazg]) Added a test suite against all API methods [ashnazg] Switch to package.xml v2 [ashnazg] Fixed Bug #4950: Incorrect CDATA serializing [ashnazg|ja.doma]";}i:18;a:5:{s:7:"version";a:2:{s:7:"release";s:7:"1.2.0a2";s:3:"api";s:5:"1.2.0";}s:9:"stability";a:2:{s:7:"release";s:5:"alpha";s:3:"api";s:5:"alpha";}s:4:"date";s:10:"2008-05-22";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:42:"http://opensource.org/licenses/bsd-license";}s:8:"_content";s:11:"BSD License";}s:5:"notes";s:403:"Changed license to New BSD License (Req #13826 [ashnazg]) Added a test suite against all API methods [ashnazg] Switch to package.xml v2 [ashnazg] Added Req #13839: Missing XHTML empty tags to collapse [ashnazg|drry] Fixed Bug #5392: encoding of ISO-8859-1 is the only supported encoding [ashnazg] Fixed Bug #4950: Incorrect CDATA serializing [ashnazg|drry] -- (this fix differs from the one in v1.2.0a1)";}i:19;a:5:{s:7:"version";a:2:{s:7:"release";s:8:"1.2.0RC1";s:3:"api";s:5:"1.2.0";}s:9:"stability";a:2:{s:7:"release";s:4:"beta";s:3:"api";s:4:"beta";}s:4:"date";s:10:"2008-07-12";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:42:"http://opensource.org/licenses/bsd-license";}s:8:"_content";s:11:"BSD License";}s:5:"notes";s:403:"Changed license to New BSD License (Req #13826 [ashnazg]) Added a test suite against all API methods [ashnazg] Switch to package.xml v2 [ashnazg] Added Req #13839: Missing XHTML empty tags to collapse [ashnazg|drry] Fixed Bug #5392: encoding of ISO-8859-1 is the only supported encoding [ashnazg] Fixed Bug #4950: Incorrect CDATA serializing [ashnazg|drry] -- (this fix differs from the one in v1.2.0a1)";}i:20;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.2.0";s:3:"api";s:5:"1.2.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2008-07-26";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:42:"http://opensource.org/licenses/bsd-license";}s:8:"_content";s:11:"BSD License";}s:5:"notes";s:403:"Changed license to New BSD License (Req #13826 [ashnazg]) Added a test suite against all API methods [ashnazg] Switch to package.xml v2 [ashnazg] Added Req #13839: Missing XHTML empty tags to collapse [ashnazg|drry] Fixed Bug #5392: encoding of ISO-8859-1 is the only supported encoding [ashnazg] Fixed Bug #4950: Incorrect CDATA serializing [ashnazg|drry] -- (this fix differs from the one in v1.2.0a1)";}i:21;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.2.1";s:3:"api";s:5:"1.2.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2011-12-31";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:42:"http://opensource.org/licenses/bsd-license";}s:8:"_content";s:11:"BSD License";}s:5:"notes";s:68:"Fixed Bug #14760: Bug in getDocTypeDeclaration() [ashnazg|fpospisil]";}i:22;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.2.2";s:3:"api";s:5:"1.2.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2014-06-07";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:42:"http://opensource.org/licenses/bsd-license";}s:8:"_content";s:11:"BSD License";}s:5:"notes";s:194:"QA release Bug #18343 Entities in file names decoded during packaging Bug #19174 upgrade PHPUnit require statements & other fixes (for PEAR QA Team) Request #19750 examples/example.php encoding";}i:23;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.2.3";s:3:"api";s:5:"1.2.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2014-06-07";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:42:"http://opensource.org/licenses/bsd-license";}s:8:"_content";s:11:"BSD License";}s:5:"notes";s:40:"Bug #20293 Broken installation for 1.2.2";}i:24;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.3.0";s:3:"api";s:5:"1.3.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2015-02-27";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:42:"http://opensource.org/licenses/bsd-license";}s:8:"_content";s:11:"BSD License";}s:5:"notes";s:76:"* Set minimum PHP version to 5.3.0 * Mark static methods with static keyword";}i:25;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.4.0";s:3:"api";s:5:"1.4.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2017-02-03";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:42:"http://opensource.org/licenses/bsd-license";}s:8:"_content";s:11:"BSD License";}s:5:"notes";s:203:"* Set minimum PHP version to 5.4.0 * Set minimum PEAR version to 1.10.1 * Adds a new XML_UTIL_COLLAPSE_NONE option for preventing empty tag collapsing. * Request #15467 CDATA sections and blank nodes";}i:26;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.4.1";s:3:"api";s:5:"1.4.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2017-02-07";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:42:"http://opensource.org/licenses/bsd-license";}s:8:"_content";s:11:"BSD License";}s:5:"notes";s:58:"* Bug #21177 XML_Util::collapseEmptyTags() can return NULL";}i:27;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.4.2";s:3:"api";s:5:"1.4.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2017-02-22";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:42:"http://opensource.org/licenses/bsd-license";}s:8:"_content";s:11:"BSD License";}s:5:"notes";s:27:"* Bug #21184 Collapse issue";}i:28;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.4.3";s:3:"api";s:5:"1.4.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2017-06-28";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:42:"http://opensource.org/licenses/bsd-license";}s:8:"_content";s:11:"BSD License";}s:5:"notes";s:63:"* Decrease minimum PEAR version to 1.9.0 to allow PEAR upgrades";}i:29;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.4.4";s:3:"api";s:5:"1.4.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2019-12-05";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:42:"http://opensource.org/licenses/bsd-license";}s:8:"_content";s:11:"BSD License";}s:5:"notes";s:29:"* PR #11: fix phplint warning";}i:30;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.4.5";s:3:"api";s:5:"1.4.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2020-04-19";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:42:"http://opensource.org/licenses/bsd-license";}s:8:"_content";s:11:"BSD License";}s:5:"notes";s:64:"* PR #12: fix Trying to access array offset on value of type int";}}}s:8:"filelist";a:25:{s:20:"examples/example.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"af2746028ae4395f549855a5e444ada7";s:4:"name";s:20:"examples/example.php";s:4:"role";s:3:"doc";s:12:"installed_as";s:63:"/opt/alt/php56/usr/share/doc/pear/XML_Util/examples/example.php";}s:21:"examples/example2.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"b9e52f4aa372c4067c609f49c2285b8f";s:4:"name";s:21:"examples/example2.php";s:4:"role";s:3:"doc";s:12:"installed_as";s:64:"/opt/alt/php56/usr/share/doc/pear/XML_Util/examples/example2.php";}s:27:"tests/AbstractUnitTests.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"d0af9354df0962e70e9e2215b5611b9c";s:4:"name";s:27:"tests/AbstractUnitTests.php";s:4:"role";s:4:"test";s:12:"installed_as";s:71:"/opt/alt/php56/usr/share/pear/test/XML_Util/tests/AbstractUnitTests.php";}s:25:"tests/ApiVersionTests.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"57ce547d64d6e1f2986c313407deffef";s:4:"name";s:25:"tests/ApiVersionTests.php";s:4:"role";s:4:"test";s:12:"installed_as";s:69:"/opt/alt/php56/usr/share/pear/test/XML_Util/tests/ApiVersionTests.php";}s:33:"tests/AttributesToStringTests.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"2d0427db94790df7ada24a744547edf5";s:4:"name";s:33:"tests/AttributesToStringTests.php";s:4:"role";s:4:"test";s:12:"installed_as";s:77:"/opt/alt/php56/usr/share/pear/test/XML_Util/tests/AttributesToStringTests.php";}s:32:"tests/CollapseEmptyTagsTests.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"673d1438c4718a70c5da3fe019027db4";s:4:"name";s:32:"tests/CollapseEmptyTagsTests.php";s:4:"role";s:4:"test";s:12:"installed_as";s:76:"/opt/alt/php56/usr/share/pear/test/XML_Util/tests/CollapseEmptyTagsTests.php";}s:33:"tests/CreateCDataSectionTests.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"46b981f91edd163f1cd021cfef5d1bb1";s:4:"name";s:33:"tests/CreateCDataSectionTests.php";s:4:"role";s:4:"test";s:12:"installed_as";s:77:"/opt/alt/php56/usr/share/pear/test/XML_Util/tests/CreateCDataSectionTests.php";}s:28:"tests/CreateCommentTests.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"6aa925b879572e9b3f1885b7cdbb223b";s:4:"name";s:28:"tests/CreateCommentTests.php";s:4:"role";s:4:"test";s:12:"installed_as";s:72:"/opt/alt/php56/usr/share/pear/test/XML_Util/tests/CreateCommentTests.php";}s:31:"tests/CreateEndElementTests.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"dbc083b62a020fa245fde5a7828a4806";s:4:"name";s:31:"tests/CreateEndElementTests.php";s:4:"role";s:4:"test";s:12:"installed_as";s:75:"/opt/alt/php56/usr/share/pear/test/XML_Util/tests/CreateEndElementTests.php";}s:33:"tests/CreateStartElementTests.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"f58e38343ecf60811c842d4cfc8194ae";s:4:"name";s:33:"tests/CreateStartElementTests.php";s:4:"role";s:4:"test";s:12:"installed_as";s:77:"/opt/alt/php56/usr/share/pear/test/XML_Util/tests/CreateStartElementTests.php";}s:24:"tests/CreateTagTests.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"9385fba272f4ebccf4c95d43d16dcff4";s:4:"name";s:24:"tests/CreateTagTests.php";s:4:"role";s:4:"test";s:12:"installed_as";s:68:"/opt/alt/php56/usr/share/pear/test/XML_Util/tests/CreateTagTests.php";}s:33:"tests/CreateTagFromArrayTests.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"51e7ba1390e6dadc3c0be0c960bf171d";s:4:"name";s:33:"tests/CreateTagFromArrayTests.php";s:4:"role";s:4:"test";s:12:"installed_as";s:77:"/opt/alt/php56/usr/share/pear/test/XML_Util/tests/CreateTagFromArrayTests.php";}s:36:"tests/GetDocTypeDeclarationTests.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"6bbb54ef4cf56dc2c0b558b295de5668";s:4:"name";s:36:"tests/GetDocTypeDeclarationTests.php";s:4:"role";s:4:"test";s:12:"installed_as";s:80:"/opt/alt/php56/usr/share/pear/test/XML_Util/tests/GetDocTypeDeclarationTests.php";}s:32:"tests/GetXmlDeclarationTests.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"825b440b0ee8abd10b4df017c08bf15f";s:4:"name";s:32:"tests/GetXmlDeclarationTests.php";s:4:"role";s:4:"test";s:12:"installed_as";s:76:"/opt/alt/php56/usr/share/pear/test/XML_Util/tests/GetXmlDeclarationTests.php";}s:26:"tests/IsValidNameTests.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"e6783bb330f8f2ae7225f02d56f194e4";s:4:"name";s:26:"tests/IsValidNameTests.php";s:4:"role";s:4:"test";s:12:"installed_as";s:70:"/opt/alt/php56/usr/share/pear/test/XML_Util/tests/IsValidNameTests.php";}s:25:"tests/RaiseErrorTests.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"b273525b905ae6d5fc53adcb3ce0b8d9";s:4:"name";s:25:"tests/RaiseErrorTests.php";s:4:"role";s:4:"test";s:12:"installed_as";s:69:"/opt/alt/php56/usr/share/pear/test/XML_Util/tests/RaiseErrorTests.php";}s:30:"tests/ReplaceEntitiesTests.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"20befbef5e55639539336761a17c64f3";s:4:"name";s:30:"tests/ReplaceEntitiesTests.php";s:4:"role";s:4:"test";s:12:"installed_as";s:74:"/opt/alt/php56/usr/share/pear/test/XML_Util/tests/ReplaceEntitiesTests.php";}s:30:"tests/ReverseEntitiesTests.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"a3ceff3302e31f90130be01c312b33b3";s:4:"name";s:30:"tests/ReverseEntitiesTests.php";s:4:"role";s:4:"test";s:12:"installed_as";s:74:"/opt/alt/php56/usr/share/pear/test/XML_Util/tests/ReverseEntitiesTests.php";}s:33:"tests/SplitQualifiedNameTests.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"aeb95108896180ef77a7dce3c310a3b8";s:4:"name";s:33:"tests/SplitQualifiedNameTests.php";s:4:"role";s:4:"test";s:12:"installed_as";s:77:"/opt/alt/php56/usr/share/pear/test/XML_Util/tests/SplitQualifiedNameTests.php";}s:22:"tests/Bug4950Tests.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"e93010b1eff68f889fefcb006bf20b63";s:4:"name";s:22:"tests/Bug4950Tests.php";s:4:"role";s:4:"test";s:12:"installed_as";s:66:"/opt/alt/php56/usr/share/pear/test/XML_Util/tests/Bug4950Tests.php";}s:22:"tests/Bug5392Tests.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"748ffb640e13e7b960385c7e12413782";s:4:"name";s:22:"tests/Bug5392Tests.php";s:4:"role";s:4:"test";s:12:"installed_as";s:66:"/opt/alt/php56/usr/share/pear/test/XML_Util/tests/Bug5392Tests.php";}s:23:"tests/Bug18343Tests.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"01e68b66e27a6fdb197d572c67ae6bc5";s:4:"name";s:23:"tests/Bug18343Tests.php";s:4:"role";s:4:"test";s:12:"installed_as";s:67:"/opt/alt/php56/usr/share/pear/test/XML_Util/tests/Bug18343Tests.php";}s:23:"tests/Bug21177Tests.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"d945220c38344bc773b18244439bb0cc";s:4:"name";s:23:"tests/Bug21177Tests.php";s:4:"role";s:4:"test";s:12:"installed_as";s:67:"/opt/alt/php56/usr/share/pear/test/XML_Util/tests/Bug21177Tests.php";}s:23:"tests/Bug21184Tests.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"af2672bb90875c2e00f93f563bfafe70";s:4:"name";s:23:"tests/Bug21184Tests.php";s:4:"role";s:4:"test";s:12:"installed_as";s:67:"/opt/alt/php56/usr/share/pear/test/XML_Util/tests/Bug21184Tests.php";}s:12:"XML/Util.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"0db6fa9c169bf6904aa7e588c2325a13";s:4:"name";s:12:"XML/Util.php";s:4:"role";s:3:"php";s:12:"installed_as";s:42:"/opt/alt/php56/usr/share/pear/XML/Util.php";}}s:12:"_lastversion";N;s:7:"dirtree";a:5:{s:51:"/opt/alt/php56/usr/share/doc/pear/XML_Util/examples";b:1;s:42:"/opt/alt/php56/usr/share/doc/pear/XML_Util";b:1;s:49:"/opt/alt/php56/usr/share/pear/test/XML_Util/tests";b:1;s:43:"/opt/alt/php56/usr/share/pear/test/XML_Util";b:1;s:33:"/opt/alt/php56/usr/share/pear/XML";b:1;}s:3:"old";a:7:{s:7:"version";s:5:"1.4.5";s:12:"release_date";s:10:"2020-04-19";s:13:"release_state";s:6:"stable";s:15:"release_license";s:11:"BSD License";s:13:"release_notes";s:64:"* PR #12: fix Trying to access array offset on value of type int";s:12:"release_deps";a:3:{i:0;a:4:{s:4:"type";s:3:"php";s:3:"rel";s:2:"ge";s:7:"version";s:5:"5.4.0";s:8:"optional";s:2:"no";}i:1;a:6:{s:4:"type";s:3:"pkg";s:7:"channel";s:12:"pear.php.net";s:4:"name";s:4:"PEAR";s:3:"rel";s:2:"ge";s:7:"version";s:5:"1.9.0";s:8:"optional";s:2:"no";}i:2;a:4:{s:4:"type";s:3:"ext";s:4:"name";s:4:"pcre";s:3:"rel";s:3:"has";s:8:"optional";s:2:"no";}}s:11:"maintainers";a:3:{i:0;a:5:{s:4:"name";s:13:"Chuck Burgess";s:5:"email";s:15:"ashnazg@php.net";s:6:"active";s:3:"yes";s:6:"handle";s:7:"ashnazg";s:4:"role";s:4:"lead";}i:1;a:5:{s:4:"name";s:15:"Stephan Schmidt";s:5:"email";s:19:"schst@php-tools.net";s:6:"active";s:2:"no";s:6:"handle";s:5:"schst";s:4:"role";s:4:"lead";}i:2;a:5:{s:4:"name";s:12:"Davey Shafik";s:5:"email";s:13:"davey@php.net";s:6:"active";s:2:"no";s:6:"handle";s:5:"davey";s:4:"role";s:6:"helper";}}}s:10:"xsdversion";s:3:"2.0";s:13:"_lastmodified";i:1747068539;}PK�����u]I(��(����.registry/file_marc.regnu�[��������a:21:{s:7:"attribs";a:6:{s:15:"packagerversion";s:6:"1.10.9";s:7:"version";s:3:"2.0";s:5:"xmlns";s:35:"http://pear.php.net/dtd/package-2.0";s:11:"xmlns:tasks";s:33:"http://pear.php.net/dtd/tasks-1.0";s:9:"xmlns:xsi";s:41:"http://www.w3.org/2001/XMLSchema-instance";s:18:"xsi:schemaLocation";s:147:"http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd";}s:4:"name";s:9:"File_MARC";s:7:"channel";s:12:"pear.php.net";s:7:"summary";s:38:"Parse, modify, and create MARC records";s:11:"description";s:574:"The standard for machine-readable cataloging (MARC) records is documented at http://loc.gov/marc/. This package enables you to read existing MARC records from a file, string, or (using the YAZ extension), from a Z39.50 source. You can also use this package to create new MARC records. This package is based on the PHP MARC package, originally called "php-marc", that is part of the Emilda Project (http://www.emilda.org). Christoffer Landtman generously agreed to make the "php-marc" code available under the GNU LGPL so it could be used as the basis of this PEAR package.";s:4:"lead";a:4:{s:4:"name";s:9:"Dan Scott";s:4:"user";s:3:"dbs";s:5:"email";s:11:"dbs@php.net";s:6:"active";s:3:"yes";}s:4:"date";s:10:"2019-11-13";s:4:"time";s:8:"17:33:33";s:7:"version";a:2:{s:7:"release";s:5:"1.4.1";s:3:"api";s:5:"1.4.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:39:"http://www.gnu.org/copyleft/lesser.html";}s:8:"_content";s:33:"GNU Lesser General Public License";}s:5:"notes";s:51:"1.4.1 * Reintroduce include_path to composer.json";s:8:"contents";a:1:{s:3:"dir";a:2:{s:7:"attribs";a:2:{s:14:"baseinstalldir";s:4:"File";s:4:"name";s:1:"/";}s:4:"file";a:82:{i:0;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"ffe2590635f404af055fe731da105939";s:4:"name";s:27:"File/MARC/Lint/CodeData.php";s:4:"role";s:3:"php";}}i:1;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"a3b9e1c817e67f59add05593500d463e";s:4:"name";s:27:"File/MARC/Control_Field.php";s:4:"role";s:3:"php";}}i:2;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"acba4463f8e40d6ee4e7ba1f2dc53123";s:4:"name";s:24:"File/MARC/Data_Field.php";s:4:"role";s:3:"php";}}i:3;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"378f483ec1fd161cd9dfb9b05db58d66";s:4:"name";s:23:"File/MARC/Exception.php";s:4:"role";s:3:"php";}}i:4;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"a9ba69030cbf4847292b9975e9d922c6";s:4:"name";s:19:"File/MARC/Field.php";s:4:"role";s:3:"php";}}i:5;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"c37351c7c80927ce6bb1e662510f9183";s:4:"name";s:18:"File/MARC/Lint.php";s:4:"role";s:3:"php";}}i:6;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"c5ac39e3d25eb0108b9dd5ad8466c821";s:4:"name";s:18:"File/MARC/List.php";s:4:"role";s:3:"php";}}i:7;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"7af6ce78cde4bb246e4e96709e90d2c0";s:4:"name";s:20:"File/MARC/Record.php";s:4:"role";s:3:"php";}}i:8;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"df5f97139685f0ad04e47fdbb67e3968";s:4:"name";s:22:"File/MARC/Subfield.php";s:4:"role";s:3:"php";}}i:9;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"6e102262dfd5d65d8d5a6221dfc74edd";s:4:"name";s:13:"File/MARC.php";s:4:"role";s:3:"php";}}i:10;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"8b64040d2d18ac4b994595a148266a66";s:4:"name";s:17:"File/MARCBASE.php";s:4:"role";s:3:"php";}}i:11;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"f5a17a60d34e84e2ee7ca1e5c5c6c620";s:4:"name";s:16:"File/MARCXML.php";s:4:"role";s:3:"php";}}i:12;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"6af971fd9ff5ef3e5fcba8a64a0e7a49";s:4:"name";s:20:"examples/example.mrc";s:4:"role";s:3:"doc";}}i:13;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"1aea40df9f1c2e32f8e065fe8da0a3b5";s:4:"name";s:21:"examples/marc_yaz.php";s:4:"role";s:3:"doc";}}i:14;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"70ae317e0890d5896e3ffccdd293369a";s:4:"name";s:17:"examples/read.php";s:4:"role";s:3:"doc";}}i:15;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"54efb9d920ac775bfc847a83a2dec73a";s:4:"name";s:22:"examples/subfields.php";s:4:"role";s:3:"doc";}}i:16;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"14297da35b510c496cd1f328cf3bb301";s:4:"name";s:21:"tests/bad_example.mrc";s:4:"role";s:4:"test";}}i:17;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"0dd4c6dbad6e8608d0ebf9d24425955d";s:4:"name";s:21:"tests/bad_example.xml";s:4:"role";s:4:"test";}}i:18;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"216a6f9d53f6d3d8e22d81fdc10f4bc1";s:4:"name";s:15:"tests/camel.mrc";s:4:"role";s:4:"test";}}i:19;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"6af971fd9ff5ef3e5fcba8a64a0e7a49";s:4:"name";s:17:"tests/example.mrc";s:4:"role";s:4:"test";}}i:20;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"9455aec3371f79cf7d31281fd03f5171";s:4:"name";s:19:"tests/marc_001.phpt";s:4:"role";s:4:"test";}}i:21;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"577e2f5f89fd48cf1a3576a29d2958f8";s:4:"name";s:19:"tests/marc_002.phpt";s:4:"role";s:4:"test";}}i:22;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"a6a586354b9a06c880c2a7470dd828d7";s:4:"name";s:19:"tests/marc_003.phpt";s:4:"role";s:4:"test";}}i:23;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"b1c7e2fc5572a0f9362a771c260a1fe3";s:4:"name";s:19:"tests/marc_004.phpt";s:4:"role";s:4:"test";}}i:24;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"84f85ac7f8a2532e4e90ccde7764556a";s:4:"name";s:19:"tests/marc_005.phpt";s:4:"role";s:4:"test";}}i:25;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"889e5e906a97de7a0e94b0c5f30e70e7";s:4:"name";s:19:"tests/marc_006.phpt";s:4:"role";s:4:"test";}}i:26;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"be823dc8a8efb408de06371ab802efcc";s:4:"name";s:19:"tests/marc_007.phpt";s:4:"role";s:4:"test";}}i:27;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"af44490aafea44e5120f881cb81cdad9";s:4:"name";s:19:"tests/marc_008.phpt";s:4:"role";s:4:"test";}}i:28;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"ac9f2a7aeb24900a11f5102744179ae3";s:4:"name";s:19:"tests/marc_009.phpt";s:4:"role";s:4:"test";}}i:29;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"5e43eb5cddbb4f2bd0d6405cd95b80aa";s:4:"name";s:19:"tests/marc_010.phpt";s:4:"role";s:4:"test";}}i:30;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"2e1cd8509c0bf04ec77fc0f51375f611";s:4:"name";s:19:"tests/marc_011.phpt";s:4:"role";s:4:"test";}}i:31;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"bc49ca48623102c8ac07679fa77a3dd9";s:4:"name";s:19:"tests/marc_012.phpt";s:4:"role";s:4:"test";}}i:32;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"245a3b20e0da1973535503e28efd1d3a";s:4:"name";s:19:"tests/marc_013.phpt";s:4:"role";s:4:"test";}}i:33;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"ce69aa734856dd40d60d30c77bdef53a";s:4:"name";s:19:"tests/marc_014.phpt";s:4:"role";s:4:"test";}}i:34;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"7b61cdd31035e60682fa92c5d519d997";s:4:"name";s:19:"tests/marc_015.phpt";s:4:"role";s:4:"test";}}i:35;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"7f4f597fe1adaa3507eb87fc4875dbd2";s:4:"name";s:19:"tests/marc_016.phpt";s:4:"role";s:4:"test";}}i:36;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"4262efd5fcacbd7503323681f4552430";s:4:"name";s:19:"tests/marc_017.phpt";s:4:"role";s:4:"test";}}i:37;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"ee1623d7bda54ba4f741b2319b158f82";s:4:"name";s:19:"tests/marc_018.phpt";s:4:"role";s:4:"test";}}i:38;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"8006c03fbab0f04377342086fafd3982";s:4:"name";s:19:"tests/marc_019.phpt";s:4:"role";s:4:"test";}}i:39;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"f5ae5b25e0ac1104314433d9e5b1f7fe";s:4:"name";s:19:"tests/marc_020.phpt";s:4:"role";s:4:"test";}}i:40;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"94d8f99e86585671a1b2d3043aeb6360";s:4:"name";s:19:"tests/marc_021.phpt";s:4:"role";s:4:"test";}}i:41;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"bb891a890effe0e77e1759043f4846d8";s:4:"name";s:19:"tests/marc_022.phpt";s:4:"role";s:4:"test";}}i:42;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"faf77dcb5cdd002c09169a14bfded65e";s:4:"name";s:19:"tests/marc_023.phpt";s:4:"role";s:4:"test";}}i:43;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"0e6c4a23f5da7df64fdd4b3b1149bbee";s:4:"name";s:21:"tests/marc_16783.phpt";s:4:"role";s:4:"test";}}i:44;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"4ea8b3520beda378db15960f1c50493a";s:4:"name";s:25:"tests/marc_field_001.phpt";s:4:"role";s:4:"test";}}i:45;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"743850ef61df69c4340be44a03bccb5a";s:4:"name";s:25:"tests/marc_field_002.phpt";s:4:"role";s:4:"test";}}i:46;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"8c765f1398b49df257d86d22ac6e4f8d";s:4:"name";s:25:"tests/marc_field_003.phpt";s:4:"role";s:4:"test";}}i:47;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"d4216cf930a308e0d02553bd3914f294";s:4:"name";s:25:"tests/marc_field_004.phpt";s:4:"role";s:4:"test";}}i:48;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"dd59514b474b78371ad522a3e13b76b7";s:4:"name";s:25:"tests/marc_field_005.phpt";s:4:"role";s:4:"test";}}i:49;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"5295bfd02a8424acac1c91de26b552c7";s:4:"name";s:27:"tests/marc_field_21246.phpt";s:4:"role";s:4:"test";}}i:50;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"6f95f09442ccf6b93df92986f58b270d";s:4:"name";s:24:"tests/marc_lint_001.phpt";s:4:"role";s:4:"test";}}i:51;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"18d721f8871edd925624ccbdd15444fb";s:4:"name";s:24:"tests/marc_lint_002.phpt";s:4:"role";s:4:"test";}}i:52;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"4eb86a2f4e0a74dedcb0bf2511da6ca1";s:4:"name";s:24:"tests/marc_lint_003.phpt";s:4:"role";s:4:"test";}}i:53;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"10430fee0a1352d0528f1507b34c57e1";s:4:"name";s:24:"tests/marc_lint_004.phpt";s:4:"role";s:4:"test";}}i:54;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"0dcd07a18577d7b22392a2214cd6436c";s:4:"name";s:24:"tests/marc_lint_005.phpt";s:4:"role";s:4:"test";}}i:55;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"fd17798fc535562e5e64461f449516b2";s:4:"name";s:26:"tests/marc_record_001.phpt";s:4:"role";s:4:"test";}}i:56;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"141b455ccf67a60c4eac44c77960f2e2";s:4:"name";s:28:"tests/marc_subfield_001.phpt";s:4:"role";s:4:"test";}}i:57;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"b1e23464ee0eec47ddca2af9a9922926";s:4:"name";s:28:"tests/marc_subfield_002.phpt";s:4:"role";s:4:"test";}}i:58;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"1d7903e8c244d647220b318b4bc758d1";s:4:"name";s:23:"tests/marc_xml_001.phpt";s:4:"role";s:4:"test";}}i:59;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"22cae3c752d843b78f583dcd92801534";s:4:"name";s:23:"tests/marc_xml_002.phpt";s:4:"role";s:4:"test";}}i:60;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"c0716d23e0f960abf8d53ad6014a413a";s:4:"name";s:23:"tests/marc_xml_003.phpt";s:4:"role";s:4:"test";}}i:61;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"7645fa19e28aca041a124fc5e2c12bd3";s:4:"name";s:23:"tests/marc_xml_004.phpt";s:4:"role";s:4:"test";}}i:62;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"b08b28c3251625b8b6e4d7ab376b0185";s:4:"name";s:23:"tests/marc_xml_005.phpt";s:4:"role";s:4:"test";}}i:63;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"6cd0934ddbf65d2d7e9ea5d108977ff7";s:4:"name";s:23:"tests/marc_xml_006.phpt";s:4:"role";s:4:"test";}}i:64;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"ffdce4aa190268fa7cbbf3bb45383abf";s:4:"name";s:23:"tests/marc_xml_007.phpt";s:4:"role";s:4:"test";}}i:65;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"998a4c1ce00ff100f39ffa9fc49a212f";s:4:"name";s:23:"tests/marc_xml_008.phpt";s:4:"role";s:4:"test";}}i:66;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"a38a67c590869f2b0a4859a910fd9e89";s:4:"name";s:23:"tests/marc_xml_009.phpt";s:4:"role";s:4:"test";}}i:67;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"db39c5055a570fcda12bb7c5fa1e3b4d";s:4:"name";s:25:"tests/marc_xml_16642.phpt";s:4:"role";s:4:"test";}}i:68;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"dc075f4a271bd7182378a3874bd5b39e";s:4:"name";s:29:"tests/marc_xml_namespace.phpt";s:4:"role";s:4:"test";}}i:69;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"208200d9a979ac360c4d326e9789b6b7";s:4:"name";s:36:"tests/marc_xml_namespace_prefix.phpt";s:4:"role";s:4:"test";}}i:70;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"d87774ede82222cfc12b2c2a06f57a3a";s:4:"name";s:27:"tests/marc_xml_rsinger.phpt";s:4:"role";s:4:"test";}}i:71;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"fb44e3eb69f1a37115235fc829c39542";s:4:"name";s:19:"tests/namespace.xml";s:4:"role";s:4:"test";}}i:72;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"e6de4d809b0af5dd99fd352eb60616a1";s:4:"name";s:16:"tests/skipif.inc";s:4:"role";s:4:"test";}}i:73;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"a0166a4ff0bc0bb283e854f11beaa793";s:4:"name";s:15:"tests/music.mrc";s:4:"role";s:4:"test";}}i:74;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"993ce494befbc25dc1326527b30b4782";s:4:"name";s:15:"tests/music.xml";s:4:"role";s:4:"test";}}i:75;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"6b0c87f0cd459ed7322c25d403b164cc";s:4:"name";s:20:"tests/bigarchive.xml";s:4:"role";s:4:"test";}}i:76;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"be850aa6ab4ac52b8c6c214c30b574af";s:4:"name";s:19:"tests/onerecord.xml";s:4:"role";s:4:"test";}}i:77;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"4f43fec7b276267eec5258044853ccc8";s:4:"name";s:18:"tests/sandburg.mrc";s:4:"role";s:4:"test";}}i:78;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"e216b95f905dd240c9bde372950e4073";s:4:"name";s:18:"tests/sandburg.xml";s:4:"role";s:4:"test";}}i:79;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"e81a92188ea0dcd9c108a63fb32b3f4f";s:4:"name";s:19:"tests/xmlescape.mrc";s:4:"role";s:4:"test";}}i:80;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"8f9f63ed6a80191d89a2296fa4c1a30b";s:4:"name";s:9:"CHANGELOG";s:4:"role";s:3:"doc";}}i:81;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"fbc093901857fcd118f065f900982c24";s:4:"name";s:7:"LICENSE";s:4:"role";s:3:"doc";}}}}}s:12:"dependencies";a:2:{s:8:"required";a:2:{s:3:"php";a:1:{s:3:"min";s:3:"5.6";}s:13:"pearinstaller";a:1:{s:3:"min";s:5:"1.4.0";}}s:8:"optional";a:1:{s:7:"package";a:2:{s:4:"name";s:13:"Validate_ISPN";s:7:"channel";s:12:"pear.php.net";}}}s:10:"phprelease";s:0:"";s:8:"filelist";a:82:{s:27:"File/MARC/Lint/CodeData.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"ffe2590635f404af055fe731da105939";s:4:"name";s:27:"File/MARC/Lint/CodeData.php";s:4:"role";s:3:"php";s:12:"installed_as";s:57:"/opt/alt/php56/usr/share/pear/File/MARC/Lint/CodeData.php";}s:27:"File/MARC/Control_Field.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"a3b9e1c817e67f59add05593500d463e";s:4:"name";s:27:"File/MARC/Control_Field.php";s:4:"role";s:3:"php";s:12:"installed_as";s:57:"/opt/alt/php56/usr/share/pear/File/MARC/Control_Field.php";}s:24:"File/MARC/Data_Field.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"acba4463f8e40d6ee4e7ba1f2dc53123";s:4:"name";s:24:"File/MARC/Data_Field.php";s:4:"role";s:3:"php";s:12:"installed_as";s:54:"/opt/alt/php56/usr/share/pear/File/MARC/Data_Field.php";}s:23:"File/MARC/Exception.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"378f483ec1fd161cd9dfb9b05db58d66";s:4:"name";s:23:"File/MARC/Exception.php";s:4:"role";s:3:"php";s:12:"installed_as";s:53:"/opt/alt/php56/usr/share/pear/File/MARC/Exception.php";}s:19:"File/MARC/Field.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"a9ba69030cbf4847292b9975e9d922c6";s:4:"name";s:19:"File/MARC/Field.php";s:4:"role";s:3:"php";s:12:"installed_as";s:49:"/opt/alt/php56/usr/share/pear/File/MARC/Field.php";}s:18:"File/MARC/Lint.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"c37351c7c80927ce6bb1e662510f9183";s:4:"name";s:18:"File/MARC/Lint.php";s:4:"role";s:3:"php";s:12:"installed_as";s:48:"/opt/alt/php56/usr/share/pear/File/MARC/Lint.php";}s:18:"File/MARC/List.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"c5ac39e3d25eb0108b9dd5ad8466c821";s:4:"name";s:18:"File/MARC/List.php";s:4:"role";s:3:"php";s:12:"installed_as";s:48:"/opt/alt/php56/usr/share/pear/File/MARC/List.php";}s:20:"File/MARC/Record.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"7af6ce78cde4bb246e4e96709e90d2c0";s:4:"name";s:20:"File/MARC/Record.php";s:4:"role";s:3:"php";s:12:"installed_as";s:50:"/opt/alt/php56/usr/share/pear/File/MARC/Record.php";}s:22:"File/MARC/Subfield.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"df5f97139685f0ad04e47fdbb67e3968";s:4:"name";s:22:"File/MARC/Subfield.php";s:4:"role";s:3:"php";s:12:"installed_as";s:52:"/opt/alt/php56/usr/share/pear/File/MARC/Subfield.php";}s:13:"File/MARC.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"6e102262dfd5d65d8d5a6221dfc74edd";s:4:"name";s:13:"File/MARC.php";s:4:"role";s:3:"php";s:12:"installed_as";s:43:"/opt/alt/php56/usr/share/pear/File/MARC.php";}s:17:"File/MARCBASE.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"8b64040d2d18ac4b994595a148266a66";s:4:"name";s:17:"File/MARCBASE.php";s:4:"role";s:3:"php";s:12:"installed_as";s:47:"/opt/alt/php56/usr/share/pear/File/MARCBASE.php";}s:16:"File/MARCXML.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"f5a17a60d34e84e2ee7ca1e5c5c6c620";s:4:"name";s:16:"File/MARCXML.php";s:4:"role";s:3:"php";s:12:"installed_as";s:46:"/opt/alt/php56/usr/share/pear/File/MARCXML.php";}s:20:"examples/example.mrc";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"6af971fd9ff5ef3e5fcba8a64a0e7a49";s:4:"name";s:20:"examples/example.mrc";s:4:"role";s:3:"doc";s:12:"installed_as";s:64:"/opt/alt/php56/usr/share/doc/pear/File_MARC/examples/example.mrc";}s:21:"examples/marc_yaz.php";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"1aea40df9f1c2e32f8e065fe8da0a3b5";s:4:"name";s:21:"examples/marc_yaz.php";s:4:"role";s:3:"doc";s:12:"installed_as";s:65:"/opt/alt/php56/usr/share/doc/pear/File_MARC/examples/marc_yaz.php";}s:17:"examples/read.php";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"70ae317e0890d5896e3ffccdd293369a";s:4:"name";s:17:"examples/read.php";s:4:"role";s:3:"doc";s:12:"installed_as";s:61:"/opt/alt/php56/usr/share/doc/pear/File_MARC/examples/read.php";}s:22:"examples/subfields.php";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"54efb9d920ac775bfc847a83a2dec73a";s:4:"name";s:22:"examples/subfields.php";s:4:"role";s:3:"doc";s:12:"installed_as";s:66:"/opt/alt/php56/usr/share/doc/pear/File_MARC/examples/subfields.php";}s:21:"tests/bad_example.mrc";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"14297da35b510c496cd1f328cf3bb301";s:4:"name";s:21:"tests/bad_example.mrc";s:4:"role";s:4:"test";s:12:"installed_as";s:66:"/opt/alt/php56/usr/share/pear/test/File_MARC/tests/bad_example.mrc";}s:21:"tests/bad_example.xml";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"0dd4c6dbad6e8608d0ebf9d24425955d";s:4:"name";s:21:"tests/bad_example.xml";s:4:"role";s:4:"test";s:12:"installed_as";s:66:"/opt/alt/php56/usr/share/pear/test/File_MARC/tests/bad_example.xml";}s:15:"tests/camel.mrc";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"216a6f9d53f6d3d8e22d81fdc10f4bc1";s:4:"name";s:15:"tests/camel.mrc";s:4:"role";s:4:"test";s:12:"installed_as";s:60:"/opt/alt/php56/usr/share/pear/test/File_MARC/tests/camel.mrc";}s:17:"tests/example.mrc";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"6af971fd9ff5ef3e5fcba8a64a0e7a49";s:4:"name";s:17:"tests/example.mrc";s:4:"role";s:4:"test";s:12:"installed_as";s:62:"/opt/alt/php56/usr/share/pear/test/File_MARC/tests/example.mrc";}s:19:"tests/marc_001.phpt";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"9455aec3371f79cf7d31281fd03f5171";s:4:"name";s:19:"tests/marc_001.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:64:"/opt/alt/php56/usr/share/pear/test/File_MARC/tests/marc_001.phpt";}s:19:"tests/marc_002.phpt";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"577e2f5f89fd48cf1a3576a29d2958f8";s:4:"name";s:19:"tests/marc_002.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:64:"/opt/alt/php56/usr/share/pear/test/File_MARC/tests/marc_002.phpt";}s:19:"tests/marc_003.phpt";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"a6a586354b9a06c880c2a7470dd828d7";s:4:"name";s:19:"tests/marc_003.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:64:"/opt/alt/php56/usr/share/pear/test/File_MARC/tests/marc_003.phpt";}s:19:"tests/marc_004.phpt";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"b1c7e2fc5572a0f9362a771c260a1fe3";s:4:"name";s:19:"tests/marc_004.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:64:"/opt/alt/php56/usr/share/pear/test/File_MARC/tests/marc_004.phpt";}s:19:"tests/marc_005.phpt";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"84f85ac7f8a2532e4e90ccde7764556a";s:4:"name";s:19:"tests/marc_005.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:64:"/opt/alt/php56/usr/share/pear/test/File_MARC/tests/marc_005.phpt";}s:19:"tests/marc_006.phpt";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"889e5e906a97de7a0e94b0c5f30e70e7";s:4:"name";s:19:"tests/marc_006.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:64:"/opt/alt/php56/usr/share/pear/test/File_MARC/tests/marc_006.phpt";}s:19:"tests/marc_007.phpt";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"be823dc8a8efb408de06371ab802efcc";s:4:"name";s:19:"tests/marc_007.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:64:"/opt/alt/php56/usr/share/pear/test/File_MARC/tests/marc_007.phpt";}s:19:"tests/marc_008.phpt";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"af44490aafea44e5120f881cb81cdad9";s:4:"name";s:19:"tests/marc_008.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:64:"/opt/alt/php56/usr/share/pear/test/File_MARC/tests/marc_008.phpt";}s:19:"tests/marc_009.phpt";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"ac9f2a7aeb24900a11f5102744179ae3";s:4:"name";s:19:"tests/marc_009.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:64:"/opt/alt/php56/usr/share/pear/test/File_MARC/tests/marc_009.phpt";}s:19:"tests/marc_010.phpt";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"5e43eb5cddbb4f2bd0d6405cd95b80aa";s:4:"name";s:19:"tests/marc_010.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:64:"/opt/alt/php56/usr/share/pear/test/File_MARC/tests/marc_010.phpt";}s:19:"tests/marc_011.phpt";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"2e1cd8509c0bf04ec77fc0f51375f611";s:4:"name";s:19:"tests/marc_011.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:64:"/opt/alt/php56/usr/share/pear/test/File_MARC/tests/marc_011.phpt";}s:19:"tests/marc_012.phpt";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"bc49ca48623102c8ac07679fa77a3dd9";s:4:"name";s:19:"tests/marc_012.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:64:"/opt/alt/php56/usr/share/pear/test/File_MARC/tests/marc_012.phpt";}s:19:"tests/marc_013.phpt";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"245a3b20e0da1973535503e28efd1d3a";s:4:"name";s:19:"tests/marc_013.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:64:"/opt/alt/php56/usr/share/pear/test/File_MARC/tests/marc_013.phpt";}s:19:"tests/marc_014.phpt";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"ce69aa734856dd40d60d30c77bdef53a";s:4:"name";s:19:"tests/marc_014.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:64:"/opt/alt/php56/usr/share/pear/test/File_MARC/tests/marc_014.phpt";}s:19:"tests/marc_015.phpt";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"7b61cdd31035e60682fa92c5d519d997";s:4:"name";s:19:"tests/marc_015.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:64:"/opt/alt/php56/usr/share/pear/test/File_MARC/tests/marc_015.phpt";}s:19:"tests/marc_016.phpt";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"7f4f597fe1adaa3507eb87fc4875dbd2";s:4:"name";s:19:"tests/marc_016.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:64:"/opt/alt/php56/usr/share/pear/test/File_MARC/tests/marc_016.phpt";}s:19:"tests/marc_017.phpt";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"4262efd5fcacbd7503323681f4552430";s:4:"name";s:19:"tests/marc_017.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:64:"/opt/alt/php56/usr/share/pear/test/File_MARC/tests/marc_017.phpt";}s:19:"tests/marc_018.phpt";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"ee1623d7bda54ba4f741b2319b158f82";s:4:"name";s:19:"tests/marc_018.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:64:"/opt/alt/php56/usr/share/pear/test/File_MARC/tests/marc_018.phpt";}s:19:"tests/marc_019.phpt";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"8006c03fbab0f04377342086fafd3982";s:4:"name";s:19:"tests/marc_019.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:64:"/opt/alt/php56/usr/share/pear/test/File_MARC/tests/marc_019.phpt";}s:19:"tests/marc_020.phpt";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"f5ae5b25e0ac1104314433d9e5b1f7fe";s:4:"name";s:19:"tests/marc_020.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:64:"/opt/alt/php56/usr/share/pear/test/File_MARC/tests/marc_020.phpt";}s:19:"tests/marc_021.phpt";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"94d8f99e86585671a1b2d3043aeb6360";s:4:"name";s:19:"tests/marc_021.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:64:"/opt/alt/php56/usr/share/pear/test/File_MARC/tests/marc_021.phpt";}s:19:"tests/marc_022.phpt";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"bb891a890effe0e77e1759043f4846d8";s:4:"name";s:19:"tests/marc_022.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:64:"/opt/alt/php56/usr/share/pear/test/File_MARC/tests/marc_022.phpt";}s:19:"tests/marc_023.phpt";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"faf77dcb5cdd002c09169a14bfded65e";s:4:"name";s:19:"tests/marc_023.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:64:"/opt/alt/php56/usr/share/pear/test/File_MARC/tests/marc_023.phpt";}s:21:"tests/marc_16783.phpt";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"0e6c4a23f5da7df64fdd4b3b1149bbee";s:4:"name";s:21:"tests/marc_16783.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:66:"/opt/alt/php56/usr/share/pear/test/File_MARC/tests/marc_16783.phpt";}s:25:"tests/marc_field_001.phpt";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"4ea8b3520beda378db15960f1c50493a";s:4:"name";s:25:"tests/marc_field_001.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:70:"/opt/alt/php56/usr/share/pear/test/File_MARC/tests/marc_field_001.phpt";}s:25:"tests/marc_field_002.phpt";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"743850ef61df69c4340be44a03bccb5a";s:4:"name";s:25:"tests/marc_field_002.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:70:"/opt/alt/php56/usr/share/pear/test/File_MARC/tests/marc_field_002.phpt";}s:25:"tests/marc_field_003.phpt";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"8c765f1398b49df257d86d22ac6e4f8d";s:4:"name";s:25:"tests/marc_field_003.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:70:"/opt/alt/php56/usr/share/pear/test/File_MARC/tests/marc_field_003.phpt";}s:25:"tests/marc_field_004.phpt";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"d4216cf930a308e0d02553bd3914f294";s:4:"name";s:25:"tests/marc_field_004.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:70:"/opt/alt/php56/usr/share/pear/test/File_MARC/tests/marc_field_004.phpt";}s:25:"tests/marc_field_005.phpt";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"dd59514b474b78371ad522a3e13b76b7";s:4:"name";s:25:"tests/marc_field_005.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:70:"/opt/alt/php56/usr/share/pear/test/File_MARC/tests/marc_field_005.phpt";}s:27:"tests/marc_field_21246.phpt";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"5295bfd02a8424acac1c91de26b552c7";s:4:"name";s:27:"tests/marc_field_21246.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:72:"/opt/alt/php56/usr/share/pear/test/File_MARC/tests/marc_field_21246.phpt";}s:24:"tests/marc_lint_001.phpt";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"6f95f09442ccf6b93df92986f58b270d";s:4:"name";s:24:"tests/marc_lint_001.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:69:"/opt/alt/php56/usr/share/pear/test/File_MARC/tests/marc_lint_001.phpt";}s:24:"tests/marc_lint_002.phpt";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"18d721f8871edd925624ccbdd15444fb";s:4:"name";s:24:"tests/marc_lint_002.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:69:"/opt/alt/php56/usr/share/pear/test/File_MARC/tests/marc_lint_002.phpt";}s:24:"tests/marc_lint_003.phpt";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"4eb86a2f4e0a74dedcb0bf2511da6ca1";s:4:"name";s:24:"tests/marc_lint_003.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:69:"/opt/alt/php56/usr/share/pear/test/File_MARC/tests/marc_lint_003.phpt";}s:24:"tests/marc_lint_004.phpt";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"10430fee0a1352d0528f1507b34c57e1";s:4:"name";s:24:"tests/marc_lint_004.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:69:"/opt/alt/php56/usr/share/pear/test/File_MARC/tests/marc_lint_004.phpt";}s:24:"tests/marc_lint_005.phpt";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"0dcd07a18577d7b22392a2214cd6436c";s:4:"name";s:24:"tests/marc_lint_005.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:69:"/opt/alt/php56/usr/share/pear/test/File_MARC/tests/marc_lint_005.phpt";}s:26:"tests/marc_record_001.phpt";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"fd17798fc535562e5e64461f449516b2";s:4:"name";s:26:"tests/marc_record_001.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:71:"/opt/alt/php56/usr/share/pear/test/File_MARC/tests/marc_record_001.phpt";}s:28:"tests/marc_subfield_001.phpt";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"141b455ccf67a60c4eac44c77960f2e2";s:4:"name";s:28:"tests/marc_subfield_001.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:73:"/opt/alt/php56/usr/share/pear/test/File_MARC/tests/marc_subfield_001.phpt";}s:28:"tests/marc_subfield_002.phpt";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"b1e23464ee0eec47ddca2af9a9922926";s:4:"name";s:28:"tests/marc_subfield_002.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:73:"/opt/alt/php56/usr/share/pear/test/File_MARC/tests/marc_subfield_002.phpt";}s:23:"tests/marc_xml_001.phpt";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"1d7903e8c244d647220b318b4bc758d1";s:4:"name";s:23:"tests/marc_xml_001.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:68:"/opt/alt/php56/usr/share/pear/test/File_MARC/tests/marc_xml_001.phpt";}s:23:"tests/marc_xml_002.phpt";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"22cae3c752d843b78f583dcd92801534";s:4:"name";s:23:"tests/marc_xml_002.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:68:"/opt/alt/php56/usr/share/pear/test/File_MARC/tests/marc_xml_002.phpt";}s:23:"tests/marc_xml_003.phpt";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"c0716d23e0f960abf8d53ad6014a413a";s:4:"name";s:23:"tests/marc_xml_003.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:68:"/opt/alt/php56/usr/share/pear/test/File_MARC/tests/marc_xml_003.phpt";}s:23:"tests/marc_xml_004.phpt";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"7645fa19e28aca041a124fc5e2c12bd3";s:4:"name";s:23:"tests/marc_xml_004.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:68:"/opt/alt/php56/usr/share/pear/test/File_MARC/tests/marc_xml_004.phpt";}s:23:"tests/marc_xml_005.phpt";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"b08b28c3251625b8b6e4d7ab376b0185";s:4:"name";s:23:"tests/marc_xml_005.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:68:"/opt/alt/php56/usr/share/pear/test/File_MARC/tests/marc_xml_005.phpt";}s:23:"tests/marc_xml_006.phpt";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"6cd0934ddbf65d2d7e9ea5d108977ff7";s:4:"name";s:23:"tests/marc_xml_006.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:68:"/opt/alt/php56/usr/share/pear/test/File_MARC/tests/marc_xml_006.phpt";}s:23:"tests/marc_xml_007.phpt";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"ffdce4aa190268fa7cbbf3bb45383abf";s:4:"name";s:23:"tests/marc_xml_007.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:68:"/opt/alt/php56/usr/share/pear/test/File_MARC/tests/marc_xml_007.phpt";}s:23:"tests/marc_xml_008.phpt";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"998a4c1ce00ff100f39ffa9fc49a212f";s:4:"name";s:23:"tests/marc_xml_008.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:68:"/opt/alt/php56/usr/share/pear/test/File_MARC/tests/marc_xml_008.phpt";}s:23:"tests/marc_xml_009.phpt";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"a38a67c590869f2b0a4859a910fd9e89";s:4:"name";s:23:"tests/marc_xml_009.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:68:"/opt/alt/php56/usr/share/pear/test/File_MARC/tests/marc_xml_009.phpt";}s:25:"tests/marc_xml_16642.phpt";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"db39c5055a570fcda12bb7c5fa1e3b4d";s:4:"name";s:25:"tests/marc_xml_16642.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:70:"/opt/alt/php56/usr/share/pear/test/File_MARC/tests/marc_xml_16642.phpt";}s:29:"tests/marc_xml_namespace.phpt";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"dc075f4a271bd7182378a3874bd5b39e";s:4:"name";s:29:"tests/marc_xml_namespace.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:74:"/opt/alt/php56/usr/share/pear/test/File_MARC/tests/marc_xml_namespace.phpt";}s:36:"tests/marc_xml_namespace_prefix.phpt";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"208200d9a979ac360c4d326e9789b6b7";s:4:"name";s:36:"tests/marc_xml_namespace_prefix.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:81:"/opt/alt/php56/usr/share/pear/test/File_MARC/tests/marc_xml_namespace_prefix.phpt";}s:27:"tests/marc_xml_rsinger.phpt";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"d87774ede82222cfc12b2c2a06f57a3a";s:4:"name";s:27:"tests/marc_xml_rsinger.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:72:"/opt/alt/php56/usr/share/pear/test/File_MARC/tests/marc_xml_rsinger.phpt";}s:19:"tests/namespace.xml";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"fb44e3eb69f1a37115235fc829c39542";s:4:"name";s:19:"tests/namespace.xml";s:4:"role";s:4:"test";s:12:"installed_as";s:64:"/opt/alt/php56/usr/share/pear/test/File_MARC/tests/namespace.xml";}s:16:"tests/skipif.inc";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"e6de4d809b0af5dd99fd352eb60616a1";s:4:"name";s:16:"tests/skipif.inc";s:4:"role";s:4:"test";s:12:"installed_as";s:61:"/opt/alt/php56/usr/share/pear/test/File_MARC/tests/skipif.inc";}s:15:"tests/music.mrc";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"a0166a4ff0bc0bb283e854f11beaa793";s:4:"name";s:15:"tests/music.mrc";s:4:"role";s:4:"test";s:12:"installed_as";s:60:"/opt/alt/php56/usr/share/pear/test/File_MARC/tests/music.mrc";}s:15:"tests/music.xml";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"993ce494befbc25dc1326527b30b4782";s:4:"name";s:15:"tests/music.xml";s:4:"role";s:4:"test";s:12:"installed_as";s:60:"/opt/alt/php56/usr/share/pear/test/File_MARC/tests/music.xml";}s:20:"tests/bigarchive.xml";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"6b0c87f0cd459ed7322c25d403b164cc";s:4:"name";s:20:"tests/bigarchive.xml";s:4:"role";s:4:"test";s:12:"installed_as";s:65:"/opt/alt/php56/usr/share/pear/test/File_MARC/tests/bigarchive.xml";}s:19:"tests/onerecord.xml";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"be850aa6ab4ac52b8c6c214c30b574af";s:4:"name";s:19:"tests/onerecord.xml";s:4:"role";s:4:"test";s:12:"installed_as";s:64:"/opt/alt/php56/usr/share/pear/test/File_MARC/tests/onerecord.xml";}s:18:"tests/sandburg.mrc";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"4f43fec7b276267eec5258044853ccc8";s:4:"name";s:18:"tests/sandburg.mrc";s:4:"role";s:4:"test";s:12:"installed_as";s:63:"/opt/alt/php56/usr/share/pear/test/File_MARC/tests/sandburg.mrc";}s:18:"tests/sandburg.xml";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"e216b95f905dd240c9bde372950e4073";s:4:"name";s:18:"tests/sandburg.xml";s:4:"role";s:4:"test";s:12:"installed_as";s:63:"/opt/alt/php56/usr/share/pear/test/File_MARC/tests/sandburg.xml";}s:19:"tests/xmlescape.mrc";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"e81a92188ea0dcd9c108a63fb32b3f4f";s:4:"name";s:19:"tests/xmlescape.mrc";s:4:"role";s:4:"test";s:12:"installed_as";s:64:"/opt/alt/php56/usr/share/pear/test/File_MARC/tests/xmlescape.mrc";}s:9:"CHANGELOG";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"8f9f63ed6a80191d89a2296fa4c1a30b";s:4:"name";s:9:"CHANGELOG";s:4:"role";s:3:"doc";s:12:"installed_as";s:53:"/opt/alt/php56/usr/share/doc/pear/File_MARC/CHANGELOG";}s:7:"LICENSE";a:5:{s:14:"baseinstalldir";s:4:"File";s:6:"md5sum";s:32:"fbc093901857fcd118f065f900982c24";s:4:"name";s:7:"LICENSE";s:4:"role";s:3:"doc";s:12:"installed_as";s:51:"/opt/alt/php56/usr/share/doc/pear/File_MARC/LICENSE";}}s:12:"_lastversion";N;s:7:"dirtree";a:7:{s:44:"/opt/alt/php56/usr/share/pear/File/MARC/Lint";b:1;s:39:"/opt/alt/php56/usr/share/pear/File/MARC";b:1;s:34:"/opt/alt/php56/usr/share/pear/File";b:1;s:52:"/opt/alt/php56/usr/share/doc/pear/File_MARC/examples";b:1;s:43:"/opt/alt/php56/usr/share/doc/pear/File_MARC";b:1;s:50:"/opt/alt/php56/usr/share/pear/test/File_MARC/tests";b:1;s:44:"/opt/alt/php56/usr/share/pear/test/File_MARC";b:1;}s:3:"old";a:7:{s:7:"version";s:5:"1.4.1";s:12:"release_date";s:10:"2019-11-13";s:13:"release_state";s:6:"stable";s:15:"release_license";s:33:"GNU Lesser General Public License";s:13:"release_notes";s:51:"1.4.1 * Reintroduce include_path to composer.json";s:12:"release_deps";a:3:{i:0;a:4:{s:4:"type";s:3:"php";s:3:"rel";s:2:"ge";s:7:"version";s:3:"5.6";s:8:"optional";s:2:"no";}i:1;a:6:{s:4:"type";s:3:"pkg";s:7:"channel";s:12:"pear.php.net";s:4:"name";s:4:"PEAR";s:3:"rel";s:2:"ge";s:7:"version";s:5:"1.4.0";s:8:"optional";s:2:"no";}i:2;a:5:{s:4:"type";s:3:"pkg";s:7:"channel";s:12:"pear.php.net";s:4:"name";s:13:"Validate_ISPN";s:3:"rel";s:3:"has";s:8:"optional";s:3:"yes";}}s:11:"maintainers";a:1:{i:0;a:5:{s:4:"name";s:9:"Dan Scott";s:5:"email";s:11:"dbs@php.net";s:6:"active";s:3:"yes";s:6:"handle";s:3:"dbs";s:4:"role";s:4:"lead";}}}s:10:"xsdversion";s:3:"2.0";s:13:"_lastmodified";i:1669631553;}PK�����u];VX+��+����.registry/structures_graph.regnu�[��������a:24:{s:7:"attribs";a:6:{s:15:"packagerversion";s:5:"1.9.4";s:7:"version";s:3:"2.0";s:5:"xmlns";s:35:"http://pear.php.net/dtd/package-2.0";s:11:"xmlns:tasks";s:33:"http://pear.php.net/dtd/tasks-1.0";s:9:"xmlns:xsi";s:41:"http://www.w3.org/2001/XMLSchema-instance";s:18:"xsi:schemaLocation";s:159:"http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd";}s:4:"name";s:16:"Structures_Graph";s:7:"channel";s:12:"pear.php.net";s:7:"summary";s:40:"Graph datastructure manipulation library";s:11:"description";s:293:"Structures_Graph is a package for creating and manipulating graph datastructures. It allows building of directed and undirected graphs, with data and metadata stored in nodes. The library provides functions for graph traversing as well as for characteristic extraction from the graph topology.";s:4:"lead";a:4:{s:4:"name";s:16:"Sérgio Carvalho";s:4:"user";s:9:"sergiosgc";s:5:"email";s:32:"sergio.carvalho@portugalmail.com";s:6:"active";s:3:"yes";}s:6:"helper";a:4:{s:4:"name";s:12:"Brett Bieber";s:4:"user";s:11:"saltybeagle";s:5:"email";s:22:"brett.bieber@gmail.com";s:6:"active";s:3:"yes";}s:4:"date";s:10:"2015-07-20";s:4:"time";s:8:"20:04:01";s:7:"version";a:2:{s:7:"release";s:5:"1.1.1";s:3:"api";s:5:"1.1.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";s:9:"LGPL-3.0+";s:5:"notes";s:55:"* Fix deprecated constructor warning on PHP 7 [cweiske]";s:8:"contents";a:1:{s:3:"dir";a:2:{s:7:"attribs";a:2:{s:14:"baseinstalldir";s:1:"/";s:4:"name";s:1:"/";}s:4:"file";a:12:{i:0;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"628eb6532a8047bf5962fe24c1c245df";s:4:"name";s:52:"docs/tutorials/Structures_Graph/Structures_Graph.pkg";s:4:"role";s:3:"doc";}}i:1;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"4b26eecd30f8695fc3739b1a5b59518e";s:4:"name";s:44:"Structures/Graph/Manipulator/AcyclicTest.php";s:4:"role";s:3:"php";}}i:2;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"1f857de1fbbaace54b857ed9712f399f";s:4:"name";s:50:"Structures/Graph/Manipulator/TopologicalSorter.php";s:4:"role";s:3:"php";}}i:3;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"f8e969f0b45d3859408901c8350bb701";s:4:"name";s:25:"Structures/Graph/Node.php";s:4:"role";s:3:"php";}}i:4;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"88ae1ad8bcd74d4b74ad845f55611cdd";s:4:"name";s:20:"Structures/Graph.php";s:4:"role";s:3:"php";}}i:5;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"65e4e85e573833516f5cc1d7a81db9c5";s:4:"name";s:18:"tests/AllTests.php";s:4:"role";s:4:"test";}}i:6;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"68ba309e2ac6713527f0fd31456457a1";s:4:"name";s:24:"tests/BasicGraphTest.php";s:4:"role";s:4:"test";}}i:7;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"190fc4634be55cd98608b72bc9d0a27f";s:4:"name";s:31:"tests/TopologicalSorterTest.php";s:4:"role";s:4:"test";}}i:8;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"4dc0c43f054732ec0f2fc78458ebadde";s:4:"name";s:25:"tests/AcyclicTestTest.php";s:4:"role";s:4:"test";}}i:9;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"68ba309e2ac6713527f0fd31456457a1";s:4:"name";s:24:"tests/BasicGraphTest.php";s:4:"role";s:4:"test";}}i:10;a:2:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"c891580ee21a7aa863ac32566c979fc5";s:4:"name";s:16:"tests/helper.inc";s:4:"role";s:4:"test";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:9:"@php_dir@";s:2:"to";s:7:"php_dir";s:4:"type";s:11:"pear-config";}}}i:11;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"b52f2d57d10c4f7ee67a7eb9615d5d24";s:4:"name";s:7:"LICENSE";s:4:"role";s:3:"doc";}}}}}s:10:"compatible";a:4:{s:4:"name";s:4:"PEAR";s:7:"channel";s:12:"pear.php.net";s:3:"min";s:8:"1.5.0RC3";s:3:"max";s:5:"1.9.1";}s:12:"dependencies";a:1:{s:8:"required";a:2:{s:3:"php";a:1:{s:3:"min";s:5:"5.3.0";}s:13:"pearinstaller";a:1:{s:3:"min";s:5:"1.4.3";}}}s:10:"phprelease";s:0:"";s:9:"changelog";a:1:{s:7:"release";a:5:{i:0;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.0.2";s:3:"api";s:5:"1.0.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2007-01-07";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:47:"http://opensource.org/licenses/lgpl-license.php";}s:8:"_content";s:4:"LGPL";}s:5:"notes";s:130:"- Bug #9682 only variables can be returned by reference - fix Bug #9661 notice in Structures_Graph_Manipulator_Topological::sort()";}i:1;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.0.3";s:3:"api";s:5:"1.0.3";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2009-10-11";s:7:"license";s:12:"LGPL License";s:5:"notes";s:258:"Bugfix Release: Version 1.0.3 is functionally equivalent to 1.0.2 but with an updated package.xml file. * Correct invalid md5 sum preventing installation with pyrus [saltybeagle] * Add compatible tag for PEAR 1.5.0RC3-1.9.0 [saltybeagle] * Update package.xml";}i:2;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.0.4";s:3:"api";s:5:"1.0.3";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2010-10-25";s:7:"license";s:12:"LGPL License";s:5:"notes";s:88:"Bugfix Release: * Bug #17108 BasicGraph::test_directed_degree fails on PHP 5 [clockwerx]";}i:3;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.1.0";s:3:"api";s:5:"1.1.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2015-02-26";s:7:"license";s:9:"LGPL-3.0+";s:5:"notes";s:128:"* Set minimum PHP version to 5.3 * Fix bug #19367: Incorrect FSF address in LICENSE * Change license from LGPL-2.1+ to LGPL-3.0+";}i:4;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.1.1";s:3:"api";s:5:"1.1.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2015-07-20";s:7:"license";s:9:"LGPL-3.0+";s:5:"notes";s:55:"* Fix deprecated constructor warning on PHP 7 [cweiske]";}}}s:8:"filelist";a:11:{s:52:"docs/tutorials/Structures_Graph/Structures_Graph.pkg";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"628eb6532a8047bf5962fe24c1c245df";s:4:"name";s:52:"docs/tutorials/Structures_Graph/Structures_Graph.pkg";s:4:"role";s:3:"doc";s:12:"installed_as";s:103:"/opt/alt/php56/usr/share/doc/pear/Structures_Graph/docs/tutorials/Structures_Graph/Structures_Graph.pkg";}s:44:"Structures/Graph/Manipulator/AcyclicTest.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"4b26eecd30f8695fc3739b1a5b59518e";s:4:"name";s:44:"Structures/Graph/Manipulator/AcyclicTest.php";s:4:"role";s:3:"php";s:12:"installed_as";s:74:"/opt/alt/php56/usr/share/pear/Structures/Graph/Manipulator/AcyclicTest.php";}s:50:"Structures/Graph/Manipulator/TopologicalSorter.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"1f857de1fbbaace54b857ed9712f399f";s:4:"name";s:50:"Structures/Graph/Manipulator/TopologicalSorter.php";s:4:"role";s:3:"php";s:12:"installed_as";s:80:"/opt/alt/php56/usr/share/pear/Structures/Graph/Manipulator/TopologicalSorter.php";}s:25:"Structures/Graph/Node.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"f8e969f0b45d3859408901c8350bb701";s:4:"name";s:25:"Structures/Graph/Node.php";s:4:"role";s:3:"php";s:12:"installed_as";s:55:"/opt/alt/php56/usr/share/pear/Structures/Graph/Node.php";}s:20:"Structures/Graph.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"88ae1ad8bcd74d4b74ad845f55611cdd";s:4:"name";s:20:"Structures/Graph.php";s:4:"role";s:3:"php";s:12:"installed_as";s:50:"/opt/alt/php56/usr/share/pear/Structures/Graph.php";}s:18:"tests/AllTests.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"65e4e85e573833516f5cc1d7a81db9c5";s:4:"name";s:18:"tests/AllTests.php";s:4:"role";s:4:"test";s:12:"installed_as";s:70:"/opt/alt/php56/usr/share/pear/test/Structures_Graph/tests/AllTests.php";}s:24:"tests/BasicGraphTest.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"68ba309e2ac6713527f0fd31456457a1";s:4:"name";s:24:"tests/BasicGraphTest.php";s:4:"role";s:4:"test";s:12:"installed_as";s:76:"/opt/alt/php56/usr/share/pear/test/Structures_Graph/tests/BasicGraphTest.php";}s:31:"tests/TopologicalSorterTest.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"190fc4634be55cd98608b72bc9d0a27f";s:4:"name";s:31:"tests/TopologicalSorterTest.php";s:4:"role";s:4:"test";s:12:"installed_as";s:83:"/opt/alt/php56/usr/share/pear/test/Structures_Graph/tests/TopologicalSorterTest.php";}s:25:"tests/AcyclicTestTest.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"4dc0c43f054732ec0f2fc78458ebadde";s:4:"name";s:25:"tests/AcyclicTestTest.php";s:4:"role";s:4:"test";s:12:"installed_as";s:77:"/opt/alt/php56/usr/share/pear/test/Structures_Graph/tests/AcyclicTestTest.php";}s:16:"tests/helper.inc";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"1f58c7773b57cd700a110bc36400d13d";s:4:"name";s:16:"tests/helper.inc";s:4:"role";s:4:"test";s:12:"installed_as";s:68:"/opt/alt/php56/usr/share/pear/test/Structures_Graph/tests/helper.inc";}s:7:"LICENSE";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"b52f2d57d10c4f7ee67a7eb9615d5d24";s:4:"name";s:7:"LICENSE";s:4:"role";s:3:"doc";s:12:"installed_as";s:58:"/opt/alt/php56/usr/share/doc/pear/Structures_Graph/LICENSE";}}s:12:"_lastversion";N;s:7:"dirtree";a:9:{s:82:"/opt/alt/php56/usr/share/doc/pear/Structures_Graph/docs/tutorials/Structures_Graph";b:1;s:65:"/opt/alt/php56/usr/share/doc/pear/Structures_Graph/docs/tutorials";b:1;s:55:"/opt/alt/php56/usr/share/doc/pear/Structures_Graph/docs";b:1;s:50:"/opt/alt/php56/usr/share/doc/pear/Structures_Graph";b:1;s:58:"/opt/alt/php56/usr/share/pear/Structures/Graph/Manipulator";b:1;s:46:"/opt/alt/php56/usr/share/pear/Structures/Graph";b:1;s:40:"/opt/alt/php56/usr/share/pear/Structures";b:1;s:57:"/opt/alt/php56/usr/share/pear/test/Structures_Graph/tests";b:1;s:51:"/opt/alt/php56/usr/share/pear/test/Structures_Graph";b:1;}s:3:"old";a:7:{s:7:"version";s:5:"1.1.1";s:12:"release_date";s:10:"2015-07-20";s:13:"release_state";s:6:"stable";s:15:"release_license";s:9:"LGPL-3.0+";s:13:"release_notes";s:55:"* Fix deprecated constructor warning on PHP 7 [cweiske]";s:12:"release_deps";a:2:{i:0;a:4:{s:4:"type";s:3:"php";s:3:"rel";s:2:"ge";s:7:"version";s:5:"5.3.0";s:8:"optional";s:2:"no";}i:1;a:6:{s:4:"type";s:3:"pkg";s:7:"channel";s:12:"pear.php.net";s:4:"name";s:4:"PEAR";s:3:"rel";s:2:"ge";s:7:"version";s:5:"1.4.3";s:8:"optional";s:2:"no";}}s:11:"maintainers";a:2:{i:0;a:5:{s:4:"name";s:16:"Sérgio Carvalho";s:5:"email";s:32:"sergio.carvalho@portugalmail.com";s:6:"active";s:3:"yes";s:6:"handle";s:9:"sergiosgc";s:4:"role";s:4:"lead";}i:1;a:5:{s:4:"name";s:12:"Brett Bieber";s:5:"email";s:22:"brett.bieber@gmail.com";s:6:"active";s:3:"yes";s:6:"handle";s:11:"saltybeagle";s:4:"role";s:6:"helper";}}}s:10:"xsdversion";s:3:"2.0";s:13:"_lastmodified";i:1747068539;}PK�����u]SGW��W����.registry/archive_tar.regnu�[��������a:24:{s:7:"attribs";a:6:{s:15:"packagerversion";s:7:"1.10.12";s:7:"version";s:3:"2.0";s:5:"xmlns";s:35:"http://pear.php.net/dtd/package-2.0";s:11:"xmlns:tasks";s:33:"http://pear.php.net/dtd/tasks-1.0";s:9:"xmlns:xsi";s:41:"http://www.w3.org/2001/XMLSchema-instance";s:18:"xsi:schemaLocation";s:147:"http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd";}s:4:"name";s:11:"Archive_Tar";s:7:"channel";s:12:"pear.php.net";s:7:"summary";s:25:"Tar file management class";s:11:"description";s:321:"This class provides handling of tar files in PHP. It supports creating, listing, extracting and adding to tar files. Gzip support is available if PHP has the zlib extension built-in or loaded. Bz2 compression is also supported with the bz2 extension loaded. Also Lzma2 compressed archives are supported with xz extension.";s:4:"lead";a:3:{i:0;a:4:{s:4:"name";s:14:"Vincent Blavet";s:4:"user";s:7:"vblavet";s:5:"email";s:22:"vincent@phpconcept.net";s:6:"active";s:2:"no";}i:1;a:4:{s:4:"name";s:11:"Greg Beaver";s:4:"user";s:6:"cellog";s:5:"email";s:22:"greg@chiaraquartet.net";s:6:"active";s:2:"no";}i:2;a:4:{s:4:"name";s:12:"Michiel Rook";s:4:"user";s:5:"mrook";s:5:"email";s:13:"mrook@php.net";s:6:"active";s:3:"yes";}}s:6:"helper";a:4:{s:4:"name";s:11:"Stig Bakken";s:4:"user";s:3:"ssb";s:5:"email";s:12:"stig@php.net";s:6:"active";s:2:"no";}s:4:"date";s:10:"2021-07-20";s:4:"time";s:8:"19:35:29";s:7:"version";a:2:{s:7:"release";s:6:"1.4.14";s:3:"api";s:5:"1.4.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:15:"New BSD License";}s:5:"notes";s:60:"* Properly fix symbolic link path traversal (CVE-2021-32610)";s:8:"contents";a:1:{s:3:"dir";a:2:{s:7:"attribs";a:1:{s:4:"name";s:1:"/";}s:4:"file";a:2:{i:0;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"95f04c226245ad192b52c9164c1287ad";s:4:"name";s:15:"Archive/Tar.php";s:4:"role";s:3:"php";}}i:1;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"2fb90f0be7089a45c09a0d1182792419";s:4:"name";s:20:"docs/Archive_Tar.txt";s:4:"role";s:3:"doc";}}}}}s:10:"compatible";a:4:{s:4:"name";s:4:"PEAR";s:7:"channel";s:12:"pear.php.net";s:3:"min";s:5:"1.8.0";s:3:"max";s:7:"1.10.10";}s:12:"dependencies";a:1:{s:8:"required";a:2:{s:3:"php";a:1:{s:3:"min";s:5:"5.2.0";}s:13:"pearinstaller";a:1:{s:3:"min";s:5:"1.9.0";}}}s:10:"phprelease";s:0:"";s:9:"changelog";a:1:{s:7:"release";a:39:{i:0;a:5:{s:7:"version";a:2:{s:7:"release";s:6:"1.4.13";s:3:"api";s:5:"1.4.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2021-02-16";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:15:"New BSD License";}s:5:"notes";s:81:"* Fix Bug #27010: Relative symlinks failing (out-of path file extraction) [mrook]";}i:1;a:5:{s:7:"version";a:2:{s:7:"release";s:6:"1.4.12";s:3:"api";s:5:"1.4.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2021-01-18";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:15:"New BSD License";}s:5:"notes";s:82:"* Fix Bug #27008: Symlink out-of-path write vulnerability (CVE-2020-36193) [mrook]";}i:2;a:5:{s:7:"version";a:2:{s:7:"release";s:6:"1.4.11";s:3:"api";s:5:"1.4.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2020-11-19";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:15:"New BSD License";}s:5:"notes";s:97:"* Fix Bug #27002: Filename manipulation vulnerabilities (CVE-2020-28948 / CVE-2020-28949) [mrook]";}i:3;a:5:{s:7:"version";a:2:{s:7:"release";s:6:"1.4.10";s:3:"api";s:5:"1.4.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2020-09-15";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:15:"New BSD License";}s:5:"notes";s:165:"* Fix block padding when the file buffer length is a multiple of 512 and smaller than Archive_Tar buffer length * Don't try to copy username/groupname in chroot jail";}i:4;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.4.9";s:3:"api";s:5:"1.4.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2019-12-04";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:15:"New BSD License";}s:5:"notes";s:67:"* Implement Feature #23861: Add option to disallow symlinks [mrook]";}i:5;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.4.8";s:3:"api";s:5:"1.4.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2019-10-21";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:15:"New BSD License";}s:5:"notes";s:79:"* Fix Bug #23852: PHP 7.4 - Archive_Tar->_readHeader throws deprecation [mrook]";}i:6;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.4.7";s:3:"api";s:5:"1.4.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2019-04-08";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:15:"New BSD License";}s:5:"notes";s:53:"* Improved performance by increasing read buffer size";}i:7;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.4.6";s:3:"api";s:5:"1.4.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2019-02-01";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:15:"New BSD License";}s:5:"notes";s:67:"* Improve path traversal detection for forward and backward slashes";}i:8;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.4.5";s:3:"api";s:5:"1.4.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2019-01-02";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:15:"New BSD License";}s:5:"notes";s:54:"* Fix Bug #23788: Relative symlinks are broken [mrook]";}i:9;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.4.4";s:3:"api";s:5:"1.4.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2018-12-20";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:15:"New BSD License";}s:5:"notes";s:127:"* Fix Bug #21058: Long symlinks are not supported [mrook] * Fix Bug #23782: Prevent phar:// files from being extracted [mrook]";}i:10;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.4.3";s:3:"api";s:5:"1.4.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2017-06-11";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:15:"New BSD License";}s:5:"notes";s:103:"* Fix Bug #21218: Cannot use result of built-in function in write context in PHP 7.2.0alpha1 [mrook]";}i:11;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.4.2";s:3:"api";s:5:"1.4.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2016-02-25";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:15:"New BSD License";}s:5:"notes";s:164:"* Fix reading of archives with files > 8GB * Performance optimizations * Do not try to call require_once on PEAR.php if it has already been loaded by the autoloader";}i:12;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.4.1";s:3:"api";s:5:"1.4.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2015-08-05";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:15:"New BSD License";}s:5:"notes";s:60:"* Update composer.json to use pear-core-minimal 1.10.0alpha2";}i:13;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.4.0";s:3:"api";s:5:"1.4.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2015-07-20";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:15:"New BSD License";}s:5:"notes";s:104:"* Add support for PHP 7 * Drop support for PHP 4 * Add visibility declarations to methods and properties";}i:14;a:5:{s:7:"version";a:2:{s:7:"release";s:6:"1.3.16";s:3:"api";s:5:"1.3.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2015-04-14";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:15:"New BSD License";}s:5:"notes";s:73:"* Fix Bug #20514: invalid package.xml; not installable with pyrus [mrook]";}i:15;a:5:{s:7:"version";a:2:{s:7:"release";s:6:"1.3.15";s:3:"api";s:5:"1.3.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2015-03-05";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:15:"New BSD License";}s:5:"notes";s:33:"* Fixes composer.json parse error";}i:16;a:5:{s:7:"version";a:2:{s:7:"release";s:6:"1.3.14";s:3:"api";s:5:"1.3.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2015-02-26";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:15:"New BSD License";}s:5:"notes";s:74:"* Fix Bug #18505: Possible incorrect handling of file names in TAR [mrook]";}i:17;a:5:{s:7:"version";a:2:{s:7:"release";s:6:"1.3.13";s:3:"api";s:5:"1.3.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2014-09-02";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:16:"New BSD License";}s:5:"notes";s:36:"* Fix Bug #20382: gzopen fix [mrook]";}i:18;a:5:{s:7:"version";a:2:{s:7:"release";s:6:"1.3.12";s:3:"api";s:5:"1.3.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2014-08-04";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:16:"New BSD License";}s:5:"notes";s:350:"* Fix Bug #19964: Memory leaking in Archive_Tar [mrook] * Fix Bug #20246: Broken with php 5.5.9 [mrook] * Fix Bug #20275: "pax_global_header" looks like a regular file * [mrook] * Implement Feature #19827: pass filename to _addFile function - downstream * patch [mrook] * Implement Feature #20132: Add custom mode/uid/gid to addString() [mrook]";}i:19;a:5:{s:7:"version";a:2:{s:7:"release";s:6:"1.3.11";s:3:"api";s:5:"1.3.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2013-02-09";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:18:"New BSD License";}s:5:"notes";s:128:"* Fix Bug #19746: Broken with PHP 5.5 [mrook] * Implement Feature #11258: Custom date/time in files added on-the-fly * [mrook]";}i:20;a:5:{s:7:"version";a:2:{s:7:"release";s:6:"1.3.10";s:3:"api";s:5:"1.3.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2012-04-10";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:18:"New BSD License";}s:5:"notes";s:143:"* Fix Bug #13361: Unable to add() some files (ex. mp3) [mrook] * Fix Bug #19330: Class creates incorrect (non-readable) tar.gz file * [mrook]";}i:21;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.3.9";s:3:"api";s:5:"1.3.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2012-02-27";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:17:"New BSD License";}s:5:"notes";s:259:"* Fix Bug #16759: No error thrown from missing PHP zlib functions [mrook] * Fix Bug #18877: Incorrect handling of backslashes in filenames on Linux [mrook] * Fix Bug #19085: Error while packaging [mrook] * Fix Bug #19289: Invalid tar file generated [mrook]";}i:22;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.3.8";s:3:"api";s:5:"1.3.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2011-10-14";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:15:"New BSD License";}s:5:"notes";s:449:"* Fix Bug #17853: Test failure: dirtraversal.phpt [mrook] * Fix Bug #18512: dead links are not saved in tar file [mrook] * Fix Bug #18702: Unpacks incorrectly on long file names using header prefix [mrook] * Implement Feature #10145: Patch to return a Pear Error Object on failure [mrook] * Implement Feature #17491: Option to preserve permissions [mrook] * Implement Feature #17813: Prevent PHP notice when extracting corrupted archive [mrook]";}i:23;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.3.7";s:3:"api";s:5:"1.3.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2010-04-26";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:15:"New BSD License";}s:5:"notes";s:25:"PEAR compatibility update";}i:24;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.3.6";s:3:"api";s:5:"1.3.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2010-03-09";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:15:"New BSD License";}s:5:"notes";s:168:"* Fix Bug #16963: extractList can't extract zipped files from big tar [mrook] * Implement Feature #4013: Ignoring files and directories on creating an archive. [mrook]";}i:25;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.3.5";s:3:"api";s:5:"1.3.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2009-12-31";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:15:"New BSD License";}s:5:"notes";s:64:"* Fix Bug #16958: Update 'compatible' tag in package.xml [mrook]";}i:26;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.3.4";s:3:"api";s:5:"1.3.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2009-12-30";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:15:"New BSD License";}s:5:"notes";s:338:"* Fix Bug #11871: wrong result of ::listContent() if filename begins or ends with space [mrook] * Fix Bug #12462: invalid tar magic [mrook] * Fix Bug #13918: Long filenames may get up to 511 0x00 bytes appended on read [mrook] * Fix Bug #16202: Bogus modification times [mrook] * Implement Feature #16212: Die is not exception [mrook]";}i:27;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.3.3";s:3:"api";s:5:"1.3.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2009-03-27";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:15:"New BSD License";}s:5:"notes";s:249:"Change the license to New BSD license minor bugfix release * fix Bug #9921 compression with bzip2 fails [cellog] * fix Bug #11594 _readLongHeader leaves 0 bytes in filename [jamessas] * fix Bug #11769 Incorrect symlink handing [fajar99]";}i:28;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.3.2";s:3:"api";s:5:"1.3.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2007-01-03";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:26:"http://www.php.net/license";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:484:"Correct Bug #4016 Remove duplicate remove error display with '@' Correct Bug #3909 : Check existence of OS_WINDOWS constant Correct Bug #5452 fix for "lone zero block" when untarring packages Change filemode (from pear-core/Archive/Tar.php v.1.21) Correct Bug #6486 Can not extract symlinks Correct Bug #6933 Archive_Tar (Tar file management class) Directory traversal Correct Bug #8114 Files added on-the-fly not storing date Correct Bug #9352 Bug on _dirCheck function over nfs path";}i:29;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.3.1";s:3:"api";s:5:"1.3.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2005-03-17";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:26:"http://www.php.net/license";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:17:"Correct Bug #3855";}i:30;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.3.0";s:3:"api";s:5:"1.3.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2005-03-06";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:26:"http://www.php.net/license";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:40:"Bugs correction (2475, 2488, 2135, 2176)";}i:31;a:5:{s:7:"version";a:2:{s:7:"release";s:3:"1.2";s:3:"api";s:3:"1.2";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2004-05-08";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:26:"http://www.php.net/license";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:71:"Add support for other separator than the space char and bug correction";}i:32;a:5:{s:7:"version";a:2:{s:7:"release";s:3:"1.1";s:3:"api";s:3:"1.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2003-05-28";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:26:"http://www.php.net/license";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:141:"* Add support for BZ2 compression * Add support for add and extract without using temporary files : methods addString() and extractInString()";}i:33;a:5:{s:7:"version";a:2:{s:7:"release";s:3:"1.0";s:3:"api";s:3:"1.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2003-01-24";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:26:"http://www.php.net/license";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:23:"Change status to stable";}i:34;a:5:{s:7:"version";a:2:{s:7:"release";s:7:"0.10-b1";s:3:"api";s:7:"0.10-b1";}s:9:"stability";a:2:{s:7:"release";s:4:"beta";s:3:"api";s:4:"beta";}s:4:"date";s:10:"2003-01-08";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:26:"http://www.php.net/license";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:59:"Add support for long filenames (greater than 99 characters)";}i:35;a:5:{s:7:"version";a:2:{s:7:"release";s:3:"0.9";s:3:"api";s:3:"0.9";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2002-05-27";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:26:"http://www.php.net/license";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:25:"Auto-detect gzip'ed files";}i:36;a:5:{s:7:"version";a:2:{s:7:"release";s:3:"0.4";s:3:"api";s:3:"0.4";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2002-05-20";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:26:"http://www.php.net/license";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:51:"Windows bugfix: use forward slashes inside archives";}i:37;a:5:{s:7:"version";a:2:{s:7:"release";s:3:"0.2";s:3:"api";s:3:"0.2";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2002-02-18";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:26:"http://www.php.net/license";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:29:"From initial commit to stable";}i:38;a:5:{s:7:"version";a:2:{s:7:"release";s:3:"0.3";s:3:"api";s:3:"0.3";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2002-04-13";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:26:"http://www.php.net/license";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:47:"Windows bugfix: used wrong directory separators";}}}s:8:"filelist";a:2:{s:15:"Archive/Tar.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"95f04c226245ad192b52c9164c1287ad";s:4:"name";s:15:"Archive/Tar.php";s:4:"role";s:3:"php";s:12:"installed_as";s:45:"/opt/alt/php56/usr/share/pear/Archive/Tar.php";}s:20:"docs/Archive_Tar.txt";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"2fb90f0be7089a45c09a0d1182792419";s:4:"name";s:20:"docs/Archive_Tar.txt";s:4:"role";s:3:"doc";s:12:"installed_as";s:66:"/opt/alt/php56/usr/share/doc/pear/Archive_Tar/docs/Archive_Tar.txt";}}s:12:"_lastversion";N;s:7:"dirtree";a:3:{s:37:"/opt/alt/php56/usr/share/pear/Archive";b:1;s:50:"/opt/alt/php56/usr/share/doc/pear/Archive_Tar/docs";b:1;s:45:"/opt/alt/php56/usr/share/doc/pear/Archive_Tar";b:1;}s:3:"old";a:7:{s:7:"version";s:6:"1.4.14";s:12:"release_date";s:10:"2021-07-20";s:13:"release_state";s:6:"stable";s:15:"release_license";s:15:"New BSD License";s:13:"release_notes";s:60:"* Properly fix symbolic link path traversal (CVE-2021-32610)";s:12:"release_deps";a:2:{i:0;a:4:{s:4:"type";s:3:"php";s:3:"rel";s:2:"ge";s:7:"version";s:5:"5.2.0";s:8:"optional";s:2:"no";}i:1;a:6:{s:4:"type";s:3:"pkg";s:7:"channel";s:12:"pear.php.net";s:4:"name";s:4:"PEAR";s:3:"rel";s:2:"ge";s:7:"version";s:5:"1.9.0";s:8:"optional";s:2:"no";}}s:11:"maintainers";a:4:{i:0;a:5:{s:4:"name";s:14:"Vincent Blavet";s:5:"email";s:22:"vincent@phpconcept.net";s:6:"active";s:2:"no";s:6:"handle";s:7:"vblavet";s:4:"role";s:4:"lead";}i:1;a:5:{s:4:"name";s:11:"Greg Beaver";s:5:"email";s:22:"greg@chiaraquartet.net";s:6:"active";s:2:"no";s:6:"handle";s:6:"cellog";s:4:"role";s:4:"lead";}i:2;a:5:{s:4:"name";s:12:"Michiel Rook";s:5:"email";s:13:"mrook@php.net";s:6:"active";s:3:"yes";s:6:"handle";s:5:"mrook";s:4:"role";s:4:"lead";}i:3;a:5:{s:4:"name";s:11:"Stig Bakken";s:5:"email";s:12:"stig@php.net";s:6:"active";s:2:"no";s:6:"handle";s:3:"ssb";s:4:"role";s:6:"helper";}}}s:10:"xsdversion";s:3:"2.0";s:13:"_lastmodified";i:1747068539;}PK�����u]0R1{��1{����.registry/xml_rpc.regnu�[��������a:23:{s:7:"attribs";a:6:{s:15:"packagerversion";s:5:"1.9.4";s:7:"version";s:3:"2.0";s:5:"xmlns";s:35:"http://pear.php.net/dtd/package-2.0";s:11:"xmlns:tasks";s:33:"http://pear.php.net/dtd/tasks-1.0";s:9:"xmlns:xsi";s:41:"http://www.w3.org/2001/XMLSchema-instance";s:18:"xsi:schemaLocation";s:159:"http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd";}s:4:"name";s:7:"XML_RPC";s:7:"channel";s:12:"pear.php.net";s:7:"summary";s:42:"PHP implementation of the XML-RPC protocol";s:11:"description";s:123:"A PEAR-ified version of Useful Inc's XML-RPC for PHP. It has support for HTTP/HTTPS transport, proxies and authentication.";s:4:"lead";a:2:{i:0;a:4:{s:4:"name";s:11:"Stig Bakken";s:4:"user";s:3:"ssb";s:5:"email";s:12:"stig@php.net";s:6:"active";s:2:"no";}i:1;a:4:{s:4:"name";s:16:"Daniel Convissor";s:4:"user";s:7:"danielc";s:5:"email";s:15:"danielc@php.net";s:6:"active";s:2:"no";}}s:4:"date";s:10:"2011-08-27";s:4:"time";s:8:"01:36:28";s:7:"version";a:2:{s:7:"release";s:5:"1.5.5";s:3:"api";s:5:"1.5.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:35:"http://www.php.net/license/3_01.txt";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:92:"* Adjust is_a() usage due to change in PHP 5.3.7. * Fix error populating headers. Bug 18653.";s:8:"contents";a:1:{s:3:"dir";a:2:{s:7:"attribs";a:2:{s:14:"baseinstalldir";s:1:"/";s:4:"name";s:1:"/";}s:4:"file";a:12:{i:0;a:2:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"41158fbcb2d49755fdaf877f92e85362";s:4:"name";s:24:"tests/actual-request.php";s:4:"role";s:4:"test";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:1;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"e9a0aa974052ee47c41ad0274c728dc6";s:4:"name";s:16:"tests/allgot.inc";s:4:"role";s:4:"test";}}i:2;a:2:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"60cd6342dd96bf0be4d4d3cbb7813cf4";s:4:"name";s:28:"tests/empty-value-struct.php";s:4:"role";s:4:"test";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:3;a:2:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"2bdf63e6eba97ea12ac4f5a3a92fdc3a";s:4:"name";s:21:"tests/empty-value.php";s:4:"role";s:4:"test";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:4;a:2:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"94ab1218006a7dc8fdd362dffc48777f";s:4:"name";s:16:"tests/encode.php";s:4:"role";s:4:"test";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:5;a:2:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"74921ba059a82e2ec9c7734c187a3f2c";s:4:"name";s:21:"tests/extra-lines.php";s:4:"role";s:4:"test";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:6;a:2:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"3e200b7a09217395196987f1e948871a";s:4:"name";s:19:"tests/protoport.php";s:4:"role";s:4:"test";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:7;a:2:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"f3af6b2112368d543f80907f1b040b77";s:4:"name";s:19:"tests/test_Dump.php";s:4:"role";s:4:"test";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:8;a:2:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"6fb82404a22f0e751697c8ffe0557a6a";s:4:"name";s:15:"tests/types.php";s:4:"role";s:4:"test";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:9;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"b361011f028738d20e8905cfa2fcefc5";s:4:"name";s:11:"XML/RPC.php";s:4:"role";s:3:"php";}}i:10;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"2036a5c5c6e965b93533cd050442fa98";s:4:"name";s:16:"XML/RPC/Dump.php";s:4:"role";s:3:"php";}}i:11;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"8a0123129ef7eb5615505b95d0f0b72f";s:4:"name";s:18:"XML/RPC/Server.php";s:4:"role";s:3:"php";}}}}}s:10:"compatible";a:4:{s:4:"name";s:4:"PEAR";s:7:"channel";s:12:"pear.php.net";s:3:"min";s:7:"1.4.0a1";s:3:"max";s:5:"1.4.9";}s:12:"dependencies";a:1:{s:8:"required";a:3:{s:3:"php";a:1:{s:3:"min";s:5:"4.2.0";}s:13:"pearinstaller";a:1:{s:3:"min";s:7:"1.4.0a1";}s:9:"extension";a:1:{s:4:"name";s:3:"xml";}}}s:10:"phprelease";s:0:"";s:9:"changelog";a:1:{s:7:"release";a:39:{i:0;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.0.1";s:3:"api";s:5:"1.0.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2001-09-25";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:34:"http://www.php.net/license/3_0.txt";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:132:"This is a PEAR-ified version of Useful Inc's 1.0.1 release. Includes an urgent security fix identified by Dan Libby <dan@libby.com>.";}i:1;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.0.2";s:3:"api";s:5:"1.0.2";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2002-04-16";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:34:"http://www.php.net/license/3_0.txt";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:48:"* E_ALL fixes * fix HTTP response header parsing";}i:2;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.0.3";s:3:"api";s:5:"1.0.3";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2002-05-19";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:34:"http://www.php.net/license/3_0.txt";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:51:"* fix bug when parsing responses with boolean types";}i:3;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.0.4";s:3:"api";s:5:"1.0.4";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2002-10-02";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:34:"http://www.php.net/license/3_0.txt";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:68:"* added HTTP proxy authorization support (thanks to Arnaud Limbourg)";}i:4;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.1.0";s:3:"api";s:5:"1.1.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2004-03-15";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:34:"http://www.php.net/license/3_0.txt";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:517:"* Added support for sequential arrays to XML_RPC_encode() (mroch) * Cleaned up new XML_RPC_encode() changes a bit (mroch, pierre) * Remove "require_once 'PEAR.php'", include only when needed to raise an error * Replace echo and error_log() with raiseError() (mroch) * Make all classes extend XML_RPC_Base, which will handle common functions (mroch) * be tolerant of junk after methodResponse (Luca Mariano, mroch) * Silent notice even in the error log (pierre) * fix include of shared xml extension on win32 (pierre)";}i:5;a:5:{s:7:"version";a:2:{s:7:"release";s:8:"1.2.0RC1";s:3:"api";s:8:"1.2.0RC1";}s:9:"stability";a:2:{s:7:"release";s:4:"beta";s:3:"api";s:4:"beta";}s:4:"date";s:10:"2004-12-30";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:34:"http://www.php.net/license/3_0.txt";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:1187:"* Make things work with SSL. Bug 2489. (nkukard lbsd net) * Allow array function callbacks (Matt Kane) * Some minor speed-ups (Matt Kane) * Add Dump.php to the package (Christian Weiske) * Replace all line endings with \r\n. Had only done replacements on \n. Bug 2521. (danielc) * Silence fsockopen() errors. Bug 1714. (danielc) * Encode empty arrays as an array. Bug 1493. (danielc) * Eliminate undefined index notice when submitting empty arrays to XML_RPC_Encode(). Bug 1819. (danielc) * Speed up check for enumerated arrays in XML_RPC_Encode(). (danielc) * Prepend "XML_RPC_" to ERROR_NON_NUMERIC_FOUND, eliminating problem when eval()'ing error messages. (danielc) * Use XML_RPC_Base::raiseError() instead of PEAR::raiseError() in XML_RPC_ee() because PEAR.php is lazy loaded. (danielc) * Allow raiseError() to be called statically. (danielc) * Stop double escaping of character entities. Bug 987. (danielc) NOTICE: the following have been removed: * XML_RPC_dh() * $GLOBALS['XML_RPC_entities'] * XML_RPC_entity_decode() * XML_RPC_lookup_entity() * Determine the XML's encoding via the encoding attribute in the XML declaration. Bug 52. (danielc)";}i:6;a:5:{s:7:"version";a:2:{s:7:"release";s:8:"1.2.0RC2";s:3:"api";s:8:"1.2.0RC2";}s:9:"stability";a:2:{s:7:"release";s:4:"beta";s:3:"api";s:4:"beta";}s:4:"date";s:10:"2005-01-11";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:34:"http://www.php.net/license/3_0.txt";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:162:"* Handle ssl:// in the $server string. (danielc) * Also default to port 445 for ssl:// requests as well. (danielc) * Enhance debugging in the server. (danielc)";}i:7;a:5:{s:7:"version";a:2:{s:7:"release";s:8:"1.2.0RC3";s:3:"api";s:8:"1.2.0RC3";}s:9:"stability";a:2:{s:7:"release";s:4:"beta";s:3:"api";s:4:"beta";}s:4:"date";s:10:"2005-01-19";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:34:"http://www.php.net/license/3_0.txt";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:29:"* ssl uses port 443, not 445.";}i:8;a:5:{s:7:"version";a:2:{s:7:"release";s:8:"1.2.0RC4";s:3:"api";s:8:"1.2.0RC4";}s:9:"stability";a:2:{s:7:"release";s:4:"beta";s:3:"api";s:4:"beta";}s:4:"date";s:10:"2005-01-24";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:34:"http://www.php.net/license/3_0.txt";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:388:"* When a connection attempt fails, have the method return 0. (danielc) * Move the protocol/port checking/switching and the property settings from sendPayloadHTTP10() to the XML_RPC_Client constructor. (danielc) * Add tests for setting the client properties. (danielc) * Remove $GLOBALS['XML_RPC_twoslash'] since it's not used. (danielc) * Bundle the tests with the package. (danielc)";}i:9;a:5:{s:7:"version";a:2:{s:7:"release";s:8:"1.2.0RC5";s:3:"api";s:8:"1.2.0RC5";}s:9:"stability";a:2:{s:7:"release";s:4:"beta";s:3:"api";s:4:"beta";}s:4:"date";s:10:"2005-01-24";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:34:"http://www.php.net/license/3_0.txt";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:91:"* If $port is 443 but a protocol isn't specified in $server, assume ssl:// is the protocol.";}i:10;a:5:{s:7:"version";a:2:{s:7:"release";s:8:"1.2.0RC6";s:3:"api";s:8:"1.2.0RC6";}s:9:"stability";a:2:{s:7:"release";s:4:"beta";s:3:"api";s:4:"beta";}s:4:"date";s:10:"2005-01-25";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:34:"http://www.php.net/license/3_0.txt";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:71:"* Don't put the protocol in the Host field of the POST data. (danielc)";}i:11;a:5:{s:7:"version";a:2:{s:7:"release";s:8:"1.2.0RC7";s:3:"api";s:8:"1.2.0RC7";}s:9:"stability";a:2:{s:7:"release";s:4:"beta";s:3:"api";s:4:"beta";}s:4:"date";s:10:"2005-02-22";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:34:"http://www.php.net/license/3_0.txt";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:346:"* Add the setSendEncoding() method and $send_encoding property to XML_RPC_Message. Request 3537. * Allow class methods to be mapped using either syntax: 'function' => 'hello::sayHello', or 'function' => array('hello', 'sayhello'), Bug 3363. * Use 8192 instead of 32768 for bytes in fread() in parseResponseFile(). Bug 3340.";}i:12;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.2.0";s:3:"api";s:5:"1.2.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2005-02-27";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:34:"http://www.php.net/license/3_0.txt";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:160:"* Provide the "stable" release. * Add package2.xml for compatibility with PEAR 1.4.0. * For changes since 1.1.0, see the changelogs for the various RC releases.";}i:13;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.2.1";s:3:"api";s:5:"1.2.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2005-03-01";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:34:"http://www.php.net/license/3_0.txt";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:65:"* Add isset() check before examining the dispatch map. Bug 3658.";}i:14;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.2.2";s:3:"api";s:5:"1.2.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2005-03-07";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:34:"http://www.php.net/license/3_0.txt";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:122:"* When using a proxy, add the protocol to the Request-URI, making it an "absoluteURI" as per the HTTP 1.0 spec. Bug 3679.";}i:15;a:5:{s:7:"version";a:2:{s:7:"release";s:8:"1.3.0RC1";s:3:"api";s:5:"1.3.0";}s:9:"stability";a:2:{s:7:"release";s:4:"beta";s:3:"api";s:4:"beta";}s:4:"date";s:10:"2005-04-07";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:34:"http://www.php.net/license/3_0.txt";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:818:"* Improve timeout handling for situations where connection to server is made but no response is not received in time. Accomplished via stream_set_timeout(). Request 3963. * Add Fault Code 6: "The requested method didn't return an XML_RPC_Response object." Request 4032. * Add the createServerPayload() and createServerHeaders() methods and the $server_payload and $server_headers properties. Request 3121. * As in earlier versions, if the $serviceNow parameter to XML_RPC_Server() is 0, no data will be returned, but now the new $server_payload and $server_headers properties will be set. * Convert the parser handle to an integer before using it as an index for $XML_RPC_xh[$parser]. Reduces E_STRICT notices. Bug 3782. * Add createHeaders() method and $headers property to XML_RPC_Client to make testing easier.";}i:16;a:5:{s:7:"version";a:2:{s:7:"release";s:8:"1.3.0RC2";s:3:"api";s:5:"1.3.0";}s:9:"stability";a:2:{s:7:"release";s:4:"beta";s:3:"api";s:4:"beta";}s:4:"date";s:10:"2005-05-05";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:34:"http://www.php.net/license/3_0.txt";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:383:"* If XML_RPC_Message::getParam() is given an incorrect parameter, raise an error with the new XML_RPC_ERROR_INCORRECT_PARAMS code and return FALSE. * Handle improper requests to XML_RPC_Server::verifySignature(). Bug 4231. * Try to allow HTTP 100 responses if followed by a 200 response. Bug 4116. * Help Delphi users by making RPCMETHODNAME an alias for METHODNAME. Request 4205.";}i:17;a:5:{s:7:"version";a:2:{s:7:"release";s:8:"1.3.0RC3";s:3:"api";s:5:"1.3.0";}s:9:"stability";a:2:{s:7:"release";s:4:"beta";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2005-05-10";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:34:"http://www.php.net/license/3_0.txt";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:724:"* When verifying requests against function signatures, if the number of parameters don't match, provide an appropriate message. NOTE: this resolves a path disclosure vulnerability. (Refines the changes made in the last commit.) Bug 4231. * XML_RPC_Message::getParam() now returns an XML_RPC_Response object upon error. Changed from Release 1.3.0RC2. * Add the XML_RPC_Value::isValue() method. For testing if an item is an XML_RPC_Value object. * If XML_RPC_Client::send() is given an incorrect $msg parameter, raise an error with the new XML_RPC_ERROR_PROGRAMMING code and return 0. * Improve cross-platform operation by using PEAR::loadExtension() instead of dl(). * Use <br /> instead of <br> in XML_RPC_Value::dump().";}i:18;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.3.0";s:3:"api";s:5:"1.3.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2005-06-13";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:34:"http://www.php.net/license/3_0.txt";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:64:"* Stable release. See earlier releases for changes since 1.2.2.";}i:19;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.3.1";s:3:"api";s:5:"1.3.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2005-06-29";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:34:"http://www.php.net/license/3_0.txt";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:42:"* Security fix. Update highly recommended!";}i:20;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.3.2";s:3:"api";s:5:"1.3.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2005-07-07";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:34:"http://www.php.net/license/3_0.txt";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:584:"* Eliminate path disclosure vulnerabilities by suppressing error messages when eval()'ing. * Eliminate path disclosure vulnerability by catching bogus parameters submitted to XML_RPC_Value::serializeval(). * In XML_RPC_Server::service(), only call createServerPayload() and createServerHeaders() if necessary. Fixes compatibility issue introduced in Release 1.3.0RC1 for users who set the $serviceNow parameter of XML_RPC_Server() to 0. Bug 4757. * Change "var $errstring" to "var $errstr". Bug 4582. Was put into CVS version 1.75 of RPC.php but didn't make it into RELEASE_1_3_1.";}i:21;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.3.3";s:3:"api";s:5:"1.3.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2005-07-15";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:34:"http://www.php.net/license/3_0.txt";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:220:"* Eliminate memory leak by resetting $XML_RPC_xh each time parseResponse() is called. Bug 4780. * Using socket_set_timeout() because stream_set_timeout() was introduced in 4.3.0, but we need to support 4.2.0. Bug 4805.";}i:22;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.4.0";s:3:"api";s:5:"1.4.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2005-08-14";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:34:"http://www.php.net/license/3_0.txt";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:171:"* MAJOR SECURITY FIX: eliminate use of eval(). * Using socket_get_status() because stream_get_meta_data() was introduced in 4.3.0, but we need to support 4.2.0. Bug 4805.";}i:23;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.4.1";s:3:"api";s:5:"1.4.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2005-09-07";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:34:"http://www.php.net/license/3_0.txt";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:158:"* Don't add debug info unless debug is on. Bug 5136. * Use is_a() instead of class_name() so people can use their own XML_RPC_Message objects. Request 5002.";}i:24;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.4.2";s:3:"api";s:5:"1.4.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2005-09-18";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:34:"http://www.php.net/license/3_0.txt";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:53:"* Allow empty <value>'s without <types>'s. Bug 5315.";}i:25;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.4.3";s:3:"api";s:5:"1.4.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2005-09-24";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:34:"http://www.php.net/license/3_0.txt";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:72:"* Make XML_RPC_encode() properly handle dateTime.iso8601. Request 5117.";}i:26;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.4.4";s:3:"api";s:5:"1.4.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2005-10-15";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:34:"http://www.php.net/license/3_0.txt";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:46:"* Properly deal with empty values in struct's.";}i:27;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.4.5";s:3:"api";s:5:"1.4.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2006-01-14";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:34:"http://www.php.net/license/3_0.txt";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:114:"* Have server send headers individualy as opposed to sending them all at once. Necessary due to changes PHP 4.4.2.";}i:28;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.4.6";s:3:"api";s:5:"1.4.6";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2006-04-07";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:34:"http://www.php.net/license/3_0.txt";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:209:"* Add XML_RPC_Message::$remove_extra_lines property. Defaults to true. If set to false, extra lines are left in place. Bug 7088. * Add XML_RPC_Message::$response_payload property. Makes logging responses easy.";}i:29;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.4.7";s:3:"api";s:5:"1.4.6";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2006-04-10";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:34:"http://www.php.net/license/3_0.txt";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:132:"* Add include_once for PEAR if need to load xml extension. Bug 7358. * Add dependency for xml extension in package file. Bug 7358.";}i:30;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.4.8";s:3:"api";s:5:"1.4.6";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2006-04-16";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:34:"http://www.php.net/license/3_0.txt";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:129:"* Characters other than alpha-numeric, punctuation, SP, TAB, LF and CR break the XML parser, encode value via Base 64. Bug 7376.";}i:31;a:5:{s:7:"version";a:2:{s:7:"release";s:8:"1.5.0RC1";s:3:"api";s:5:"1.5.0";}s:9:"stability";a:2:{s:7:"release";s:4:"beta";s:3:"api";s:4:"beta";}s:4:"date";s:10:"2006-06-16";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:35:"http://www.php.net/license/3_01.txt";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:749:"* Provide complete multi-byte string support for systems with the mbstring extension enabled. Bug 7837. * If PHP's mbstring extension is enabled, use mb_convert_encoding() to ensure the client payload matches the intended encoding. This is a better resolution of Bug 7376. * Turn off the default of automatically base64 encoding strings that can generate fatal errors in PHP's SAX parser. The automatic base64 encoding can be turned on via the new XML_RPC_Client::setAutoBase64() method. The auto-encoding is a workaround for systems that don't have PHP's mbstring extension available. (The automatic base64 encoding was added in the prior release, 1.4.8, and caused problems for users who don't control the receiving end of the requests.) Bug 7837.";}i:32;a:5:{s:7:"version";a:2:{s:7:"release";s:8:"1.5.0RC2";s:3:"api";s:5:"1.5.0";}s:9:"stability";a:2:{s:7:"release";s:4:"beta";s:3:"api";s:4:"beta";}s:4:"date";s:10:"2006-06-21";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:35:"http://www.php.net/license/3_01.txt";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:127:"* If PHP's mbstring extension is enabled, use mb_convert_encoding() to ensure the server payload matches the intended encoding.";}i:33;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.5.0";s:3:"api";s:5:"1.5.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2006-07-11";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:35:"http://www.php.net/license/3_01.txt";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:134:"No changes from 1.5.0RC2. The primary change from 1.4.8 is improved multi-byte support. See the change log for complete information.";}i:34;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.5.1";s:3:"api";s:5:"1.5.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2006-10-28";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:35:"http://www.php.net/license/3_01.txt";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:280:"* Turn passing payload through mb_convert_encoding() off by default. Use new XML_RPC_Message::setConvertPayloadEncoding() and XML_RPC_Server::setConvertPayloadEncoding() to turn it on. Bug 8632. * Have XML_RPC_Value::scalarval() return FALSE if value is not a scalar. Bug 8251.";}i:35;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.5.2";s:3:"api";s:5:"1.5.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2009-08-18";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:35:"http://www.php.net/license/3_01.txt";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:64:"* Change license in empty-value-struct.php from PHP 3.0 to 3.01.";}i:36;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.5.3";s:3:"api";s:5:"1.5.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2010-01-14";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:35:"http://www.php.net/license/3_01.txt";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:242:"* Make licenses consistent. Bug 12575. * Fix serializedata() for non-sequentially indexed arrays. Bug 16780. * Show request information in debug mode. Request 8240. * Creating the payload before opening a socket connection. Request 11981.";}i:37;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.5.4";s:3:"api";s:5:"1.5.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2010-07-03";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:35:"http://www.php.net/license/3_01.txt";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:209:"* Change ereg functions to preg due to deprecation (Request 17546 and then some.) * Fix bugs in XML_RPC_Dump error detection process. * Escape XML special characters in key names of struct elements. Bug 17368.";}i:38;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.5.5";s:3:"api";s:5:"1.5.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2011-08-27";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:35:"http://www.php.net/license/3_01.txt";}s:8:"_content";s:11:"PHP License";}s:5:"notes";s:92:"* Adjust is_a() usage due to change in PHP 5.3.7. * Fix error populating headers. Bug 18653.";}}}s:8:"filelist";a:12:{s:24:"tests/actual-request.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"41158fbcb2d49755fdaf877f92e85362";s:4:"name";s:24:"tests/actual-request.php";s:4:"role";s:4:"test";s:12:"installed_as";s:67:"/opt/alt/php56/usr/share/pear/test/XML_RPC/tests/actual-request.php";}s:16:"tests/allgot.inc";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"e9a0aa974052ee47c41ad0274c728dc6";s:4:"name";s:16:"tests/allgot.inc";s:4:"role";s:4:"test";s:12:"installed_as";s:59:"/opt/alt/php56/usr/share/pear/test/XML_RPC/tests/allgot.inc";}s:28:"tests/empty-value-struct.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"60cd6342dd96bf0be4d4d3cbb7813cf4";s:4:"name";s:28:"tests/empty-value-struct.php";s:4:"role";s:4:"test";s:12:"installed_as";s:71:"/opt/alt/php56/usr/share/pear/test/XML_RPC/tests/empty-value-struct.php";}s:21:"tests/empty-value.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"2bdf63e6eba97ea12ac4f5a3a92fdc3a";s:4:"name";s:21:"tests/empty-value.php";s:4:"role";s:4:"test";s:12:"installed_as";s:64:"/opt/alt/php56/usr/share/pear/test/XML_RPC/tests/empty-value.php";}s:16:"tests/encode.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"94ab1218006a7dc8fdd362dffc48777f";s:4:"name";s:16:"tests/encode.php";s:4:"role";s:4:"test";s:12:"installed_as";s:59:"/opt/alt/php56/usr/share/pear/test/XML_RPC/tests/encode.php";}s:21:"tests/extra-lines.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"74921ba059a82e2ec9c7734c187a3f2c";s:4:"name";s:21:"tests/extra-lines.php";s:4:"role";s:4:"test";s:12:"installed_as";s:64:"/opt/alt/php56/usr/share/pear/test/XML_RPC/tests/extra-lines.php";}s:19:"tests/protoport.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"3e200b7a09217395196987f1e948871a";s:4:"name";s:19:"tests/protoport.php";s:4:"role";s:4:"test";s:12:"installed_as";s:62:"/opt/alt/php56/usr/share/pear/test/XML_RPC/tests/protoport.php";}s:19:"tests/test_Dump.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"f3af6b2112368d543f80907f1b040b77";s:4:"name";s:19:"tests/test_Dump.php";s:4:"role";s:4:"test";s:12:"installed_as";s:62:"/opt/alt/php56/usr/share/pear/test/XML_RPC/tests/test_Dump.php";}s:15:"tests/types.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"6fb82404a22f0e751697c8ffe0557a6a";s:4:"name";s:15:"tests/types.php";s:4:"role";s:4:"test";s:12:"installed_as";s:58:"/opt/alt/php56/usr/share/pear/test/XML_RPC/tests/types.php";}s:11:"XML/RPC.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"b361011f028738d20e8905cfa2fcefc5";s:4:"name";s:11:"XML/RPC.php";s:4:"role";s:3:"php";s:12:"installed_as";s:41:"/opt/alt/php56/usr/share/pear/XML/RPC.php";}s:16:"XML/RPC/Dump.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"2036a5c5c6e965b93533cd050442fa98";s:4:"name";s:16:"XML/RPC/Dump.php";s:4:"role";s:3:"php";s:12:"installed_as";s:46:"/opt/alt/php56/usr/share/pear/XML/RPC/Dump.php";}s:18:"XML/RPC/Server.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"8a0123129ef7eb5615505b95d0f0b72f";s:4:"name";s:18:"XML/RPC/Server.php";s:4:"role";s:3:"php";s:12:"installed_as";s:48:"/opt/alt/php56/usr/share/pear/XML/RPC/Server.php";}}s:12:"_lastversion";N;s:7:"dirtree";a:4:{s:48:"/opt/alt/php56/usr/share/pear/test/XML_RPC/tests";b:1;s:42:"/opt/alt/php56/usr/share/pear/test/XML_RPC";b:1;s:33:"/opt/alt/php56/usr/share/pear/XML";b:1;s:37:"/opt/alt/php56/usr/share/pear/XML/RPC";b:1;}s:3:"old";a:7:{s:7:"version";s:5:"1.5.5";s:12:"release_date";s:10:"2011-08-27";s:13:"release_state";s:6:"stable";s:15:"release_license";s:11:"PHP License";s:13:"release_notes";s:92:"* Adjust is_a() usage due to change in PHP 5.3.7. * Fix error populating headers. Bug 18653.";s:12:"release_deps";a:3:{i:0;a:4:{s:4:"type";s:3:"php";s:3:"rel";s:2:"ge";s:7:"version";s:5:"4.2.0";s:8:"optional";s:2:"no";}i:1;a:6:{s:4:"type";s:3:"pkg";s:7:"channel";s:12:"pear.php.net";s:4:"name";s:4:"PEAR";s:3:"rel";s:2:"ge";s:7:"version";s:7:"1.4.0a1";s:8:"optional";s:2:"no";}i:2;a:4:{s:4:"type";s:3:"ext";s:4:"name";s:3:"xml";s:3:"rel";s:3:"has";s:8:"optional";s:2:"no";}}s:11:"maintainers";a:2:{i:0;a:5:{s:4:"name";s:11:"Stig Bakken";s:5:"email";s:12:"stig@php.net";s:6:"active";s:2:"no";s:6:"handle";s:3:"ssb";s:4:"role";s:4:"lead";}i:1;a:5:{s:4:"name";s:16:"Daniel Convissor";s:5:"email";s:15:"danielc@php.net";s:6:"active";s:2:"no";s:6:"handle";s:7:"danielc";s:4:"role";s:4:"lead";}}}s:10:"xsdversion";s:3:"2.0";s:13:"_lastmodified";i:1747068539;}PK�����u]->,6��,6��#��.registry/structures_linkedlist.regnu�[��������a:21:{s:7:"attribs";a:6:{s:15:"packagerversion";s:5:"1.9.0";s:7:"version";s:3:"2.0";s:5:"xmlns";s:35:"http://pear.php.net/dtd/package-2.0";s:11:"xmlns:tasks";s:33:"http://pear.php.net/dtd/tasks-1.0";s:9:"xmlns:xsi";s:41:"http://www.w3.org/2001/XMLSchema-instance";s:18:"xsi:schemaLocation";s:147:"http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd";}s:4:"name";s:21:"Structures_LinkedList";s:7:"channel";s:12:"pear.php.net";s:7:"summary";s:41:"Implements singly and doubly-linked lists";s:11:"description";s:181:"A singly-linked list offers the ability to insert or delete nodes at any point within the list. A doubly-linked list also offers the ability to request previous nodes in the list.";s:4:"lead";a:4:{s:4:"name";s:9:"Dan Scott";s:4:"user";s:3:"dbs";s:5:"email";s:11:"dbs@php.net";s:6:"active";s:3:"yes";}s:4:"date";s:10:"2010-08-15";s:4:"time";s:8:"10:13:00";s:7:"version";a:2:{s:7:"release";s:5:"0.2.2";s:3:"api";s:5:"0.2.0";}s:9:"stability";a:2:{s:7:"release";s:4:"beta";s:3:"api";s:4:"beta";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:38:"http://apache.org/licenses/LICENSE-2.0";}s:8:"_content";s:27:"Apache License, Version 2.0";}s:5:"notes";s:20:"* Fix package layout";s:8:"contents";a:1:{s:3:"dir";a:2:{s:7:"attribs";a:2:{s:14:"baseinstalldir";s:21:"Structures/LinkedList";s:4:"name";s:1:"/";}s:4:"file";a:22:{i:0;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"b7ac5a9d6d9a3eb2c3cbb1db76ad75a3";s:4:"name";s:32:"Structures/LinkedList/Double.php";s:4:"role";s:3:"php";}}i:1;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"310eefdff99016e4a3282dd02d5a7efa";s:4:"name";s:32:"Structures/LinkedList/Single.php";s:4:"role";s:3:"php";}}i:2;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:21:"Structures/LinkedList";s:6:"md5sum";s:32:"9b1565a45687bb631a452b152e0d3d15";s:4:"name";s:32:"examples/double_link_example.php";s:4:"role";s:3:"doc";}}i:3;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:21:"Structures/LinkedList";s:6:"md5sum";s:32:"56d8c9a65cf967f09136a1b5b42fb787";s:4:"name";s:32:"examples/single_link_example.php";s:4:"role";s:3:"doc";}}i:4;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:21:"Structures/LinkedList";s:6:"md5sum";s:32:"54a63c64625c0b1785d890cc0ecb6957";s:4:"name";s:20:"tests/LinkTester.php";s:4:"role";s:4:"test";}}i:5;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:21:"Structures/LinkedList";s:6:"md5sum";s:32:"6138a89189609d8b0c35a69ce6995457";s:4:"name";s:26:"tests/SingleLinkTester.php";s:4:"role";s:4:"test";}}i:6;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:21:"Structures/LinkedList";s:6:"md5sum";s:32:"c7a6ad89f79222cf62148893e88a0b5a";s:4:"name";s:19:"tests/link_001.phpt";s:4:"role";s:4:"test";}}i:7;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:21:"Structures/LinkedList";s:6:"md5sum";s:32:"960408b3ea85cfe453f7d4b1814784ea";s:4:"name";s:19:"tests/link_002.phpt";s:4:"role";s:4:"test";}}i:8;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:21:"Structures/LinkedList";s:6:"md5sum";s:32:"392d4c38523f764091433fdf19cf4943";s:4:"name";s:19:"tests/link_003.phpt";s:4:"role";s:4:"test";}}i:9;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:21:"Structures/LinkedList";s:6:"md5sum";s:32:"88bfd20fe97800c4f69ec7577abd2ecd";s:4:"name";s:19:"tests/link_004.phpt";s:4:"role";s:4:"test";}}i:10;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:21:"Structures/LinkedList";s:6:"md5sum";s:32:"dac8403b1df9d64e16e45e87121a74fa";s:4:"name";s:19:"tests/link_005.phpt";s:4:"role";s:4:"test";}}i:11;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:21:"Structures/LinkedList";s:6:"md5sum";s:32:"bfc84666dbe64008101adadecf008677";s:4:"name";s:19:"tests/link_006.phpt";s:4:"role";s:4:"test";}}i:12;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:21:"Structures/LinkedList";s:6:"md5sum";s:32:"1a7eb8c8a63ec97fdb0154214c679cfa";s:4:"name";s:19:"tests/link_007.phpt";s:4:"role";s:4:"test";}}i:13;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:21:"Structures/LinkedList";s:6:"md5sum";s:32:"86f0c12acf2706a82d0d0dc625ab3608";s:4:"name";s:26:"tests/single_link_001.phpt";s:4:"role";s:4:"test";}}i:14;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:21:"Structures/LinkedList";s:6:"md5sum";s:32:"19c3e9b406dffe9c315e0264e0d257f8";s:4:"name";s:26:"tests/single_link_002.phpt";s:4:"role";s:4:"test";}}i:15;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:21:"Structures/LinkedList";s:6:"md5sum";s:32:"d4029576a49c41f18c35f72bdb37da7e";s:4:"name";s:26:"tests/single_link_003.phpt";s:4:"role";s:4:"test";}}i:16;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:21:"Structures/LinkedList";s:6:"md5sum";s:32:"574cb63523d7716f37fad368eefc695b";s:4:"name";s:26:"tests/single_link_004.phpt";s:4:"role";s:4:"test";}}i:17;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:21:"Structures/LinkedList";s:6:"md5sum";s:32:"4712a8421da2369e72ec789e0fe3993f";s:4:"name";s:26:"tests/single_link_005.phpt";s:4:"role";s:4:"test";}}i:18;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:21:"Structures/LinkedList";s:6:"md5sum";s:32:"a7f31515a9a3260aa1c17e003a4c352c";s:4:"name";s:26:"tests/single_link_006.phpt";s:4:"role";s:4:"test";}}i:19;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:21:"Structures/LinkedList";s:6:"md5sum";s:32:"6fe94be57c862475367ed91a7284a6b2";s:4:"name";s:26:"tests/single_link_007.phpt";s:4:"role";s:4:"test";}}i:20;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:21:"Structures/LinkedList";s:6:"md5sum";s:32:"6e8edc55d5a37acbe96ed9860b8680cc";s:4:"name";s:9:"CHANGELOG";s:4:"role";s:3:"doc";}}i:21;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:21:"Structures/LinkedList";s:6:"md5sum";s:32:"3b83ef96387f14655fc854ddc3c6bd57";s:4:"name";s:7:"LICENSE";s:4:"role";s:3:"doc";}}}}}s:12:"dependencies";a:1:{s:8:"required";a:2:{s:3:"php";a:1:{s:3:"min";s:3:"5.0";}s:13:"pearinstaller";a:1:{s:3:"min";s:5:"1.4.0";}}}s:10:"phprelease";s:0:"";s:8:"filelist";a:22:{s:32:"Structures/LinkedList/Double.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"b7ac5a9d6d9a3eb2c3cbb1db76ad75a3";s:4:"name";s:32:"Structures/LinkedList/Double.php";s:4:"role";s:3:"php";s:12:"installed_as";s:62:"/opt/alt/php56/usr/share/pear/Structures/LinkedList/Double.php";}s:32:"Structures/LinkedList/Single.php";a:5:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"310eefdff99016e4a3282dd02d5a7efa";s:4:"name";s:32:"Structures/LinkedList/Single.php";s:4:"role";s:3:"php";s:12:"installed_as";s:62:"/opt/alt/php56/usr/share/pear/Structures/LinkedList/Single.php";}s:32:"examples/double_link_example.php";a:5:{s:14:"baseinstalldir";s:21:"Structures/LinkedList";s:6:"md5sum";s:32:"9b1565a45687bb631a452b152e0d3d15";s:4:"name";s:32:"examples/double_link_example.php";s:4:"role";s:3:"doc";s:12:"installed_as";s:88:"/opt/alt/php56/usr/share/doc/pear/Structures_LinkedList/examples/double_link_example.php";}s:32:"examples/single_link_example.php";a:5:{s:14:"baseinstalldir";s:21:"Structures/LinkedList";s:6:"md5sum";s:32:"56d8c9a65cf967f09136a1b5b42fb787";s:4:"name";s:32:"examples/single_link_example.php";s:4:"role";s:3:"doc";s:12:"installed_as";s:88:"/opt/alt/php56/usr/share/doc/pear/Structures_LinkedList/examples/single_link_example.php";}s:20:"tests/LinkTester.php";a:5:{s:14:"baseinstalldir";s:21:"Structures/LinkedList";s:6:"md5sum";s:32:"54a63c64625c0b1785d890cc0ecb6957";s:4:"name";s:20:"tests/LinkTester.php";s:4:"role";s:4:"test";s:12:"installed_as";s:77:"/opt/alt/php56/usr/share/pear/test/Structures_LinkedList/tests/LinkTester.php";}s:26:"tests/SingleLinkTester.php";a:5:{s:14:"baseinstalldir";s:21:"Structures/LinkedList";s:6:"md5sum";s:32:"6138a89189609d8b0c35a69ce6995457";s:4:"name";s:26:"tests/SingleLinkTester.php";s:4:"role";s:4:"test";s:12:"installed_as";s:83:"/opt/alt/php56/usr/share/pear/test/Structures_LinkedList/tests/SingleLinkTester.php";}s:19:"tests/link_001.phpt";a:5:{s:14:"baseinstalldir";s:21:"Structures/LinkedList";s:6:"md5sum";s:32:"c7a6ad89f79222cf62148893e88a0b5a";s:4:"name";s:19:"tests/link_001.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:76:"/opt/alt/php56/usr/share/pear/test/Structures_LinkedList/tests/link_001.phpt";}s:19:"tests/link_002.phpt";a:5:{s:14:"baseinstalldir";s:21:"Structures/LinkedList";s:6:"md5sum";s:32:"960408b3ea85cfe453f7d4b1814784ea";s:4:"name";s:19:"tests/link_002.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:76:"/opt/alt/php56/usr/share/pear/test/Structures_LinkedList/tests/link_002.phpt";}s:19:"tests/link_003.phpt";a:5:{s:14:"baseinstalldir";s:21:"Structures/LinkedList";s:6:"md5sum";s:32:"392d4c38523f764091433fdf19cf4943";s:4:"name";s:19:"tests/link_003.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:76:"/opt/alt/php56/usr/share/pear/test/Structures_LinkedList/tests/link_003.phpt";}s:19:"tests/link_004.phpt";a:5:{s:14:"baseinstalldir";s:21:"Structures/LinkedList";s:6:"md5sum";s:32:"88bfd20fe97800c4f69ec7577abd2ecd";s:4:"name";s:19:"tests/link_004.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:76:"/opt/alt/php56/usr/share/pear/test/Structures_LinkedList/tests/link_004.phpt";}s:19:"tests/link_005.phpt";a:5:{s:14:"baseinstalldir";s:21:"Structures/LinkedList";s:6:"md5sum";s:32:"dac8403b1df9d64e16e45e87121a74fa";s:4:"name";s:19:"tests/link_005.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:76:"/opt/alt/php56/usr/share/pear/test/Structures_LinkedList/tests/link_005.phpt";}s:19:"tests/link_006.phpt";a:5:{s:14:"baseinstalldir";s:21:"Structures/LinkedList";s:6:"md5sum";s:32:"bfc84666dbe64008101adadecf008677";s:4:"name";s:19:"tests/link_006.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:76:"/opt/alt/php56/usr/share/pear/test/Structures_LinkedList/tests/link_006.phpt";}s:19:"tests/link_007.phpt";a:5:{s:14:"baseinstalldir";s:21:"Structures/LinkedList";s:6:"md5sum";s:32:"1a7eb8c8a63ec97fdb0154214c679cfa";s:4:"name";s:19:"tests/link_007.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:76:"/opt/alt/php56/usr/share/pear/test/Structures_LinkedList/tests/link_007.phpt";}s:26:"tests/single_link_001.phpt";a:5:{s:14:"baseinstalldir";s:21:"Structures/LinkedList";s:6:"md5sum";s:32:"86f0c12acf2706a82d0d0dc625ab3608";s:4:"name";s:26:"tests/single_link_001.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:83:"/opt/alt/php56/usr/share/pear/test/Structures_LinkedList/tests/single_link_001.phpt";}s:26:"tests/single_link_002.phpt";a:5:{s:14:"baseinstalldir";s:21:"Structures/LinkedList";s:6:"md5sum";s:32:"19c3e9b406dffe9c315e0264e0d257f8";s:4:"name";s:26:"tests/single_link_002.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:83:"/opt/alt/php56/usr/share/pear/test/Structures_LinkedList/tests/single_link_002.phpt";}s:26:"tests/single_link_003.phpt";a:5:{s:14:"baseinstalldir";s:21:"Structures/LinkedList";s:6:"md5sum";s:32:"d4029576a49c41f18c35f72bdb37da7e";s:4:"name";s:26:"tests/single_link_003.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:83:"/opt/alt/php56/usr/share/pear/test/Structures_LinkedList/tests/single_link_003.phpt";}s:26:"tests/single_link_004.phpt";a:5:{s:14:"baseinstalldir";s:21:"Structures/LinkedList";s:6:"md5sum";s:32:"574cb63523d7716f37fad368eefc695b";s:4:"name";s:26:"tests/single_link_004.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:83:"/opt/alt/php56/usr/share/pear/test/Structures_LinkedList/tests/single_link_004.phpt";}s:26:"tests/single_link_005.phpt";a:5:{s:14:"baseinstalldir";s:21:"Structures/LinkedList";s:6:"md5sum";s:32:"4712a8421da2369e72ec789e0fe3993f";s:4:"name";s:26:"tests/single_link_005.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:83:"/opt/alt/php56/usr/share/pear/test/Structures_LinkedList/tests/single_link_005.phpt";}s:26:"tests/single_link_006.phpt";a:5:{s:14:"baseinstalldir";s:21:"Structures/LinkedList";s:6:"md5sum";s:32:"a7f31515a9a3260aa1c17e003a4c352c";s:4:"name";s:26:"tests/single_link_006.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:83:"/opt/alt/php56/usr/share/pear/test/Structures_LinkedList/tests/single_link_006.phpt";}s:26:"tests/single_link_007.phpt";a:5:{s:14:"baseinstalldir";s:21:"Structures/LinkedList";s:6:"md5sum";s:32:"6fe94be57c862475367ed91a7284a6b2";s:4:"name";s:26:"tests/single_link_007.phpt";s:4:"role";s:4:"test";s:12:"installed_as";s:83:"/opt/alt/php56/usr/share/pear/test/Structures_LinkedList/tests/single_link_007.phpt";}s:9:"CHANGELOG";a:5:{s:14:"baseinstalldir";s:21:"Structures/LinkedList";s:6:"md5sum";s:32:"6e8edc55d5a37acbe96ed9860b8680cc";s:4:"name";s:9:"CHANGELOG";s:4:"role";s:3:"doc";s:12:"installed_as";s:65:"/opt/alt/php56/usr/share/doc/pear/Structures_LinkedList/CHANGELOG";}s:7:"LICENSE";a:5:{s:14:"baseinstalldir";s:21:"Structures/LinkedList";s:6:"md5sum";s:32:"3b83ef96387f14655fc854ddc3c6bd57";s:4:"name";s:7:"LICENSE";s:4:"role";s:3:"doc";s:12:"installed_as";s:63:"/opt/alt/php56/usr/share/doc/pear/Structures_LinkedList/LICENSE";}}s:12:"_lastversion";N;s:7:"dirtree";a:6:{s:51:"/opt/alt/php56/usr/share/pear/Structures/LinkedList";b:1;s:40:"/opt/alt/php56/usr/share/pear/Structures";b:1;s:64:"/opt/alt/php56/usr/share/doc/pear/Structures_LinkedList/examples";b:1;s:55:"/opt/alt/php56/usr/share/doc/pear/Structures_LinkedList";b:1;s:62:"/opt/alt/php56/usr/share/pear/test/Structures_LinkedList/tests";b:1;s:56:"/opt/alt/php56/usr/share/pear/test/Structures_LinkedList";b:1;}s:3:"old";a:7:{s:7:"version";s:5:"0.2.2";s:12:"release_date";s:10:"2010-08-15";s:13:"release_state";s:4:"beta";s:15:"release_license";s:27:"Apache License, Version 2.0";s:13:"release_notes";s:20:"* Fix package layout";s:12:"release_deps";a:2:{i:0;a:4:{s:4:"type";s:3:"php";s:3:"rel";s:2:"ge";s:7:"version";s:3:"5.0";s:8:"optional";s:2:"no";}i:1;a:6:{s:4:"type";s:3:"pkg";s:7:"channel";s:12:"pear.php.net";s:4:"name";s:4:"PEAR";s:3:"rel";s:2:"ge";s:7:"version";s:5:"1.4.0";s:8:"optional";s:2:"no";}}s:11:"maintainers";a:1:{i:0;a:5:{s:4:"name";s:9:"Dan Scott";s:5:"email";s:11:"dbs@php.net";s:6:"active";s:3:"yes";s:6:"handle";s:3:"dbs";s:4:"role";s:4:"lead";}}}s:10:"xsdversion";s:3:"2.0";s:13:"_lastmodified";i:1669631553;}PK�����u]-EN��EN����.registry/net_sieve.regnu�[��������a:22:{s:7:"attribs";a:6:{s:15:"packagerversion";s:7:"1.10.12";s:7:"version";s:3:"2.0";s:5:"xmlns";s:35:"http://pear.php.net/dtd/package-2.0";s:11:"xmlns:tasks";s:33:"http://pear.php.net/dtd/tasks-1.0";s:9:"xmlns:xsi";s:41:"http://www.w3.org/2001/XMLSchema-instance";s:18:"xsi:schemaLocation";s:147:"http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd";}s:4:"name";s:9:"Net_Sieve";s:7:"channel";s:12:"pear.php.net";s:7:"summary";s:34:"Handles talking to a sieve server.";s:11:"description";s:160:"This package provides an API to talk to servers implementing the managesieve protocol. It can be used to install and remove sieve scripts, mark them active etc.";s:4:"lead";a:5:{i:0;a:4:{s:4:"name";s:19:"Aleksander Machniak";s:4:"user";s:4:"alec";s:5:"email";s:12:"alec@alec.pl";s:6:"active";s:3:"yes";}i:1;a:4:{s:4:"name";s:13:"Jan Schneider";s:4:"user";s:6:"yunosh";s:5:"email";s:13:"jan@horde.org";s:6:"active";s:2:"no";}i:2;a:4:{s:4:"name";s:13:"Richard Heyes";s:4:"user";s:7:"richard";s:5:"email";s:15:"richard@php.net";s:6:"active";s:2:"no";}i:3;a:4:{s:4:"name";s:21:"Damian Fernandez Sosa";s:4:"user";s:6:"damian";s:5:"email";s:20:"damlists@cnba.uba.ar";s:6:"active";s:2:"no";}i:4;a:4:{s:4:"name";s:12:"Anish Mistry";s:4:"user";s:7:"amistry";s:5:"email";s:26:"amistry@am-productions.biz";s:6:"active";s:2:"no";}}s:4:"date";s:10:"2021-04-24";s:4:"time";s:8:"13:33:52";s:7:"version";a:2:{s:7:"release";s:5:"1.4.5";s:3:"api";s:5:"1.4.3";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:3:"BSD";}s:5:"notes";s:38:"* Support XOAUTH2 authorization method";s:8:"contents";a:1:{s:3:"dir";a:2:{s:7:"attribs";a:2:{s:14:"baseinstalldir";s:3:"Net";s:4:"name";s:1:"/";}s:4:"file";a:4:{i:0;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:3:"Net";s:6:"md5sum";s:32:"ef8cd688674fba85cc067e06c221e43b";s:4:"name";s:21:"tests/largescript.siv";s:4:"role";s:4:"test";}}i:1;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:3:"Net";s:6:"md5sum";s:32:"7d772fe47ee45bdb521dd581281f38c3";s:4:"name";s:21:"tests/config.php.dist";s:4:"role";s:4:"test";}}i:2;a:1:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:3:"Net";s:6:"md5sum";s:32:"6050fac5e66a4a6bbed7913f826974ed";s:4:"name";s:19:"tests/SieveTest.php";s:4:"role";s:4:"test";}}i:3;a:2:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:3:"Net";s:6:"md5sum";s:32:"2a45a03c042351957f3435929a17bca3";s:4:"name";s:9:"Sieve.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}}}}s:12:"dependencies";a:2:{s:8:"required";a:3:{s:3:"php";a:1:{s:3:"min";s:5:"5.0.0";}s:13:"pearinstaller";a:1:{s:3:"min";s:7:"1.4.0b1";}s:7:"package";a:3:{s:4:"name";s:10:"Net_Socket";s:7:"channel";s:12:"pear.php.net";s:3:"min";s:3:"1.0";}}s:8:"optional";a:1:{s:7:"package";a:3:{s:4:"name";s:9:"Auth_SASL";s:7:"channel";s:12:"pear.php.net";s:3:"min";s:3:"1.0";}}}s:10:"phprelease";s:0:"";s:9:"changelog";a:1:{s:7:"release";a:28:{i:0;a:5:{s:4:"date";s:10:"2018-03-04";s:7:"version";a:2:{s:7:"release";s:5:"1.4.3";s:3:"api";s:5:"1.4.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:3:"BSD";}s:5:"notes";s:31:"* Support GSSAPI authentication";}i:1;a:5:{s:4:"date";s:10:"2018-02-14";s:7:"version";a:2:{s:7:"release";s:5:"1.4.2";s:3:"api";s:5:"1.4.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:3:"BSD";}s:5:"notes";s:78:"* Composer: Fix license identifier, don't use unbound version numbers for deps";}i:2;a:5:{s:4:"date";s:10:"2017-05-26";s:7:"version";a:2:{s:7:"release";s:5:"1.4.1";s:3:"api";s:5:"1.4.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:3:"BSD";}s:5:"notes";s:199:"* Use 8bit instead of latin1 for string length in bytes calculation * Extend listScripts() so it's possible to get an active script name in one go * Request #20491: Skip redundant CAPABILITY requests";}i:3;a:5:{s:4:"date";s:10:"2017-05-21";s:7:"version";a:2:{s:7:"release";s:5:"1.4.0";s:3:"api";s:5:"1.4.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:3:"BSD";}s:5:"notes";s:129:"* Dropped PHP4 support, fixed PHP7 warnings * Fixed E_DEPRECATED warning on Auth_SASL::factory() call * Enable later TLS versions";}i:4;a:5:{s:4:"date";s:10:"2015-01-20";s:7:"version";a:2:{s:7:"release";s:5:"1.3.4";s:3:"api";s:5:"1.3.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:3:"BSD";}s:5:"notes";s:70:"* Remove erroneous and unnecessary active script caching (Bug #20472).";}i:5;a:5:{s:4:"date";s:10:"2014-09-24";s:7:"version";a:2:{s:7:"release";s:5:"1.3.3";s:3:"api";s:5:"1.3.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:3:"BSD";}s:5:"notes";s:111:"* Fix notices from non-static calling of PEAR methods. * Fix reading OK responses with string literal messages.";}i:6;a:5:{s:4:"date";s:10:"2011-08-06";s:7:"version";a:2:{s:7:"release";s:5:"1.3.2";s:3:"api";s:5:"1.3.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:3:"BSD";}s:5:"notes";s:146:"* Fix referrals if host data or user credentials are passed to connect() and login() instead of the constructor (Aleksander Machniak, Bug #17107).";}i:7;a:5:{s:4:"date";s:10:"2011-08-05";s:7:"version";a:2:{s:7:"release";s:5:"1.3.1";s:3:"api";s:5:"1.3.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:3:"BSD";}s:5:"notes";s:417:"* Query capabilities again after successful authentication (Jesse Crawford, Request #18382). * Escape quotes and backslashes in script names, and use literal strings for script names with non-ASCII characters (Aleksander Machniak, Bug #16691). * Work around broken STARTTLS behavior in Cyrus versions before 2.3.10 (Aleksander Machniak, Bug #18241). * Improve string literal parsing (Aleksander Machniak, Bug #18228).";}i:8;a:5:{s:4:"date";s:10:"2010-07-01";s:7:"version";a:2:{s:7:"release";s:5:"1.3.0";s:3:"api";s:5:"1.3.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:3:"BSD";}s:5:"notes";s:122:"* Add debug handler parameter to constructor. * Fix LOGIN authentication (Agustín Eijo, Aleksander Machniak, Bug #17527).";}i:9;a:5:{s:4:"date";s:10:"2010-06-13";s:7:"version";a:2:{s:7:"release";s:5:"1.2.2";s:3:"api";s:5:"1.2.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:3:"BSD";}s:5:"notes";s:57:"* Fix SASL authentication without Auth_SASL (Bug #17489).";}i:10;a:5:{s:4:"date";s:10:"2010-04-19";s:7:"version";a:2:{s:7:"release";s:5:"1.2.1";s:3:"api";s:5:"1.2.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:3:"BSD";}s:5:"notes";s:72:"* Fix DIGEST-MD5 authentication with Dovecot (Stef Simoens, Bug #17320).";}i:11;a:5:{s:4:"date";s:10:"2010-04-01";s:7:"version";a:2:{s:7:"release";s:5:"1.2.0";s:3:"api";s:5:"1.2.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:3:"BSD";}s:5:"notes";s:432:"Changes since version 1.2.0b1: * Fix DIGEST-MD5 authentication (Aleksander Machniak, Bug #17285). * Don't try to call dl() if mbstring extension isn't loaded (Bug #17038). Changes since version 1.1.7: * Added support for adding a custom debug handler (Aleksander Machniak, Request #16681). * Fix breakage with certain locales, especially Turkish. * Fix reading authentication responses without literals (Bug #16647). * Code cleanup.";}i:12;a:5:{s:4:"date";s:10:"2009-10-07";s:7:"version";a:2:{s:7:"release";s:7:"1.2.0b1";s:3:"api";s:5:"1.2.0";}s:9:"stability";a:2:{s:7:"release";s:4:"beta";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:3:"BSD";}s:5:"notes";s:231:"* Added support for adding a custom debug handler (Aleksander Machniak, Request #16681). * Fix breakage with certain locales, especially Turkish. * Fix reading authentication responses without literals (Bug #16647). * Code cleanup.";}i:13;a:5:{s:4:"date";s:10:"2009-07-24";s:7:"version";a:2:{s:7:"release";s:5:"1.1.7";s:3:"api";s:5:"1.1.6";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:3:"BSD";}s:5:"notes";s:91:"* Fixed STARTTLS support (Bug #14205). * Added connect options and EXTERNAL authentication.";}i:14;a:5:{s:4:"date";s:10:"2008-03-22";s:7:"version";a:2:{s:7:"release";s:5:"1.1.6";s:3:"api";s:5:"1.1.6";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:3:"BSD";}s:5:"notes";s:88:"* Fixed Bug #9273 * Fixed copy/paste error in CRAM and DIGEST authentication error case.";}i:15;a:5:{s:4:"date";s:10:"2006-10-24";s:7:"version";a:2:{s:7:"release";s:5:"1.1.5";s:3:"api";s:5:"1.1.5";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:3:"BSD";}s:5:"notes";s:47:"* Fixed Bug connect() bug * Fixed Request #8071";}i:16;a:5:{s:4:"date";s:10:"2006-09-09";s:7:"version";a:2:{s:7:"release";s:5:"1.1.4";s:3:"api";s:5:"1.1.4";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:3:"BSD";}s:5:"notes";s:207:"* Fixed Bug #8452 Unterminated read loop * Fixed Bug #7845 Add mbstring support * Added Request #8071 Enable the ability to toggle TLS support if available. * Added Request #8453 Clean up PHPDoc and comments";}i:17;a:5:{s:4:"date";s:10:"2006-05-21";s:7:"version";a:2:{s:7:"release";s:5:"1.1.3";s:3:"api";s:5:"1.1.3";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:3:"BSD";}s:5:"notes";s:164:"* Correctly Fixed Bug #3519 Net_Sieve w/ externally established sockets * Fixed Bug #7197 getScript() truncates long scripts * Added PHPUnit2 regression test script";}i:18;a:5:{s:4:"date";s:10:"2006-02-09";s:7:"version";a:2:{s:7:"release";s:5:"1.1.2";s:3:"api";s:5:"1.1.2";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:3:"BSD";}s:5:"notes";s:285:"* Fixed Request #4053 Added STARTTLS support for PHP 5.1 and above * Fixed Bug #3519 Net_Sieve w/ externally established sockets * Fixed Bug #4794 drops protocol prefix, e.g. "ssl://" in referrals * Fixed STARTTLS detection * Allow $options[] to be passed to Net_Socket";}i:19;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.1.1";s:3:"api";s:5:"1.1.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2005-02-02";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:3:"BSD";}s:5:"notes";s:53:"* Fixed Bug #3242 cyrus murder referrals not followed";}i:20;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.1.0";s:3:"api";s:5:"1.1.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2004-12-18";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:3:"BSD";}s:5:"notes";s:61:"* Fixed Bug #2728 Linebreaks not being read using getScript()";}i:21;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.0.1";s:3:"api";s:5:"1.0.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2004-03-13";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:3:"BSD";}s:5:"notes";s:17:"* Fixed BUG #1006";}i:22;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"1.0.0";s:3:"api";s:5:"1.0.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2004-03-10";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:3:"BSD";}s:5:"notes";s:108:"* Fixed DIGEST-MD5 sasl version handling (sasl v1.xx responses are diferent than v2.xx) * Fixed LOGIN Method";}i:23;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"0.9.1";s:3:"api";s:5:"0.9.1";}s:9:"stability";a:2:{s:7:"release";s:4:"beta";s:3:"api";s:4:"beta";}s:4:"date";s:10:"2004-02-29";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:3:"BSD";}s:5:"notes";s:1138:"* There is an issue whith the DIGEST-MD5 method. in one installation it does not work but in my server it works perfect! please send me debug info to solve the problem if it affects you or disable DIGEST-MD5 * some optimizations to the code * added haveSpace() to check if the server has space to store the script. Use with care HAVESPACE seems to be broken in cyrus 2.0.16 * added hasExtension() * added getExtensions() * added referral support and automatic following of them. (it also handles the following of multireferrals). * removed _getResponse replaced by _doCmd. (thanks to Etienne Goyer for this) * added supportsAuthMech() * if installed automatically uses Auth_SASL * added CRAM-MD5 auth Method * added DIGEST-MD5 auth Method * added getAuthMechs() returns an array containing all the auth methods the server supports * added hasAuthMech() to check if the server has a particular auth method * _connect --> connect: now is a public method (without breaking BC) * _login --> login: now is a public method (without breaking BC) * fix typo cmdAuthenticate() ---> _cmdAuthenticate() * _doCmd() now parses string responses also.";}i:24;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"0.9.0";s:3:"api";s:5:"0.9.0";}s:9:"stability";a:2:{s:7:"release";s:4:"beta";s:3:"api";s:4:"beta";}s:4:"date";s:10:"2004-01-31";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:3:"BSD";}s:5:"notes";s:177:"* Added setDebug() method and debugging capabilities * added disconnect() method * added sample file test_sieve.php * fixed bug #591 * automagically selects the best auth method";}i:25;a:5:{s:7:"version";a:2:{s:7:"release";s:5:"0.8.1";s:3:"api";s:5:"0.8.1";}s:9:"stability";a:2:{s:7:"release";s:4:"beta";s:3:"api";s:4:"beta";}s:4:"date";s:10:"2002-07-27";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:3:"BSD";}s:5:"notes";s:15:"Initial release";}i:26;a:5:{s:7:"version";a:2:{s:7:"release";s:3:"0.8";s:3:"api";s:3:"0.8";}s:9:"stability";a:2:{s:7:"release";s:4:"beta";s:3:"api";s:4:"beta";}s:4:"date";s:10:"2002-05-10";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:26:"http://www.php.net/license";}s:8:"_content";s:3:"PHP";}s:5:"notes";s:15:"Initial release";}i:27;a:5:{s:4:"date";s:10:"2018-09-09";s:7:"version";a:2:{s:7:"release";s:5:"1.4.4";s:3:"api";s:5:"1.4.2";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:50:"http://www.opensource.org/licenses/bsd-license.php";}s:8:"_content";s:3:"BSD";}s:5:"notes";s:70:"* Fix PHP 7.3: Declaration of case-insensitive constants is deprecated";}}}s:8:"filelist";a:4:{s:21:"tests/largescript.siv";a:5:{s:14:"baseinstalldir";s:3:"Net";s:6:"md5sum";s:32:"ef8cd688674fba85cc067e06c221e43b";s:4:"name";s:21:"tests/largescript.siv";s:4:"role";s:4:"test";s:12:"installed_as";s:66:"/opt/alt/php56/usr/share/pear/test/Net_Sieve/tests/largescript.siv";}s:21:"tests/config.php.dist";a:5:{s:14:"baseinstalldir";s:3:"Net";s:6:"md5sum";s:32:"7d772fe47ee45bdb521dd581281f38c3";s:4:"name";s:21:"tests/config.php.dist";s:4:"role";s:4:"test";s:12:"installed_as";s:66:"/opt/alt/php56/usr/share/pear/test/Net_Sieve/tests/config.php.dist";}s:19:"tests/SieveTest.php";a:5:{s:14:"baseinstalldir";s:3:"Net";s:6:"md5sum";s:32:"6050fac5e66a4a6bbed7913f826974ed";s:4:"name";s:19:"tests/SieveTest.php";s:4:"role";s:4:"test";s:12:"installed_as";s:64:"/opt/alt/php56/usr/share/pear/test/Net_Sieve/tests/SieveTest.php";}s:9:"Sieve.php";a:5:{s:14:"baseinstalldir";s:3:"Net";s:6:"md5sum";s:32:"2a45a03c042351957f3435929a17bca3";s:4:"name";s:9:"Sieve.php";s:4:"role";s:3:"php";s:12:"installed_as";s:43:"/opt/alt/php56/usr/share/pear/Net/Sieve.php";}}s:12:"_lastversion";N;s:7:"dirtree";a:3:{s:50:"/opt/alt/php56/usr/share/pear/test/Net_Sieve/tests";b:1;s:44:"/opt/alt/php56/usr/share/pear/test/Net_Sieve";b:1;s:33:"/opt/alt/php56/usr/share/pear/Net";b:1;}s:3:"old";a:7:{s:7:"version";s:5:"1.4.5";s:12:"release_date";s:10:"2021-04-24";s:13:"release_state";s:6:"stable";s:15:"release_license";s:3:"BSD";s:13:"release_notes";s:38:"* Support XOAUTH2 authorization method";s:12:"release_deps";a:4:{i:0;a:4:{s:4:"type";s:3:"php";s:3:"rel";s:2:"ge";s:7:"version";s:5:"5.0.0";s:8:"optional";s:2:"no";}i:1;a:6:{s:4:"type";s:3:"pkg";s:7:"channel";s:12:"pear.php.net";s:4:"name";s:4:"PEAR";s:3:"rel";s:2:"ge";s:7:"version";s:7:"1.4.0b1";s:8:"optional";s:2:"no";}i:2;a:6:{s:4:"type";s:3:"pkg";s:7:"channel";s:12:"pear.php.net";s:4:"name";s:10:"Net_Socket";s:3:"rel";s:2:"ge";s:7:"version";s:3:"1.0";s:8:"optional";s:2:"no";}i:3;a:6:{s:4:"type";s:3:"pkg";s:7:"channel";s:12:"pear.php.net";s:4:"name";s:9:"Auth_SASL";s:3:"rel";s:2:"ge";s:7:"version";s:3:"1.0";s:8:"optional";s:3:"yes";}}s:11:"maintainers";a:5:{i:0;a:5:{s:4:"name";s:19:"Aleksander Machniak";s:5:"email";s:12:"alec@alec.pl";s:6:"active";s:3:"yes";s:6:"handle";s:4:"alec";s:4:"role";s:4:"lead";}i:1;a:5:{s:4:"name";s:13:"Jan Schneider";s:5:"email";s:13:"jan@horde.org";s:6:"active";s:2:"no";s:6:"handle";s:6:"yunosh";s:4:"role";s:4:"lead";}i:2;a:5:{s:4:"name";s:13:"Richard Heyes";s:5:"email";s:15:"richard@php.net";s:6:"active";s:2:"no";s:6:"handle";s:7:"richard";s:4:"role";s:4:"lead";}i:3;a:5:{s:4:"name";s:21:"Damian Fernandez Sosa";s:5:"email";s:20:"damlists@cnba.uba.ar";s:6:"active";s:2:"no";s:6:"handle";s:6:"damian";s:4:"role";s:4:"lead";}i:4;a:5:{s:4:"name";s:12:"Anish Mistry";s:5:"email";s:26:"amistry@am-productions.biz";s:6:"active";s:2:"no";s:6:"handle";s:7:"amistry";s:4:"role";s:4:"lead";}}}s:10:"xsdversion";s:3:"2.0";s:13:"_lastmodified";i:1669631553;}PK�����u]b@D�D���.registry/pear.regnu�[��������a:24:{s:7:"attribs";a:6:{s:15:"packagerversion";s:7:"1.10.13";s:7:"version";s:3:"2.0";s:5:"xmlns";s:35:"http://pear.php.net/dtd/package-2.0";s:11:"xmlns:tasks";s:33:"http://pear.php.net/dtd/tasks-1.0";s:9:"xmlns:xsi";s:41:"http://www.w3.org/2001/XMLSchema-instance";s:18:"xsi:schemaLocation";s:147:"http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd";}s:4:"name";s:4:"PEAR";s:7:"channel";s:12:"pear.php.net";s:7:"summary";s:16:"PEAR Base System";s:11:"description";s:1100:"The PEAR package contains: * the PEAR installer, for creating, distributing and installing packages * the PEAR_Exception PHP5 error handling mechanism * the PEAR_ErrorStack advanced error handling mechanism * the PEAR_Error error handling mechanism * the OS_Guess class for retrieving info about the OS where PHP is running on * the System class for quick handling of common operations with files and directories * the PEAR base class Features in a nutshell: * full support for channels * pre-download dependency validation * new package.xml 2.0 format allows tremendous flexibility while maintaining BC * support for optional dependency groups and limited support for sub-packaging * robust dependency support * full dependency validation on uninstall * remote install for hosts with only ftp access - no more problems with restricted host installation * full support for mirroring * support for bundling several packages into a single tarball * support for static dependencies on a url-based package * support for custom file roles and installation tasks";s:4:"lead";a:7:{i:0;a:4:{s:4:"name";s:11:"Greg Beaver";s:4:"user";s:6:"cellog";s:5:"email";s:14:"cellog@php.net";s:6:"active";s:2:"no";}i:1;a:4:{s:4:"name";s:17:"Pierre-Alain Joye";s:4:"user";s:6:"pajoye";s:5:"email";s:14:"pierre@php.net";s:6:"active";s:2:"no";}i:2;a:4:{s:4:"name";s:11:"Stig Bakken";s:4:"user";s:3:"ssb";s:5:"email";s:12:"stig@php.net";s:6:"active";s:2:"no";}i:3;a:4:{s:4:"name";s:13:"Tomas V.V.Cox";s:4:"user";s:3:"cox";s:5:"email";s:15:"cox@idecnet.com";s:6:"active";s:2:"no";}i:4;a:4:{s:4:"name";s:13:"Helgi Thormar";s:4:"user";s:5:"dufuz";s:5:"email";s:13:"dufuz@php.net";s:6:"active";s:2:"no";}i:5;a:4:{s:4:"name";s:16:"Christian Weiske";s:4:"user";s:7:"cweiske";s:5:"email";s:15:"cweiske@php.net";s:6:"active";s:2:"no";}i:6;a:4:{s:4:"name";s:13:"Chuck Burgess";s:4:"user";s:7:"ashnazg";s:5:"email";s:15:"ashnazg@php.net";s:6:"active";s:3:"yes";}}s:9:"developer";a:4:{s:4:"name";s:9:"Tias Guns";s:4:"user";s:4:"tias";s:5:"email";s:12:"tias@php.net";s:6:"active";s:2:"no";}s:6:"helper";a:3:{i:0;a:4:{s:4:"name";s:11:"Tim Jackson";s:4:"user";s:4:"timj";s:5:"email";s:12:"timj@php.net";s:6:"active";s:2:"no";}i:1;a:4:{s:4:"name";s:15:"Bertrand Gugger";s:4:"user";s:5:"toggg";s:5:"email";s:13:"toggg@php.net";s:6:"active";s:2:"no";}i:2;a:4:{s:4:"name";s:13:"Martin Jansen";s:4:"user";s:2:"mj";s:5:"email";s:10:"mj@php.net";s:6:"active";s:2:"no";}}s:4:"date";s:10:"2024-11-24";s:4:"time";s:8:"22:09:42";s:7:"version";a:2:{s:7:"release";s:7:"1.10.16";s:3:"api";s:6:"1.10.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:46:"http://opensource.org/licenses/bsd-license.php";}s:8:"_content";s:15:"New BSD License";}s:5:"notes";s:164:"* PR #141: Fix bug #27796: "Array to string" conversion warnings on installs/other actions * PR #145: Never reference E_STRICT on PHP 8.4+ * PR #147: Fix tests 8.1+";s:8:"contents";a:1:{s:3:"dir";a:2:{s:7:"attribs";a:1:{s:4:"name";s:1:"/";}s:4:"file";a:105:{i:0;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"c0482b234f269360953c87472b5cf746";s:4:"name";s:12:"OS/Guess.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:1;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"3b371e9c6b4d667abb8be01f2788dcf9";s:4:"name";s:27:"PEAR/ChannelFile/Parser.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:2;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"8fd87e64002e11fd86eb2f3fbfee6599";s:4:"name";s:21:"PEAR/Command/Auth.xml";s:4:"role";s:3:"php";}}i:3;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"65b6b36c4cc53f2836ad09b070829877";s:4:"name";s:21:"PEAR/Command/Auth.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:4;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"ce6bb5b6fdc02e0f50e7676403fd84a4";s:4:"name";s:22:"PEAR/Command/Build.xml";s:4:"role";s:3:"php";}}i:5;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"e19325f59c4013694a4a06b61e7ac3be";s:4:"name";s:22:"PEAR/Command/Build.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:6;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"6d5aab4d4308c3005b5f584c7783a031";s:4:"name";s:25:"PEAR/Command/Channels.xml";s:4:"role";s:3:"php";}}i:7;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"56b3b36834a751f6e7b86dcba6cefe2f";s:4:"name";s:25:"PEAR/Command/Channels.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:8;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"aae7cc03e9b7fe7c4f504b970dca5411";s:4:"name";s:23:"PEAR/Command/Common.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:9;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"91f189cb9423b5e87ee0abc5ea1a2be3";s:4:"name";s:23:"PEAR/Command/Config.xml";s:4:"role";s:3:"php";}}i:10;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"3c5d633b0e8d4e39e9bfb286f51130a5";s:4:"name";s:23:"PEAR/Command/Config.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:11;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"24d05213cae7faa3880bbb5e40998867";s:4:"name";s:24:"PEAR/Command/Install.xml";s:4:"role";s:3:"php";}}i:12;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"3dab53d092878709aa16f73143600107";s:4:"name";s:24:"PEAR/Command/Install.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:13;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"5cb62a04c0a268f4edd64a49a3895c92";s:4:"name";s:23:"PEAR/Command/Mirror.xml";s:4:"role";s:3:"php";}}i:14;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"2f5798bb62453d8d1bffa3d050584232";s:4:"name";s:23:"PEAR/Command/Mirror.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:15;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"9367dcd7e4dbdde423f9c4c7d3f3a919";s:4:"name";s:24:"PEAR/Command/Package.xml";s:4:"role";s:3:"php";}}i:16;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"57521ff1e89bcd23a853134f30836990";s:4:"name";s:24:"PEAR/Command/Package.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:2:{i:0;a:1:{s:7:"attribs";a:3:{s:4:"from";s:10:"@DATA-DIR@";s:2:"to";s:8:"data_dir";s:4:"type";s:11:"pear-config";}}i:1;a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}}i:17;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"28dc842ea725d8787b9f9c3dbca5aa22";s:4:"name";s:23:"PEAR/Command/Pickle.xml";s:4:"role";s:3:"php";}}i:18;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"4025dd6411a73b19a5c19b3300060625";s:4:"name";s:23:"PEAR/Command/Pickle.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:19;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"49b046cfc14747f0365e02e9c3f0e6dc";s:4:"name";s:25:"PEAR/Command/Registry.xml";s:4:"role";s:3:"php";}}i:20;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"9f2ea65794243f0b7287e8883f2ab60e";s:4:"name";s:25:"PEAR/Command/Registry.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:21;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"29c02e823879b4e3e291f6b36fb339f1";s:4:"name";s:23:"PEAR/Command/Remote.xml";s:4:"role";s:3:"php";}}i:22;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"42c51cbb21c103fe0288e5c16871f401";s:4:"name";s:23:"PEAR/Command/Remote.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:23;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"a50c32015005e0761cc3b04679b29ed0";s:4:"name";s:21:"PEAR/Command/Test.xml";s:4:"role";s:3:"php";}}i:24;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"fbb0098fcda7fa29adaa0714a325caea";s:4:"name";s:21:"PEAR/Command/Test.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:25;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"9229a9711a893a18298e473212689ab4";s:4:"name";s:27:"PEAR/Downloader/Package.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:10:"@PEAR-VER@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:26;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"5379be9492842c3af98241c6e226d285";s:4:"name";s:21:"PEAR/Frontend/CLI.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:27;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"adae220f10a82e5f78b8689a57387753";s:4:"name";s:30:"PEAR/Installer/Role/Common.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:28;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"d8c62e6275e3aaa7784290912406092c";s:4:"name";s:27:"PEAR/Installer/Role/Cfg.xml";s:4:"role";s:3:"php";}}i:29;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"d89d39dcc1c55fb4464f447ce4f84eed";s:4:"name";s:27:"PEAR/Installer/Role/Cfg.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:30;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"89a4a2a286e842d45a98974f40a0565c";s:4:"name";s:28:"PEAR/Installer/Role/Data.xml";s:4:"role";s:3:"php";}}i:31;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"89754e8d153937f3dd3266fd8897d965";s:4:"name";s:28:"PEAR/Installer/Role/Data.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:32;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"b1ce0fe105251c3b75209d6518ee69ac";s:4:"name";s:27:"PEAR/Installer/Role/Doc.xml";s:4:"role";s:3:"php";}}i:33;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"849c557b355f78890ef47fcfd12073ab";s:4:"name";s:27:"PEAR/Installer/Role/Doc.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:34;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"af71c0ad42d16a323afe24a4f884ef15";s:4:"name";s:27:"PEAR/Installer/Role/Ext.xml";s:4:"role";s:3:"php";}}i:35;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"7d3dc799576b3e3d74d187de118cc3e4";s:4:"name";s:27:"PEAR/Installer/Role/Ext.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:36;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"da6743f1e45cce72ea13aef5cdb14867";s:4:"name";s:27:"PEAR/Installer/Role/Man.xml";s:4:"role";s:3:"php";}}i:37;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"2509a027ae42c4b96aa49557325a0ec4";s:4:"name";s:27:"PEAR/Installer/Role/Man.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:38;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"ef88f0321d3e481c2130c95122cf76d8";s:4:"name";s:27:"PEAR/Installer/Role/Php.xml";s:4:"role";s:3:"php";}}i:39;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"d7547896ec403dba2eed9825ed86ea64";s:4:"name";s:27:"PEAR/Installer/Role/Php.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:40;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"746461dc3b48af6d24094cb0211608f2";s:4:"name";s:30:"PEAR/Installer/Role/Script.xml";s:4:"role";s:3:"php";}}i:41;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"325c60df7f78be127741621561758f46";s:4:"name";s:30:"PEAR/Installer/Role/Script.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:42;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"e147d63f168ea156fc2be38caaa63804";s:4:"name";s:27:"PEAR/Installer/Role/Src.xml";s:4:"role";s:3:"php";}}i:43;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"464722cee0665ebc75757f76532f0ab2";s:4:"name";s:27:"PEAR/Installer/Role/Src.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:44;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"a24b596ec987aa5688fc19e8ed4e97ea";s:4:"name";s:28:"PEAR/Installer/Role/Test.xml";s:4:"role";s:3:"php";}}i:45;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"a04eb2f4881ec6e6a13ae78f6a43e3cd";s:4:"name";s:28:"PEAR/Installer/Role/Test.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:46;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"7641e71c5785bb33a4261ebe25ed0fd7";s:4:"name";s:27:"PEAR/Installer/Role/Www.xml";s:4:"role";s:3:"php";}}i:47;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"62699034e3186c2d68a6bb56a6cc23eb";s:4:"name";s:27:"PEAR/Installer/Role/Www.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:48;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"e95f2d850fce183e221912b2c2056d04";s:4:"name";s:23:"PEAR/Installer/Role.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:49;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"cfa08685115d5e2d7635225d73a91f39";s:4:"name";s:33:"PEAR/PackageFile/Generator/v1.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:10:"@PEAR-VER@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:50;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"8d264031153993866828e82129e389ab";s:4:"name";s:33:"PEAR/PackageFile/Generator/v2.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:10:"@PEAR-VER@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:51;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"a2206e0e32ad2ba2f4e2a0c1797f295c";s:4:"name";s:30:"PEAR/PackageFile/Parser/v1.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:52;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"3857f4b60878d64551a7cdae783437f7";s:4:"name";s:30:"PEAR/PackageFile/Parser/v2.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:53;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"a253999b2109460badc3c71ad2c069e7";s:4:"name";s:26:"PEAR/PackageFile/v2/rw.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:54;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"44dafa313204f68b5fb54b9f61a86d0c";s:4:"name";s:33:"PEAR/PackageFile/v2/Validator.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:55;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"cc1ea307bb79c0cbcff4a90a4656e96e";s:4:"name";s:23:"PEAR/PackageFile/v1.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:56;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"9e6012d4ef9cb8e12e2ccadcbdcf3d24";s:4:"name";s:23:"PEAR/PackageFile/v2.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:57;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"ce77cc6593d8d4eda5ff8620ff09d6ec";s:4:"name";s:16:"PEAR/REST/10.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:58;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"bdbd1f2e8afa2cddddecf2687579d316";s:4:"name";s:16:"PEAR/REST/11.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:59;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"11179085b6efb577d37f45cc25e42a35";s:4:"name";s:16:"PEAR/REST/13.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:60;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"0eb57da4993a3cfed69fe8135f10b05a";s:4:"name";s:34:"PEAR/Task/Postinstallscript/rw.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:61;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"46c1bdb9a7af8628643e639ec1c3bc58";s:4:"name";s:24:"PEAR/Task/Replace/rw.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:62;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"50e20dbde7e51bb5e11545c56482b68a";s:4:"name";s:24:"PEAR/Task/Unixeol/rw.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:63;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"340be01552844adb50f6e0fa37aa3ffe";s:4:"name";s:27:"PEAR/Task/Windowseol/rw.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:64;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"ec7f8db335ad3b5a25d78682745185d1";s:4:"name";s:20:"PEAR/Task/Common.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:65;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"86f240c600447fdb86bd38bd32c66c02";s:4:"name";s:31:"PEAR/Task/Postinstallscript.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:66;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"c993cdedc64084a1c4b735baec048d50";s:4:"name";s:21:"PEAR/Task/Replace.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:67;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"76c4ca15858c005cda208a9da1f5eb2d";s:4:"name";s:21:"PEAR/Task/Unixeol.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:68;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"d790eb3aa5ba22a33e42cb7c5f99fb25";s:4:"name";s:24:"PEAR/Task/Windowseol.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:69;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"b3c83ca826a4825ca2db726ed7d4b245";s:4:"name";s:23:"PEAR/Validator/PECL.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:70;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"7d89f25a54d100c2afd562fb3bd7c308";s:4:"name";s:16:"PEAR/Builder.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:10:"@PEAR-VER@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:71;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"edcd484ecfd400875df90ee480c5384d";s:4:"name";s:20:"PEAR/ChannelFile.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:72;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"a5d56f9d15ff6d22c12f7db851f281e8";s:4:"name";s:16:"PEAR/Command.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:73;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"0af44a13df74291ac2f46949d2035e0e";s:4:"name";s:15:"PEAR/Common.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:74;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"64d0f7b2737e5f182d0ab98bc77930d2";s:4:"name";s:15:"PEAR/Config.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:75;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"7e8dfae09802be7f2e6170062bb80cbd";s:4:"name";s:21:"PEAR/DependencyDB.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:76;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"76fdabdee883fd16b986332552b9e3dc";s:4:"name";s:20:"PEAR/Dependency2.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:10:"@PEAR-VER@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:77;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"2ccb7bb2d00eae201ee7ae1eef49ad8a";s:4:"name";s:19:"PEAR/Downloader.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:78;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"ea807632b63d2e0acd6924db23aaa0eb";s:4:"name";s:19:"PEAR/ErrorStack.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:79;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"544ed48cab9407a936d058d09e773e22";s:4:"name";s:18:"PEAR/Exception.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:80;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"31c0b91767550adf77f1c9bea92a0559";s:4:"name";s:17:"PEAR/Frontend.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:81;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"b8b85e42b840676ad3ae1c15e55b005b";s:4:"name";s:18:"PEAR/Installer.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:82;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"2929765413405abf63574c8a544e4a04";s:4:"name";s:20:"PEAR/PackageFile.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:10:"@PEAR-VER@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:83;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"ad25a29d464b62cbaaa3ca96e622526c";s:4:"name";s:17:"PEAR/Packager.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:84;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"ef9d00adaeccff7516f08170096026d3";s:4:"name";s:14:"PEAR/Proxy.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:85;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"ae8c1dcfddb6a2717e09239bb1430dc7";s:4:"name";s:17:"PEAR/Registry.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:86;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"389d1bad72267d3ed770abf0662d8086";s:4:"name";s:13:"PEAR/REST.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:87;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"df0d7022e22fd78ecd82080ff4f108d5";s:4:"name";s:16:"PEAR/RunTest.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:88;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"3711c281e0234203ec7879f53bc766ab";s:4:"name";s:17:"PEAR/Validate.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:89;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"da9510087eddd489945dde07260256ee";s:4:"name";s:18:"PEAR/XMLParser.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:90;a:3:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"d888d06143e3cac0dae78bbb2e761366";s:4:"name";s:16:"scripts/pear.bat";s:4:"role";s:6:"script";}s:13:"tasks:replace";a:3:{i:0;a:1:{s:7:"attribs";a:3:{s:4:"from";s:9:"@bin_dir@";s:2:"to";s:7:"bin_dir";s:4:"type";s:11:"pear-config";}}i:1;a:1:{s:7:"attribs";a:3:{s:4:"from";s:9:"@php_bin@";s:2:"to";s:7:"php_bin";s:4:"type";s:11:"pear-config";}}i:2;a:1:{s:7:"attribs";a:3:{s:4:"from";s:14:"@include_path@";s:2:"to";s:7:"php_dir";s:4:"type";s:11:"pear-config";}}}s:16:"tasks:windowseol";s:0:"";}i:91;a:3:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"17d7d08ce2c6c476eeaae4763f69efcc";s:4:"name";s:19:"scripts/peardev.bat";s:4:"role";s:6:"script";}s:13:"tasks:replace";a:3:{i:0;a:1:{s:7:"attribs";a:3:{s:4:"from";s:9:"@bin_dir@";s:2:"to";s:7:"bin_dir";s:4:"type";s:11:"pear-config";}}i:1;a:1:{s:7:"attribs";a:3:{s:4:"from";s:9:"@php_bin@";s:2:"to";s:7:"php_bin";s:4:"type";s:11:"pear-config";}}i:2;a:1:{s:7:"attribs";a:3:{s:4:"from";s:14:"@include_path@";s:2:"to";s:7:"php_dir";s:4:"type";s:11:"pear-config";}}}s:16:"tasks:windowseol";s:0:"";}i:92;a:3:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"1c5819d67da59739e6298d6094c58f7b";s:4:"name";s:16:"scripts/pecl.bat";s:4:"role";s:6:"script";}s:13:"tasks:replace";a:3:{i:0;a:1:{s:7:"attribs";a:3:{s:4:"from";s:9:"@bin_dir@";s:2:"to";s:7:"bin_dir";s:4:"type";s:11:"pear-config";}}i:1;a:1:{s:7:"attribs";a:3:{s:4:"from";s:9:"@php_bin@";s:2:"to";s:7:"php_bin";s:4:"type";s:11:"pear-config";}}i:2;a:1:{s:7:"attribs";a:3:{s:4:"from";s:14:"@include_path@";s:2:"to";s:7:"php_dir";s:4:"type";s:11:"pear-config";}}}s:16:"tasks:windowseol";s:0:"";}i:93;a:3:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"8ac139504e80bede470aef6d405100b6";s:4:"name";s:15:"scripts/pear.sh";s:4:"role";s:6:"script";}s:13:"tasks:replace";a:4:{i:0;a:1:{s:7:"attribs";a:3:{s:4:"from";s:9:"@php_bin@";s:2:"to";s:7:"php_bin";s:4:"type";s:11:"pear-config";}}i:1;a:1:{s:7:"attribs";a:3:{s:4:"from";s:9:"@php_dir@";s:2:"to";s:7:"php_dir";s:4:"type";s:11:"pear-config";}}i:2;a:1:{s:7:"attribs";a:3:{s:4:"from";s:14:"@pear_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}i:3;a:1:{s:7:"attribs";a:3:{s:4:"from";s:14:"@include_path@";s:2:"to";s:7:"php_dir";s:4:"type";s:11:"pear-config";}}}s:13:"tasks:unixeol";s:0:"";}i:94;a:3:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"08ea03525b4ba914dfd9ec69c4238cf4";s:4:"name";s:18:"scripts/peardev.sh";s:4:"role";s:6:"script";}s:13:"tasks:replace";a:4:{i:0;a:1:{s:7:"attribs";a:3:{s:4:"from";s:9:"@php_bin@";s:2:"to";s:7:"php_bin";s:4:"type";s:11:"pear-config";}}i:1;a:1:{s:7:"attribs";a:3:{s:4:"from";s:9:"@php_dir@";s:2:"to";s:7:"php_dir";s:4:"type";s:11:"pear-config";}}i:2;a:1:{s:7:"attribs";a:3:{s:4:"from";s:14:"@pear_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}i:3;a:1:{s:7:"attribs";a:3:{s:4:"from";s:14:"@include_path@";s:2:"to";s:7:"php_dir";s:4:"type";s:11:"pear-config";}}}s:13:"tasks:unixeol";s:0:"";}i:95;a:3:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"bde09b17fa816d58bb136375a13119c3";s:4:"name";s:15:"scripts/pecl.sh";s:4:"role";s:6:"script";}s:13:"tasks:replace";a:4:{i:0;a:1:{s:7:"attribs";a:3:{s:4:"from";s:9:"@php_bin@";s:2:"to";s:7:"php_bin";s:4:"type";s:11:"pear-config";}}i:1;a:1:{s:7:"attribs";a:3:{s:4:"from";s:9:"@php_dir@";s:2:"to";s:7:"php_dir";s:4:"type";s:11:"pear-config";}}i:2;a:1:{s:7:"attribs";a:3:{s:4:"from";s:14:"@pear_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}i:3;a:1:{s:7:"attribs";a:3:{s:4:"from";s:14:"@include_path@";s:2:"to";s:7:"php_dir";s:4:"type";s:11:"pear-config";}}}s:13:"tasks:unixeol";s:0:"";}i:96;a:2:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"9b5d5e5bd017c50df00c6b34ef32652e";s:4:"name";s:19:"scripts/pearcmd.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:4:{i:0;a:1:{s:7:"attribs";a:3:{s:4:"from";s:9:"@php_bin@";s:2:"to";s:7:"php_bin";s:4:"type";s:11:"pear-config";}}i:1;a:1:{s:7:"attribs";a:3:{s:4:"from";s:9:"@php_dir@";s:2:"to";s:7:"php_dir";s:4:"type";s:11:"pear-config";}}i:2;a:1:{s:7:"attribs";a:3:{s:4:"from";s:14:"@pear_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}i:3;a:1:{s:7:"attribs";a:3:{s:4:"from";s:14:"@include_path@";s:2:"to";s:7:"php_dir";s:4:"type";s:11:"pear-config";}}}}i:97;a:2:{s:7:"attribs";a:4:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"48867dfbb41f2532d034f56a79565893";s:4:"name";s:19:"scripts/peclcmd.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:4:{i:0;a:1:{s:7:"attribs";a:3:{s:4:"from";s:9:"@php_bin@";s:2:"to";s:7:"php_bin";s:4:"type";s:11:"pear-config";}}i:1;a:1:{s:7:"attribs";a:3:{s:4:"from";s:9:"@php_dir@";s:2:"to";s:7:"php_dir";s:4:"type";s:11:"pear-config";}}i:2;a:1:{s:7:"attribs";a:3:{s:4:"from";s:14:"@pear_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}i:3;a:1:{s:7:"attribs";a:3:{s:4:"from";s:14:"@include_path@";s:2:"to";s:7:"php_dir";s:4:"type";s:11:"pear-config";}}}}i:98;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"45b44486d8090de17b2a8b4211fab247";s:4:"name";s:7:"LICENSE";s:4:"role";s:3:"doc";}}i:99;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"eaac3d33068c6e67573ed44155b149ae";s:4:"name";s:7:"INSTALL";s:4:"role";s:3:"doc";}}i:100;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"69341ea97af9c88956568f8e7e41d4c6";s:4:"name";s:11:"package.dtd";s:4:"role";s:4:"data";}}i:101;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"47aeb7eaff6438beb60bc42bc0e6c658";s:4:"name";s:8:"PEAR.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:102;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"cd10521cc4054923a3d2b6e15b4df493";s:4:"name";s:10:"README.rst";s:4:"role";s:3:"doc";}}i:103;a:2:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"ba9e5c5a567e51b440808a8ed53cd76d";s:4:"name";s:10:"System.php";s:4:"role";s:3:"php";}s:13:"tasks:replace";a:1:{s:7:"attribs";a:3:{s:4:"from";s:17:"@package_version@";s:2:"to";s:7:"version";s:4:"type";s:12:"package-info";}}}i:104;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"acd010e3bc43c0f72df584acde7b9158";s:4:"name";s:13:"template.spec";s:4:"role";s:4:"data";}}}}}s:12:"dependencies";a:2:{s:8:"required";a:4:{s:3:"php";a:1:{s:3:"min";s:5:"5.4.0";}s:13:"pearinstaller";a:1:{s:3:"min";s:6:"1.10.1";}s:7:"package";a:4:{i:0;a:4:{s:4:"name";s:11:"Archive_Tar";s:7:"channel";s:12:"pear.php.net";s:3:"min";s:5:"1.4.9";s:11:"recommended";s:5:"1.4.4";}i:1;a:4:{s:4:"name";s:16:"Structures_Graph";s:7:"channel";s:12:"pear.php.net";s:3:"min";s:5:"1.1.0";s:11:"recommended";s:5:"1.1.1";}i:2;a:4:{s:4:"name";s:14:"Console_Getopt";s:7:"channel";s:12:"pear.php.net";s:3:"min";s:5:"1.4.1";s:11:"recommended";s:5:"1.4.3";}i:3;a:4:{s:4:"name";s:8:"XML_Util";s:7:"channel";s:12:"pear.php.net";s:3:"min";s:5:"1.4.0";s:11:"recommended";s:5:"1.4.5";}}s:9:"extension";a:2:{i:0;a:1:{s:4:"name";s:3:"xml";}i:1;a:1:{s:4:"name";s:4:"pcre";}}}s:5:"group";a:3:{i:0;a:2:{s:7:"attribs";a:2:{s:4:"hint";s:26:"PEAR's web-based installer";s:4:"name";s:12:"webinstaller";}s:7:"package";a:3:{s:4:"name";s:17:"PEAR_Frontend_Web";s:7:"channel";s:12:"pear.php.net";s:3:"min";s:5:"0.5.1";}}i:1;a:2:{s:7:"attribs";a:2:{s:4:"hint";s:30:"PEAR's PHP-GTK-based installer";s:4:"name";s:12:"gtkinstaller";}s:7:"package";a:3:{s:4:"name";s:17:"PEAR_Frontend_Gtk";s:7:"channel";s:12:"pear.php.net";s:3:"min";s:5:"0.4.0";}}i:2;a:2:{s:7:"attribs";a:2:{s:4:"hint";s:31:"PEAR's PHP-GTK2-based installer";s:4:"name";s:13:"gtk2installer";}s:7:"package";a:2:{s:4:"name";s:18:"PEAR_Frontend_Gtk2";s:7:"channel";s:12:"pear.php.net";}}}}s:10:"phprelease";a:2:{i:0;a:2:{s:17:"installconditions";a:1:{s:2:"os";a:1:{s:4:"name";s:7:"windows";}}s:8:"filelist";a:2:{s:7:"install";a:5:{i:0;a:1:{s:7:"attribs";a:2:{s:2:"as";s:8:"pear.bat";s:4:"name";s:16:"scripts/pear.bat";}}i:1;a:1:{s:7:"attribs";a:2:{s:2:"as";s:11:"peardev.bat";s:4:"name";s:19:"scripts/peardev.bat";}}i:2;a:1:{s:7:"attribs";a:2:{s:2:"as";s:8:"pecl.bat";s:4:"name";s:16:"scripts/pecl.bat";}}i:3;a:1:{s:7:"attribs";a:2:{s:2:"as";s:11:"pearcmd.php";s:4:"name";s:19:"scripts/pearcmd.php";}}i:4;a:1:{s:7:"attribs";a:2:{s:2:"as";s:11:"peclcmd.php";s:4:"name";s:19:"scripts/peclcmd.php";}}}s:6:"ignore";a:3:{i:0;a:1:{s:7:"attribs";a:1:{s:4:"name";s:18:"scripts/peardev.sh";}}i:1;a:1:{s:7:"attribs";a:1:{s:4:"name";s:15:"scripts/pear.sh";}}i:2;a:1:{s:7:"attribs";a:1:{s:4:"name";s:15:"scripts/pecl.sh";}}}}}i:1;a:1:{s:8:"filelist";a:2:{s:7:"install";a:5:{i:0;a:1:{s:7:"attribs";a:2:{s:2:"as";s:4:"pear";s:4:"name";s:15:"scripts/pear.sh";}}i:1;a:1:{s:7:"attribs";a:2:{s:2:"as";s:7:"peardev";s:4:"name";s:18:"scripts/peardev.sh";}}i:2;a:1:{s:7:"attribs";a:2:{s:2:"as";s:4:"pecl";s:4:"name";s:15:"scripts/pecl.sh";}}i:3;a:1:{s:7:"attribs";a:2:{s:2:"as";s:11:"pearcmd.php";s:4:"name";s:19:"scripts/pearcmd.php";}}i:4;a:1:{s:7:"attribs";a:2:{s:2:"as";s:11:"peclcmd.php";s:4:"name";s:19:"scripts/peclcmd.php";}}}s:6:"ignore";a:3:{i:0;a:1:{s:7:"attribs";a:1:{s:4:"name";s:16:"scripts/pear.bat";}}i:1;a:1:{s:7:"attribs";a:1:{s:4:"name";s:19:"scripts/peardev.bat";}}i:2;a:1:{s:7:"attribs";a:1:{s:4:"name";s:16:"scripts/pecl.bat";}}}}}}s:9:"changelog";a:1:{s:7:"release";a:35:{i:0;a:5:{s:7:"version";a:2:{s:7:"release";s:11:"1.8.0alpha1";s:3:"api";s:5:"1.8.0";}s:9:"stability";a:2:{s:7:"release";s:5:"alpha";s:3:"api";s:6:"stable";}s:4:"date";s:10:"2009-03-09";s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:46:"http://opensource.org/licenses/bsd-license.php";}s:8:"_content";s:15:"New BSD License";}s:5:"notes";s:4876:"* Implement Request #10373: if pref_state=stable and installed package=beta, allow up to latest beta version [dufuz] * Implement Request #10581: login / logout should map to channel-login / channel-logout [dufuz] * Implement Request #10825: Only display the "invalid or missing package file"-error if it makes sense [dufuz] * Implement Request #11170: script to generate Command/[command].xml [dufuz] * Implement Request #11176: improve channel ... has updated its protocols message [dufuz] * Implement Request #12706: pear list -a hard to read [dufuz] * Implement Request #11353: upgrade-all and upgrade commands to upgrade within the same stability level [dufuz] * Implement Request #13015: Add https discovery for channel.xml [dufuz / initial patch by Martin Roos] * Implement Request #13927: install-pear.php should have option to set www_dir [timj] * Implement Request #14324: Make the pear install command behave similar to apt-get [dufuz] * Implement Request #14325: make pear upgrade with no params behave like pear upgrade-all [dufuz] - upgrade-all can be considered deprecated in favor of calling upgrade with no parameters to replicate better what other package managers are doing. upgrade-all will still work as intended. * Implement Request #14504: add a channel parameter support to the upgrade function [dufuz] - Options -c ezc and --channel=ezc got added to upgrade and upgrade-all to allow for channel specific upgrades * Implement Request #14556: install-pear-nozlib.phar should get download_dir config and other options [cweiske] * Implement Request #15566: Add doc.php.net as a default channel [dufuz / saltybeagle] * Fix PHP Bug #43857: --program-suffix not always reflected everywhere [cellog] * Fix PHP Bug #47323: strotime warnings in make install [dufuz] * Fix Bug #13908: pear info command and maintainers inactive not mentioned [dufuz] * Fix Bug #13926: install-pear.php does not set cfg_dir if -d option set with no -c option [timj] * Fix Bug #13943: tests fail when php.exe path contains spaces [dufuz / jorrit] * Fix Bug #13953: config-set/config-show with channel alias fail [cellog] * Fix Bug #13958: When a phpt tests exit() or die() xdebug coverage is not generated, patch by izi (David Jean Louis) [izi / dufuz] * Fix Bug #14041: Unpredictable unit test processing sequence [dufuz] * Fix Bug #14140: Strict warning not suppressed in the shutdown function [dufuz] * Fix Bug #14210: pear list -ia brings warnings [dufuz] * Fix Bug #14274: PEAR packager mangles package.xml encoding, then complains about it [dufuz] * Fix Bug #14287: cannot upgrade from stable to beta via -beta when config is set to stable [dufuz] * Fix Bug #14300: Package files themselves can not be served over https [dufuz / initial patch by Martin Roos] * Fix Bug #14437: openbasedir warning when loading config [dufuz] * Fix Bug #14558: PackageFile.php creates tmp directory outside configured temp_dir [cweiske] * Fix Bug #14947: downloadHttp() is missing Host part of the HTTP Request when using Proxy [ifeghali] * Fix Bug #14977: PEAR/Frontend.php doesn't require_once PEAR.php [dufuz] * Fix Bug #15750: Unreachable code in PEAR_Downloader [dufuz] * Fix Bug #15979: Package files incorrectly removed when splitting a package into multiple pkgs [dufuz] * Fix Bug #15914: pear upgrade installs different version if desired version not found [dufuz] NOTE! Functions that have been deprecated for 3+ years in PEAR_Common, please take a moment to migrate over to one of the alternatives that have ben provided: * PEAR_Common->downloadHttp (use PEAR_Downloader->downloadHttp instead) * PEAR_Common->infoFromTgzFile (use PEAR_PackageFile->fromTgzFile instead) * PEAR_Common->infoFromDescriptionFile (use PEAR_PackageFile->fromPackageFile instead) * PEAR_Common->infoFromString (use PEAR_PackageFile->fromXmlstring instead) * PEAR_Common->infoFromArray (use PEAR_PackageFile->fromAnyFile instead) * PEAR_Common->xmlFromInfo (use a PEAR_PackageFile_v* object's generator instead) * PEAR_Common->validatePackageInfo (use the validation of PEAR_PackageFile objects) * PEAR_Common->analyzeSourceCode (use a PEAR_PackageFile_v* object instead) * PEAR_Common->detectDependencies (use PEAR_Downloader_Package->detectDependencies instead) * PEAR_Common->buildProvidesArray (use PEAR_PackageFile_v1->_buildProvidesArray or PEAR_PackageFile_v2_Validator->_buildProvidesArray) PHP 4.4 and 5.1.6 are now the minimum PHP requirements, for brave souls pear upgrade -f PEAR will allow people with lower versions to upgrade to this release but no guarantees will be made that it will work properly. Support for XML RPC channels has been dropped - The only ones that used it (pear.php.net and pecl.php.net) have used the REST interface for years now. SOAP support also removed as it was only proof of concept. Move codebase from the PHP License to New BSD 2 clause license";}i:1;a:5:{s:4:"date";s:10:"2009-03-27";s:7:"version";a:2:{s:7:"release";s:8:"1.8.0RC1";s:3:"api";s:5:"1.8.0";}s:9:"stability";a:2:{s:7:"release";s:4:"beta";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:46:"http://opensource.org/licenses/bsd-license.php";}s:8:"_content";s:15:"New BSD License";}s:5:"notes";s:347:"* Fix Bug #14331: pear cvstag only works from inside the package directory [dufuz] * Fix Bug #16045: E_Notice: Undefined index: channel in PEAR/DependencyDB.php [dufuz] * Implemented Request #11230: better error message when mirror not in channel.xml file [dufuz] * Implemented Request #13150: Add support for following HTTP 302 redirects [dufuz]";}i:2;a:5:{s:4:"date";s:10:"2009-04-10";s:7:"version";a:2:{s:7:"release";s:5:"1.8.0";s:3:"api";s:5:"1.8.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:46:"http://opensource.org/licenses/bsd-license.php";}s:8:"_content";s:15:"New BSD License";}s:5:"notes";s:5737:"Changes since RC1: * Fix Bug #14792: Bad md5sum for files with replaced content [dufuz] * Fix Bug #16057:-r is limited to 4 directories in depth [dufuz] * Fix Bug #16077: PEAR5::getStaticProperty does not return a reference to the property [dufuz] Remove custom XML_Util class in favor of using upstream XML_Util package as dependency RC1 Release Notes: * Fix Bug #14331: pear cvstag only works from inside the package directory [dufuz] * Fix Bug #16045: E_Notice: Undefined index: channel in PEAR/DependencyDB.php [dufuz] * Implemented Request #11230: better error message when mirror not in channel.xml file [dufuz] * Implemented Request #13150: Add support for following HTTP 302 redirects [dufuz] Alpha1 Release Notes: * Implement Request #10373: if pref_state=stable and installed package=beta, allow up to latest beta version [dufuz] * Implement Request #10581: login / logout should map to channel-login / channel-logout [dufuz] * Implement Request #10825: Only display the "invalid or missing package file"-error if it makes sense [dufuz] * Implement Request #11170: script to generate Command/[command].xml [dufuz] * Implement Request #11176: improve channel ... has updated its protocols message [dufuz] * Implement Request #12706: pear list -a hard to read [dufuz] * Implement Request #11353: upgrade-all and upgrade commands to upgrade within the same stability level [dufuz] * Implement Request #13015: Add https discovery for channel.xml [dufuz / initial patch by Martin Roos] * Implement Request #13927: install-pear.php should have option to set www_dir [timj] * Implement Request #14324: Make the pear install command behave similar to apt-get [dufuz] * Implement Request #14325: make pear upgrade with no params behave like pear upgrade-all [dufuz] - upgrade-all can be considered deprecated in favor of calling upgrade with no parameters to replicate better what other package managers are doing. upgrade-all will still work as intended. * Implement Request #14504: add a channel parameter support to the upgrade function [dufuz] - Options -c ezc and --channel=ezc got added to upgrade and upgrade-all to allow for channel specific upgrades * Implement Request #14556: install-pear-nozlib.phar should get download_dir config and other options [cweiske] * Implement Request #15566: Add doc.php.net as a default channel [dufuz / saltybeagle] * Fix PHP Bug #43857: --program-suffix not always reflected everywhere [cellog] * Fix PHP Bug #47323: strotime warnings in make install [dufuz] * Fix Bug #13908: pear info command and maintainers inactive not mentioned [dufuz] * Fix Bug #13926: install-pear.php does not set cfg_dir if -d option set with no -c option [timj] * Fix Bug #13943: tests fail when php.exe path contains spaces [dufuz / jorrit] * Fix Bug #13953: config-set/config-show with channel alias fail [cellog] * Fix Bug #13958: When a phpt tests exit() or die() xdebug coverage is not generated, patch by izi (David Jean Louis) [izi / dufuz] * Fix Bug #14041: Unpredictable unit test processing sequence [dufuz] * Fix Bug #14140: Strict warning not suppressed in the shutdown function [dufuz] * Fix Bug #14210: pear list -ia brings warnings [dufuz] * Fix Bug #14274: PEAR packager mangles package.xml encoding, then complains about it [dufuz] * Fix Bug #14287: cannot upgrade from stable to beta via -beta when config is set to stable [dufuz] * Fix Bug #14300: Package files themselves can not be served over https [dufuz / initial patch by Martin Roos] * Fix Bug #14437: openbasedir warning when loading config [dufuz] * Fix Bug #14558: PackageFile.php creates tmp directory outside configured temp_dir [cweiske] * Fix Bug #14947: downloadHttp() is missing Host part of the HTTP Request when using Proxy [ifeghali] * Fix Bug #14977: PEAR/Frontend.php doesn't require_once PEAR.php [dufuz] * Fix Bug #15750: Unreachable code in PEAR_Downloader [dufuz] * Fix Bug #15979: Package files incorrectly removed when splitting a package into multiple pkgs [dufuz] * Fix Bug #15914: pear upgrade installs different version if desired version not found [dufuz] NOTE! Functions that have been deprecated for 3+ years in PEAR_Common, please take a moment to migrate over to one of the alternatives that have ben provided: * PEAR_Common->downloadHttp (use PEAR_Downloader->downloadHttp instead) * PEAR_Common->infoFromTgzFile (use PEAR_PackageFile->fromTgzFile instead) * PEAR_Common->infoFromDescriptionFile (use PEAR_PackageFile->fromPackageFile instead) * PEAR_Common->infoFromString (use PEAR_PackageFile->fromXmlstring instead) * PEAR_Common->infoFromArray (use PEAR_PackageFile->fromAnyFile instead) * PEAR_Common->xmlFromInfo (use a PEAR_PackageFile_v* object's generator instead) * PEAR_Common->validatePackageInfo (use the validation of PEAR_PackageFile objects) * PEAR_Common->analyzeSourceCode (use a PEAR_PackageFile_v* object instead) * PEAR_Common->detectDependencies (use PEAR_Downloader_Package->detectDependencies instead) * PEAR_Common->buildProvidesArray (use PEAR_PackageFile_v1->_buildProvidesArray or PEAR_PackageFile_v2_Validator->_buildProvidesArray) PHP 4.4 and 5.1.6 are now the minimum PHP requirements, for brave souls pear upgrade -f PEAR will allow people with lower versions to upgrade to this release but no guarantees will be made that it will work properly. Support for XML RPC channels has been dropped - The only ones that used it (pear.php.net and pecl.php.net) have used the REST interface for years now. SOAP support also removed as it was only proof of concept. Move codebase from the PHP License to New BSD 2 clause license";}i:3;a:5:{s:4:"date";s:10:"2009-04-15";s:7:"version";a:2:{s:7:"release";s:5:"1.8.1";s:3:"api";s:5:"1.8.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:46:"http://opensource.org/licenses/bsd-license.php";}s:8:"_content";s:15:"New BSD License";}s:5:"notes";s:58:"* Fix Bug #16099 PEAR crash on PHP4 (parse error) [dufuz]";}i:4;a:5:{s:4:"date";s:10:"2009-08-18";s:7:"version";a:2:{s:7:"release";s:8:"1.9.0RC1";s:3:"api";s:8:"1.9.0RC1";}s:9:"stability";a:2:{s:7:"release";s:4:"beta";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:46:"http://opensource.org/licenses/bsd-license.php";}s:8:"_content";s:15:"New BSD License";}s:5:"notes";s:1106:"* Implement Request #16213: add alias to list-channels output [dufuz] * Implement Request #16378: pear svntag [dufuz] * Implement Request #16386: PEAR_Config::remove() does not support specifying a channel [timj] * Implement Request #16396: package-dependencies should allow package names [dufuz] * Fix Bug #11181: pear requests channel.xml from main server instead from mirror [dufuz] * Fix Bug #14493: pear install --offline doesn't print out errors [dufuz] * Fix Bug #11348: pear package-dependencies isn't well explained [dufuz] * Fix Bug #16108: PEAR_PackageFile_Generator_v2 PHP4 parse error when running upgrade-all [dufuz] * Fix Bug #16113: Installing certain packages fails due incorrect encoding handling [dufuz] * Fix Bug #16122: PEAR RunTest failed to run as expected [dufuz] * Fix Bug #16366: compiling 5.2.10 leads to non-functioning pear [dufuz] * Fix Bug #16387: channel-logout does not support logging out from a non-default channel [timj] * Fix Bug #16444: Setting preferred mirror fails [dufuz] * Fix the shutdown functions where a index might not exist and thus raise a notice [derick]";}i:5;a:5:{s:4:"date";s:10:"2009-08-20";s:7:"version";a:2:{s:7:"release";s:8:"1.9.0RC2";s:3:"api";s:8:"1.9.0RC2";}s:9:"stability";a:2:{s:7:"release";s:4:"beta";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:46:"http://opensource.org/licenses/bsd-license.php";}s:8:"_content";s:15:"New BSD License";}s:5:"notes";s:107:"* REST 1.4 file was occasionally being included but REST 1.4 is not intended for this release cycle [dufuz]";}i:6;a:5:{s:4:"date";s:10:"2009-08-21";s:7:"version";a:2:{s:7:"release";s:8:"1.9.0RC3";s:3:"api";s:8:"1.9.0RC3";}s:9:"stability";a:2:{s:7:"release";s:4:"beta";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:46:"http://opensource.org/licenses/bsd-license.php";}s:8:"_content";s:15:"New BSD License";}s:5:"notes";s:70:"* Improved svntag support to handle packages like PEAR it self [dufuz]";}i:7;a:5:{s:4:"date";s:10:"2009-08-23";s:7:"version";a:2:{s:7:"release";s:8:"1.9.0RC4";s:3:"api";s:8:"1.9.0RC4";}s:9:"stability";a:2:{s:7:"release";s:4:"beta";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:46:"http://opensource.org/licenses/bsd-license.php";}s:8:"_content";s:15:"New BSD License";}s:5:"notes";s:244:"* Fixed a problem where the original channel could not be set as a preferred_mirror again [dufuz] * Make sure channel aliases can't be made to start with - [dufuz] * Output issues with pear search [dufuz] * Fixed couple of stray notices [dufuz]";}i:8;a:5:{s:4:"date";s:10:"2009-09-03";s:7:"version";a:2:{s:7:"release";s:5:"1.9.0";s:3:"api";s:5:"1.9.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:46:"http://opensource.org/licenses/bsd-license.php";}s:8:"_content";s:15:"New BSD License";}s:5:"notes";s:86:"* Fix Bug #16547: The phar for PEAR installer uses ereg() which is deprecated [dufuz]";}i:9;a:5:{s:4:"date";s:10:"2010-05-26";s:7:"version";a:2:{s:7:"release";s:5:"1.9.1";s:3:"api";s:5:"1.9.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:46:"http://opensource.org/licenses/bsd-license.php";}s:8:"_content";s:15:"New BSD License";}s:5:"notes";s:1111:"* svntag improvements, tag package files passed into the command and better directory checks [dufuz] * rely on Structures_Graph minimum version instead of recommended version [saltybeagle] * Fix Bug #12613: running go-pear.phar from C:\ fails [dufuz] * Fix Bug #14841: Installing pear into directory with space fails [dufuz] * Fix Bug #16644: pear.bat returns syntax error when parenthesis are in install path. [dufuz] [patch by bwaters (Bryan Waters)] * Fix Bug #16767: Use of Depreciated HTML Attributes in the Exception class [dufuz] [patch by fuhrysteve (Stephen J. Fuhry)] * Fix Bug #16864: "pear list-upgrades -i" issues E_WARNINGS [dufuz] [patch by rquadling (Richard Quadling)] * Fix Bug #17220: command `pear help` outputs to stderr instead of stdout [dufuz] * Fix Bug #17234: channel-discover adds port to HTTP Host header [dufuz] * Fix Bug #17292: Code Coverage in PEAR_RunTest does not work with namespaces [sebastian] * Fix Bug #17359: loadExtension() fails over missing dl() when used in multithread env [dufuz] * Fix Bug #17378: pear info $package fails if directory with that name exists [dufuz]";}i:10;a:6:{s:4:"date";s:10:"2011-02-28";s:4:"time";s:8:"18:30:00";s:7:"version";a:2:{s:7:"release";s:5:"1.9.2";s:3:"api";s:5:"1.9.2";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:46:"http://opensource.org/licenses/bsd-license.php";}s:8:"_content";s:15:"New BSD License";}s:5:"notes";s:1258:"Important! This is a security fix release. The advisory can be found at http://pear.php.net/advisory-20110228.txt Bugs: * Fixed Bug #17463: Regression: On Windows, svntag [patch by doconnor] * Fixed Bug #17641: pecl-list doesn't sort packages by name [dufuz] * Fixed Bug #17781: invalid argument warning on foreach due to an empty optional dependencie [dufuz] * Fixed Bug #17801: PEAR run-tests wrongly detects php-cgi [patch by David Jean Louis (izi)] * Fixed Bug #17839: pear svntag does not tag package.xml file [dufuz] * Fixed Bug #17986: PEAR Installer cannot handle files moved between packages [dufuz] * Fixed Bug #17997: Strange output if directories are not writeable [dufuz] * Fixed Bug #18001: PEAR/RunTest coverage fails [dufuz] * Fixed Bug #18056 [SECURITY]: Symlink attack in PEAR install [dufuz] * Fixed Bug #18218: "pear package" does not allow the use of late static binding [dufuz and Christer Edvartsen] * Fixed Bug #18238: Wrong return code from "pear help" [till] * Fixed Bug #18308: Broken error message about missing channel validator [yunosh] This feature is implemented as a result of #18056 * Implemented Request #16648: Use TMPDIR for builds instead of /var/tmp [dufuz]";}i:11;a:6:{s:4:"date";s:10:"2011-06-04";s:4:"time";s:8:"15:30:00";s:7:"version";a:2:{s:7:"release";s:5:"1.9.3";s:3:"api";s:5:"1.9.2";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:46:"http://opensource.org/licenses/bsd-license.php";}s:8:"_content";s:15:"New BSD License";}s:5:"notes";s:820:"* Fixed Bug #17744: Empty changelog causes fatal error in setChangelogentry [dufuz] * Fixed Bug #18340: raiseErro typo [doconnor] * Fixed Bug #18349: package.xml version not recognized when single quoted [dufuz] * Fixed Bug #18364: date.timezone errors for sh/bat files when TZ is not set in php.ini [dufuz] * Fixed Bug #18388: Parentheses error in REST.php line 232 [dufuz] * Fixed Bug #18428: invalid preg_match patterns [glen] * Fixed Bug #18486: REST/10.php does not check error condition [dufuz] * Fixed a problem in RunTest and code coverage. Correctly register the code coverage shutdown function in case we are inside a namespace. [sebastian] * Fixed a bug with extensions not providing their config.m4 and co in the root directory of their pecl package but rather in a sub directory, such as xhprof. [dufuz]";}i:12;a:6:{s:4:"date";s:10:"2011-07-06";s:4:"time";s:8:"15:30:00";s:7:"version";a:2:{s:7:"release";s:5:"1.9.4";s:3:"api";s:5:"1.9.4";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:46:"http://opensource.org/licenses/bsd-license.php";}s:8:"_content";s:15:"New BSD License";}s:5:"notes";s:705:"Bug Fixes: * Bug #17350: "pear install --force" doesn't uninstall files from previous pkg versions [dufuz] * Bug #18362: A whitespace TEMP_DIR path breaks install/upgrade functionality [dufuz] * Bug #18440: bad tmp folder path on install : Unable to create path for C:/Program/tmp [dufuz] * Bug #18581: "config-get -c" not returning channel's configuration when using alias [dufuz] * Bug #18639: regression: installing xdebug fails most likely due to another fix [dufuz] Features * All System (the class) functions can now take in spaced paths as long as they are surrounded in quotes. Prior to this it was possible to do that by passing all values in as an array (by product of #18362, #18440) [dufuz]";}i:13;a:6:{s:4:"date";s:10:"2014-06-27";s:4:"time";s:8:"18:17:00";s:7:"version";a:2:{s:7:"release";s:9:"1.9.5dev1";s:3:"api";s:5:"1.9.5";}s:9:"stability";a:2:{s:7:"release";s:5:"devel";s:3:"api";s:5:"devel";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:46:"http://opensource.org/licenses/bsd-license.php";}s:8:"_content";s:15:"New BSD License";}s:5:"notes";s:1093:"Bug fixes: * Fix bug #18343: Entities in file names decoded during packaging [cweiske] * Fix bug #18665: pecl extensions not enabled in empty php.ini files [Louis Opter] * Fix bug #18834: Do not truncate cache file if it is a symlink [avb] * Fix bug #18892: Parse error in Installer.php [ashnazg] * Fix bug #19482: fix pearcmd for include paths with trailing backslash [cweiske] * Fix bug #19793: PHP Notice about ob_end_clean() [cweiske] * Fix bug #20086: Invalid regexp in PEAR_Builder::build() [avb] * Fix bug #20203: split content-type and get real mime type [Samu Voutilainen] * Fix bug #20283: use full path for "zend_extension=..." [cweiske] * Fix bug #20284: Reset interpreter before running --CLEAN-- section php-cgi run [Mats Lindh] * Fix bug #20285: fix spelling mistakes [Veres Lajos] * Fix bug #20286: Support access of static variables on objects in validator [cweiske] * Fix bug #20321: Correctly detect name of current user during installation [cweiske] * Fix bug: let pear run-tests fail when there are failed tests [cweiske] * Prepare a test for bug #18056 / bug #18834 [avb]";}i:14;a:6:{s:4:"date";s:10:"2014-07-12";s:4:"time";s:8:"14:22:23";s:7:"version";a:2:{s:7:"release";s:5:"1.9.5";s:3:"api";s:5:"1.9.5";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:46:"http://opensource.org/licenses/bsd-license.php";}s:8:"_content";s:15:"New BSD License";}s:5:"notes";s:1137:"No changes since 1.9.5.dev1. Bug fixes in 1.9.5.dev1: * Fix bug #18343: Entities in file names decoded during packaging [cweiske] * Fix bug #18665: pecl extensions not enabled in empty php.ini files [Louis Opter] * Fix bug #18834: Do not truncate cache file if it is a symlink [avb] * Fix bug #18892: Parse error in Installer.php [ashnazg] * Fix bug #19482: fix pearcmd for include paths with trailing backslash [cweiske] * Fix bug #19793: PHP Notice about ob_end_clean() [cweiske] * Fix bug #20086: Invalid regexp in PEAR_Builder::build() [avb] * Fix bug #20203: split content-type and get real mime type [Samu Voutilainen] * Fix bug #20283: use full path for "zend_extension=..." [cweiske] * Fix bug #20284: Reset interpreter before running --CLEAN-- section php-cgi run [Mats Lindh] * Fix bug #20285: fix spelling mistakes [Veres Lajos] * Fix bug #20286: Support access of static variables on objects in validator [cweiske] * Fix bug #20321: Correctly detect name of current user during installation [cweiske] * Fix bug: let pear run-tests fail when there are failed tests [cweiske] * Prepare a test for bug #18056 / bug #18834 [avb]";}i:15;a:6:{s:4:"date";s:10:"2015-07-25";s:4:"time";s:8:"13:42:42";s:7:"version";a:2:{s:7:"release";s:10:"1.10.0dev1";s:3:"api";s:6:"1.10.0";}s:9:"stability";a:2:{s:7:"release";s:5:"devel";s:3:"api";s:5:"devel";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:46:"http://opensource.org/licenses/bsd-license.php";}s:8:"_content";s:15:"New BSD License";}s:5:"notes";s:444:"* Implement #20488: Add support for PHP 7 [cweiske] * Drop support for PHP 4 and 5.0 - 5.3 [cweiske] * Remove deprecated methods [cweiske] * Fix static warnings [cweiske] * Fix #17045: avoid overwriting include path [glen] * Fix #17399: "pear help" doesn't mention the "version" command [kguest] * Add --showdiff to "pear run-tests" to print diff for failed tests [tyrael] * Fix channel.xml downloading from https if it did not change [cweiske]";}i:16;a:6:{s:4:"date";s:10:"2015-07-31";s:4:"time";s:8:"09:42:42";s:7:"version";a:2:{s:7:"release";s:10:"1.10.0dev2";s:3:"api";s:6:"1.10.0";}s:9:"stability";a:2:{s:7:"release";s:5:"devel";s:3:"api";s:5:"devel";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:46:"http://opensource.org/licenses/bsd-license.php";}s:8:"_content";s:15:"New BSD License";}s:5:"notes";s:328:"* Fix #18638 and #18405: Make PEAR::loadExtension static [cweiske] * Fix #20319: allow pear to work when cache_dir is not writable [remicollet] * Implement #20333: New role=man for man pages [bjori] * Implement #20334: add "metadata_dir" configuration option [remicollet] * Add long option names to install-pear.php [remicollet]";}i:17;a:6:{s:4:"date";s:10:"2015-09-28";s:4:"time";s:8:"09:42:42";s:7:"version";a:2:{s:7:"release";s:10:"1.10.0dev3";s:3:"api";s:6:"1.10.0";}s:9:"stability";a:2:{s:7:"release";s:5:"devel";s:3:"api";s:5:"devel";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:46:"http://opensource.org/licenses/bsd-license.php";}s:8:"_content";s:15:"New BSD License";}s:5:"notes";s:227:"* Fix #20507: pear list-upgrades does not take PHP version into account [cweiske] * Fix #20927: Use correct php-config [cweiske] * Fix #20946: PEAR_Builder::log() declaration [remicollet] * Remove PEAR/ErrorStack5.php [cweiske]";}i:18;a:6:{s:4:"date";s:10:"2015-10-07";s:4:"time";s:8:"11:22:42";s:7:"version";a:2:{s:7:"release";s:6:"1.10.0";s:3:"api";s:6:"1.10.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:46:"http://opensource.org/licenses/bsd-license.php";}s:8:"_content";s:15:"New BSD License";}s:5:"notes";s:1068:"No changes since version 1.10.0dev3. Changes since version 1.9.5: * Implement #20488: Add support for PHP 7 [cweiske] * Drop support for PHP 4 and 5.0 - 5.3 [cweiske] * Remove deprecated methods [cweiske] * Add --showdiff to "pear run-tests" to print diff for failed tests [tyrael] * Implement #20333: New role=man for man pages [bjori] * Implement #20334: add "metadata_dir" configuration option [remicollet] * Add long option names to install-pear.php [remicollet] * Remove PEAR/ErrorStack5.php [cweiske] * Fix #17045: avoid overwriting include path [glen] * Fix #17399: "pear help" doesn't mention the "version" command [kguest] * Fix #18638 and #18405: Make PEAR::loadExtension static [cweiske] * Fix #20319: allow pear to work when cache_dir is not writable [remicollet] * Fix #20507: pear list-upgrades does not take PHP version into account [cweiske] * Fix #20927: Use correct php-config [cweiske] * Fix #20946: PEAR_Builder::log() declaration [remicollet] * Fix channel.xml downloading from https if it did not change [cweiske] * Fix static warnings [cweiske]";}i:19;a:6:{s:4:"date";s:10:"2015-10-17";s:4:"time";s:8:"13:22:42";s:7:"version";a:2:{s:7:"release";s:6:"1.10.1";s:3:"api";s:6:"1.10.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:46:"http://opensource.org/licenses/bsd-license.php";}s:8:"_content";s:15:"New BSD License";}s:5:"notes";s:229:"* Fix bug #20959: Crash on channel discovery with channel.xml redirect [cweiske] * Fix bug #20968: Incorrect call to __construct() from PEAR() [edlman] * Add legacy constructor for PEAR_Error for backwards compatibility [cweiske]";}i:20;a:6:{s:4:"date";s:10:"2017-02-28";s:4:"time";s:8:"07:40:00";s:7:"version";a:2:{s:7:"release";s:6:"1.10.2";s:3:"api";s:6:"1.10.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:46:"http://opensource.org/licenses/bsd-license.php";}s:8:"_content";s:15:"New BSD License";}s:5:"notes";s:544:"* Fix Bug #4426: PEAR_Autoloader __call() must take only 2 arguments [kna] * Fix Bug #20989: fatal error/bug in the postinstallscript task [kguest] * Fix Bug #20991: Strict Standards: startSession and run methods in PEAR_Task_Postinstallscript [kguest] * Fix Bug #21001: PEAR_ERROR_DIE exit code is 0 [danielc] * Pull Request #52: Channel's _lastmodified is an int and not a string [sathieu] * Pull Request #53: Add proper HTTPS proxy support through the CONNECT verb [youknow0] * Pull Request #58: Make method signatures compatible. [yunosh]";}i:21;a:6:{s:4:"date";s:10:"2017-02-28";s:4:"time";s:8:"10:15:00";s:7:"version";a:2:{s:7:"release";s:6:"1.10.3";s:3:"api";s:6:"1.10.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:46:"http://opensource.org/licenses/bsd-license.php";}s:8:"_content";s:15:"New BSD License";}s:5:"notes";s:42:"* Bug #21188: Class 'PEAR_Proxy' not found";}i:22;a:5:{s:4:"date";s:10:"2017-04-25";s:7:"version";a:2:{s:7:"release";s:6:"1.10.4";s:3:"api";s:6:"1.10.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:46:"http://opensource.org/licenses/bsd-license.php";}s:8:"_content";s:15:"New BSD License";}s:5:"notes";s:50:"* Bug #18102: pear install does not fail on error";}i:23;a:5:{s:4:"date";s:10:"2017-06-27";s:7:"version";a:2:{s:7:"release";s:6:"1.10.5";s:3:"api";s:6:"1.10.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:46:"http://opensource.org/licenses/bsd-license.php";}s:8:"_content";s:15:"New BSD License";}s:5:"notes";s:73:"* Bug #21222: PHP 7.2 compatibility: Upgrade to Archive_Tar 1.4.3 needed";}i:24;a:5:{s:4:"date";s:10:"2018-08-22";s:7:"version";a:2:{s:7:"release";s:6:"1.10.6";s:3:"api";s:6:"1.10.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:46:"http://opensource.org/licenses/bsd-license.php";}s:8:"_content";s:15:"New BSD License";}s:5:"notes";s:544:"* PR #70: Fix notice undefined variable metadata_dir * PR #71: fix Warning: count(): Parameter must be an array or an object * PR #74: Bug #23744 Remove is_executable check * Bug #23744: The is_executable check in the Which method when run on Windows is unnecessary * PR #75: Migrate old while(list() = each()) constructs to foreach * PR #76: Fix PHP Warning: "continue" targeting switch is equivalent to "break" * PR #77: proxy server auth * PR #72: Correctly authenticate at proxy server * PR #78: array or Countable error in 7.2";}i:25;a:5:{s:4:"date";s:10:"2018-12-05";s:7:"version";a:2:{s:7:"release";s:6:"1.10.7";s:3:"api";s:6:"1.10.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:46:"http://opensource.org/licenses/bsd-license.php";}s:8:"_content";s:15:"New BSD License";}s:5:"notes";s:238:"* PR #79: Prevent Unable to find the wrapper "channel" Warning * PR #80: fix Warning: "continue" targeting switch is equivalent to "break". Did you mean to use "continue 2" * PR #81: Add flags to PECL shell script for shared extensions";}i:26;a:5:{s:4:"date";s:10:"2019-02-07";s:7:"version";a:2:{s:7:"release";s:6:"1.10.8";s:3:"api";s:6:"1.10.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:46:"http://opensource.org/licenses/bsd-license.php";}s:8:"_content";s:15:"New BSD License";}s:5:"notes";s:83:"* PR #83: Drop track_errors from options * PR #84: Fix PHP 8 compatibility issues";}i:27;a:5:{s:4:"date";s:10:"2019-03-13";s:7:"version";a:2:{s:7:"release";s:6:"1.10.9";s:3:"api";s:6:"1.10.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:46:"http://opensource.org/licenses/bsd-license.php";}s:8:"_content";s:15:"New BSD License";}s:5:"notes";s:191:"* PR #85: Fixes static calls for PHP 8 * PR #86: Adjust silencing check for PHP 8 * PR #87: Comparison fixes * PR #88: Only add bin_dir to PATH if not already there (fixes PHP Bug #75852)";}i:28;a:5:{s:4:"date";s:10:"2019-11-19";s:7:"version";a:2:{s:7:"release";s:7:"1.10.10";s:3:"api";s:6:"1.10.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:46:"http://opensource.org/licenses/bsd-license.php";}s:8:"_content";s:15:"New BSD License";}s:5:"notes";s:672:"* PR #89: Fix scripts/* include paths * PR #90: Non-interactive configureoption answers * PR #91: Added missing preg quote * PR #92: handle "lib64" case for glibc detection * PR #93: Fix PHP Notice: Trying to access array offset on value of type bool with 7.4 * PR #94: Updated logic in useLocalCache to reuse getCacheId * PR #95: Fix manpage warning * PR #96: Implement the SOURCE_DATE_EPOCH specification * PR #97: Fix PHP 7.4 deprecation: array/string curly braces access * PR #98: Fix use of null/false as array * PR #99: Fix Travis builds on PHP 5.4 and 5.5 * PR #100: Honor PHP temp directory config * PR #101: Fix documentation: the `--force` is required";}i:29;a:5:{s:4:"date";s:10:"2020-04-10";s:7:"version";a:2:{s:7:"release";s:7:"1.10.11";s:3:"api";s:6:"1.10.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:46:"http://opensource.org/licenses/bsd-license.php";}s:8:"_content";s:15:"New BSD License";}s:5:"notes";s:230:"* PR #102: Fix logging error for urls not in cache * PR #103: Fix undefined constant name * PR #105: Sort list of packages * PR #106: Update REST.php * PR #107: Update .travis.yml to include PHP 7.4 * PR #108: Remove unneeded code";}i:30;a:5:{s:4:"date";s:10:"2020-04-19";s:7:"version";a:2:{s:7:"release";s:7:"1.10.12";s:3:"api";s:6:"1.10.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:46:"http://opensource.org/licenses/bsd-license.php";}s:8:"_content";s:15:"New BSD License";}s:5:"notes";s:43:"* adjust dependencies based on new releases";}i:31;a:5:{s:4:"date";s:10:"2021-08-10";s:7:"version";a:2:{s:7:"release";s:7:"1.10.13";s:3:"api";s:6:"1.10.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:46:"http://opensource.org/licenses/bsd-license.php";}s:8:"_content";s:15:"New BSD License";}s:5:"notes";s:116:"* PR #114: unsupported protocol - use --force to continue * PR #117: Add $this operator to _determineIfPowerpc calls";}i:32;a:5:{s:4:"date";s:10:"2023-11-26";s:7:"version";a:2:{s:7:"release";s:7:"1.10.14";s:3:"api";s:6:"1.10.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:46:"http://opensource.org/licenses/bsd-license.php";}s:8:"_content";s:15:"New BSD License";}s:5:"notes";s:583:"* PR #112: Put glue and pieces parameters to implode in correct order for PHP 7.4+ * PR #121: Fix PHP bug 81653: Typo in install-pear-nozlib.phar * PR #122: add %S EXPECTF capability * PR #124: Fix: Creation of dynamic property PEAR_Error::$callback is deprecated * PR #125: Fixed extension loaded check for pecl binaries * PR #126: Remove -n option from pecl.bat for shared extensions * PR #127: fix Using ${var} in strings is deprecated * PR #128: fix lingering license references to PHP license * PR #129: Exclude tests from composer classmap * PR #131: fix private lastError name";}i:33;a:5:{s:4:"date";s:10:"2024-03-09";s:7:"version";a:2:{s:7:"release";s:7:"1.10.15";s:3:"api";s:6:"1.10.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:46:"http://opensource.org/licenses/bsd-license.php";}s:8:"_content";s:15:"New BSD License";}s:5:"notes";s:100:"* PR #132: cleanup uneeded test * PR #135: Fix PHP Deprecated: Calling get_class() without arguments";}i:34;a:5:{s:4:"date";s:10:"2024-11-24";s:7:"version";a:2:{s:7:"release";s:7:"1.10.16";s:3:"api";s:6:"1.10.1";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:46:"http://opensource.org/licenses/bsd-license.php";}s:8:"_content";s:15:"New BSD License";}s:5:"notes";s:164:"* PR #141: Fix bug #27796: "Array to string" conversion warnings on installs/other actions * PR #145: Never reference E_STRICT on PHP 8.4+ * PR #147: Fix tests 8.1+";}}}s:8:"filelist";a:102:{s:12:"OS/Guess.php";a:4:{s:6:"md5sum";s:32:"c0482b234f269360953c87472b5cf746";s:4:"name";s:12:"OS/Guess.php";s:4:"role";s:3:"php";s:12:"installed_as";s:42:"/opt/alt/php56/usr/share/pear/OS/Guess.php";}s:27:"PEAR/ChannelFile/Parser.php";a:4:{s:6:"md5sum";s:32:"3b371e9c6b4d667abb8be01f2788dcf9";s:4:"name";s:27:"PEAR/ChannelFile/Parser.php";s:4:"role";s:3:"php";s:12:"installed_as";s:57:"/opt/alt/php56/usr/share/pear/PEAR/ChannelFile/Parser.php";}s:21:"PEAR/Command/Auth.xml";a:4:{s:6:"md5sum";s:32:"8fd87e64002e11fd86eb2f3fbfee6599";s:4:"name";s:21:"PEAR/Command/Auth.xml";s:4:"role";s:3:"php";s:12:"installed_as";s:51:"/opt/alt/php56/usr/share/pear/PEAR/Command/Auth.xml";}s:21:"PEAR/Command/Auth.php";a:4:{s:6:"md5sum";s:32:"65b6b36c4cc53f2836ad09b070829877";s:4:"name";s:21:"PEAR/Command/Auth.php";s:4:"role";s:3:"php";s:12:"installed_as";s:51:"/opt/alt/php56/usr/share/pear/PEAR/Command/Auth.php";}s:22:"PEAR/Command/Build.xml";a:4:{s:6:"md5sum";s:32:"ce6bb5b6fdc02e0f50e7676403fd84a4";s:4:"name";s:22:"PEAR/Command/Build.xml";s:4:"role";s:3:"php";s:12:"installed_as";s:52:"/opt/alt/php56/usr/share/pear/PEAR/Command/Build.xml";}s:22:"PEAR/Command/Build.php";a:4:{s:6:"md5sum";s:32:"e19325f59c4013694a4a06b61e7ac3be";s:4:"name";s:22:"PEAR/Command/Build.php";s:4:"role";s:3:"php";s:12:"installed_as";s:52:"/opt/alt/php56/usr/share/pear/PEAR/Command/Build.php";}s:25:"PEAR/Command/Channels.xml";a:4:{s:6:"md5sum";s:32:"6d5aab4d4308c3005b5f584c7783a031";s:4:"name";s:25:"PEAR/Command/Channels.xml";s:4:"role";s:3:"php";s:12:"installed_as";s:55:"/opt/alt/php56/usr/share/pear/PEAR/Command/Channels.xml";}s:25:"PEAR/Command/Channels.php";a:4:{s:6:"md5sum";s:32:"56b3b36834a751f6e7b86dcba6cefe2f";s:4:"name";s:25:"PEAR/Command/Channels.php";s:4:"role";s:3:"php";s:12:"installed_as";s:55:"/opt/alt/php56/usr/share/pear/PEAR/Command/Channels.php";}s:23:"PEAR/Command/Common.php";a:4:{s:6:"md5sum";s:32:"aae7cc03e9b7fe7c4f504b970dca5411";s:4:"name";s:23:"PEAR/Command/Common.php";s:4:"role";s:3:"php";s:12:"installed_as";s:53:"/opt/alt/php56/usr/share/pear/PEAR/Command/Common.php";}s:23:"PEAR/Command/Config.xml";a:4:{s:6:"md5sum";s:32:"91f189cb9423b5e87ee0abc5ea1a2be3";s:4:"name";s:23:"PEAR/Command/Config.xml";s:4:"role";s:3:"php";s:12:"installed_as";s:53:"/opt/alt/php56/usr/share/pear/PEAR/Command/Config.xml";}s:23:"PEAR/Command/Config.php";a:4:{s:6:"md5sum";s:32:"3c5d633b0e8d4e39e9bfb286f51130a5";s:4:"name";s:23:"PEAR/Command/Config.php";s:4:"role";s:3:"php";s:12:"installed_as";s:53:"/opt/alt/php56/usr/share/pear/PEAR/Command/Config.php";}s:24:"PEAR/Command/Install.xml";a:4:{s:6:"md5sum";s:32:"24d05213cae7faa3880bbb5e40998867";s:4:"name";s:24:"PEAR/Command/Install.xml";s:4:"role";s:3:"php";s:12:"installed_as";s:54:"/opt/alt/php56/usr/share/pear/PEAR/Command/Install.xml";}s:24:"PEAR/Command/Install.php";a:4:{s:6:"md5sum";s:32:"3dab53d092878709aa16f73143600107";s:4:"name";s:24:"PEAR/Command/Install.php";s:4:"role";s:3:"php";s:12:"installed_as";s:54:"/opt/alt/php56/usr/share/pear/PEAR/Command/Install.php";}s:23:"PEAR/Command/Mirror.xml";a:4:{s:6:"md5sum";s:32:"5cb62a04c0a268f4edd64a49a3895c92";s:4:"name";s:23:"PEAR/Command/Mirror.xml";s:4:"role";s:3:"php";s:12:"installed_as";s:53:"/opt/alt/php56/usr/share/pear/PEAR/Command/Mirror.xml";}s:23:"PEAR/Command/Mirror.php";a:4:{s:6:"md5sum";s:32:"2f5798bb62453d8d1bffa3d050584232";s:4:"name";s:23:"PEAR/Command/Mirror.php";s:4:"role";s:3:"php";s:12:"installed_as";s:53:"/opt/alt/php56/usr/share/pear/PEAR/Command/Mirror.php";}s:24:"PEAR/Command/Package.xml";a:4:{s:6:"md5sum";s:32:"9367dcd7e4dbdde423f9c4c7d3f3a919";s:4:"name";s:24:"PEAR/Command/Package.xml";s:4:"role";s:3:"php";s:12:"installed_as";s:54:"/opt/alt/php56/usr/share/pear/PEAR/Command/Package.xml";}s:24:"PEAR/Command/Package.php";a:4:{s:6:"md5sum";s:32:"a0a6b2ba1e67351359cf105b6f863806";s:4:"name";s:24:"PEAR/Command/Package.php";s:4:"role";s:3:"php";s:12:"installed_as";s:54:"/opt/alt/php56/usr/share/pear/PEAR/Command/Package.php";}s:23:"PEAR/Command/Pickle.xml";a:4:{s:6:"md5sum";s:32:"28dc842ea725d8787b9f9c3dbca5aa22";s:4:"name";s:23:"PEAR/Command/Pickle.xml";s:4:"role";s:3:"php";s:12:"installed_as";s:53:"/opt/alt/php56/usr/share/pear/PEAR/Command/Pickle.xml";}s:23:"PEAR/Command/Pickle.php";a:4:{s:6:"md5sum";s:32:"4025dd6411a73b19a5c19b3300060625";s:4:"name";s:23:"PEAR/Command/Pickle.php";s:4:"role";s:3:"php";s:12:"installed_as";s:53:"/opt/alt/php56/usr/share/pear/PEAR/Command/Pickle.php";}s:25:"PEAR/Command/Registry.xml";a:4:{s:6:"md5sum";s:32:"49b046cfc14747f0365e02e9c3f0e6dc";s:4:"name";s:25:"PEAR/Command/Registry.xml";s:4:"role";s:3:"php";s:12:"installed_as";s:55:"/opt/alt/php56/usr/share/pear/PEAR/Command/Registry.xml";}s:25:"PEAR/Command/Registry.php";a:4:{s:6:"md5sum";s:32:"9f2ea65794243f0b7287e8883f2ab60e";s:4:"name";s:25:"PEAR/Command/Registry.php";s:4:"role";s:3:"php";s:12:"installed_as";s:55:"/opt/alt/php56/usr/share/pear/PEAR/Command/Registry.php";}s:23:"PEAR/Command/Remote.xml";a:4:{s:6:"md5sum";s:32:"29c02e823879b4e3e291f6b36fb339f1";s:4:"name";s:23:"PEAR/Command/Remote.xml";s:4:"role";s:3:"php";s:12:"installed_as";s:53:"/opt/alt/php56/usr/share/pear/PEAR/Command/Remote.xml";}s:23:"PEAR/Command/Remote.php";a:4:{s:6:"md5sum";s:32:"42c51cbb21c103fe0288e5c16871f401";s:4:"name";s:23:"PEAR/Command/Remote.php";s:4:"role";s:3:"php";s:12:"installed_as";s:53:"/opt/alt/php56/usr/share/pear/PEAR/Command/Remote.php";}s:21:"PEAR/Command/Test.xml";a:4:{s:6:"md5sum";s:32:"a50c32015005e0761cc3b04679b29ed0";s:4:"name";s:21:"PEAR/Command/Test.xml";s:4:"role";s:3:"php";s:12:"installed_as";s:51:"/opt/alt/php56/usr/share/pear/PEAR/Command/Test.xml";}s:21:"PEAR/Command/Test.php";a:4:{s:6:"md5sum";s:32:"fbb0098fcda7fa29adaa0714a325caea";s:4:"name";s:21:"PEAR/Command/Test.php";s:4:"role";s:3:"php";s:12:"installed_as";s:51:"/opt/alt/php56/usr/share/pear/PEAR/Command/Test.php";}s:27:"PEAR/Downloader/Package.php";a:4:{s:6:"md5sum";s:32:"9229a9711a893a18298e473212689ab4";s:4:"name";s:27:"PEAR/Downloader/Package.php";s:4:"role";s:3:"php";s:12:"installed_as";s:57:"/opt/alt/php56/usr/share/pear/PEAR/Downloader/Package.php";}s:21:"PEAR/Frontend/CLI.php";a:4:{s:6:"md5sum";s:32:"5379be9492842c3af98241c6e226d285";s:4:"name";s:21:"PEAR/Frontend/CLI.php";s:4:"role";s:3:"php";s:12:"installed_as";s:51:"/opt/alt/php56/usr/share/pear/PEAR/Frontend/CLI.php";}s:30:"PEAR/Installer/Role/Common.php";a:4:{s:6:"md5sum";s:32:"adae220f10a82e5f78b8689a57387753";s:4:"name";s:30:"PEAR/Installer/Role/Common.php";s:4:"role";s:3:"php";s:12:"installed_as";s:60:"/opt/alt/php56/usr/share/pear/PEAR/Installer/Role/Common.php";}s:27:"PEAR/Installer/Role/Cfg.xml";a:4:{s:6:"md5sum";s:32:"d8c62e6275e3aaa7784290912406092c";s:4:"name";s:27:"PEAR/Installer/Role/Cfg.xml";s:4:"role";s:3:"php";s:12:"installed_as";s:57:"/opt/alt/php56/usr/share/pear/PEAR/Installer/Role/Cfg.xml";}s:27:"PEAR/Installer/Role/Cfg.php";a:4:{s:6:"md5sum";s:32:"d89d39dcc1c55fb4464f447ce4f84eed";s:4:"name";s:27:"PEAR/Installer/Role/Cfg.php";s:4:"role";s:3:"php";s:12:"installed_as";s:57:"/opt/alt/php56/usr/share/pear/PEAR/Installer/Role/Cfg.php";}s:28:"PEAR/Installer/Role/Data.xml";a:4:{s:6:"md5sum";s:32:"89a4a2a286e842d45a98974f40a0565c";s:4:"name";s:28:"PEAR/Installer/Role/Data.xml";s:4:"role";s:3:"php";s:12:"installed_as";s:58:"/opt/alt/php56/usr/share/pear/PEAR/Installer/Role/Data.xml";}s:28:"PEAR/Installer/Role/Data.php";a:4:{s:6:"md5sum";s:32:"89754e8d153937f3dd3266fd8897d965";s:4:"name";s:28:"PEAR/Installer/Role/Data.php";s:4:"role";s:3:"php";s:12:"installed_as";s:58:"/opt/alt/php56/usr/share/pear/PEAR/Installer/Role/Data.php";}s:27:"PEAR/Installer/Role/Doc.xml";a:4:{s:6:"md5sum";s:32:"b1ce0fe105251c3b75209d6518ee69ac";s:4:"name";s:27:"PEAR/Installer/Role/Doc.xml";s:4:"role";s:3:"php";s:12:"installed_as";s:57:"/opt/alt/php56/usr/share/pear/PEAR/Installer/Role/Doc.xml";}s:27:"PEAR/Installer/Role/Doc.php";a:4:{s:6:"md5sum";s:32:"849c557b355f78890ef47fcfd12073ab";s:4:"name";s:27:"PEAR/Installer/Role/Doc.php";s:4:"role";s:3:"php";s:12:"installed_as";s:57:"/opt/alt/php56/usr/share/pear/PEAR/Installer/Role/Doc.php";}s:27:"PEAR/Installer/Role/Ext.xml";a:4:{s:6:"md5sum";s:32:"af71c0ad42d16a323afe24a4f884ef15";s:4:"name";s:27:"PEAR/Installer/Role/Ext.xml";s:4:"role";s:3:"php";s:12:"installed_as";s:57:"/opt/alt/php56/usr/share/pear/PEAR/Installer/Role/Ext.xml";}s:27:"PEAR/Installer/Role/Ext.php";a:4:{s:6:"md5sum";s:32:"7d3dc799576b3e3d74d187de118cc3e4";s:4:"name";s:27:"PEAR/Installer/Role/Ext.php";s:4:"role";s:3:"php";s:12:"installed_as";s:57:"/opt/alt/php56/usr/share/pear/PEAR/Installer/Role/Ext.php";}s:27:"PEAR/Installer/Role/Man.xml";a:4:{s:6:"md5sum";s:32:"da6743f1e45cce72ea13aef5cdb14867";s:4:"name";s:27:"PEAR/Installer/Role/Man.xml";s:4:"role";s:3:"php";s:12:"installed_as";s:57:"/opt/alt/php56/usr/share/pear/PEAR/Installer/Role/Man.xml";}s:27:"PEAR/Installer/Role/Man.php";a:4:{s:6:"md5sum";s:32:"2509a027ae42c4b96aa49557325a0ec4";s:4:"name";s:27:"PEAR/Installer/Role/Man.php";s:4:"role";s:3:"php";s:12:"installed_as";s:57:"/opt/alt/php56/usr/share/pear/PEAR/Installer/Role/Man.php";}s:27:"PEAR/Installer/Role/Php.xml";a:4:{s:6:"md5sum";s:32:"ef88f0321d3e481c2130c95122cf76d8";s:4:"name";s:27:"PEAR/Installer/Role/Php.xml";s:4:"role";s:3:"php";s:12:"installed_as";s:57:"/opt/alt/php56/usr/share/pear/PEAR/Installer/Role/Php.xml";}s:27:"PEAR/Installer/Role/Php.php";a:4:{s:6:"md5sum";s:32:"d7547896ec403dba2eed9825ed86ea64";s:4:"name";s:27:"PEAR/Installer/Role/Php.php";s:4:"role";s:3:"php";s:12:"installed_as";s:57:"/opt/alt/php56/usr/share/pear/PEAR/Installer/Role/Php.php";}s:30:"PEAR/Installer/Role/Script.xml";a:4:{s:6:"md5sum";s:32:"746461dc3b48af6d24094cb0211608f2";s:4:"name";s:30:"PEAR/Installer/Role/Script.xml";s:4:"role";s:3:"php";s:12:"installed_as";s:60:"/opt/alt/php56/usr/share/pear/PEAR/Installer/Role/Script.xml";}s:30:"PEAR/Installer/Role/Script.php";a:4:{s:6:"md5sum";s:32:"325c60df7f78be127741621561758f46";s:4:"name";s:30:"PEAR/Installer/Role/Script.php";s:4:"role";s:3:"php";s:12:"installed_as";s:60:"/opt/alt/php56/usr/share/pear/PEAR/Installer/Role/Script.php";}s:27:"PEAR/Installer/Role/Src.xml";a:4:{s:6:"md5sum";s:32:"e147d63f168ea156fc2be38caaa63804";s:4:"name";s:27:"PEAR/Installer/Role/Src.xml";s:4:"role";s:3:"php";s:12:"installed_as";s:57:"/opt/alt/php56/usr/share/pear/PEAR/Installer/Role/Src.xml";}s:27:"PEAR/Installer/Role/Src.php";a:4:{s:6:"md5sum";s:32:"464722cee0665ebc75757f76532f0ab2";s:4:"name";s:27:"PEAR/Installer/Role/Src.php";s:4:"role";s:3:"php";s:12:"installed_as";s:57:"/opt/alt/php56/usr/share/pear/PEAR/Installer/Role/Src.php";}s:28:"PEAR/Installer/Role/Test.xml";a:4:{s:6:"md5sum";s:32:"a24b596ec987aa5688fc19e8ed4e97ea";s:4:"name";s:28:"PEAR/Installer/Role/Test.xml";s:4:"role";s:3:"php";s:12:"installed_as";s:58:"/opt/alt/php56/usr/share/pear/PEAR/Installer/Role/Test.xml";}s:28:"PEAR/Installer/Role/Test.php";a:4:{s:6:"md5sum";s:32:"a04eb2f4881ec6e6a13ae78f6a43e3cd";s:4:"name";s:28:"PEAR/Installer/Role/Test.php";s:4:"role";s:3:"php";s:12:"installed_as";s:58:"/opt/alt/php56/usr/share/pear/PEAR/Installer/Role/Test.php";}s:27:"PEAR/Installer/Role/Www.xml";a:4:{s:6:"md5sum";s:32:"7641e71c5785bb33a4261ebe25ed0fd7";s:4:"name";s:27:"PEAR/Installer/Role/Www.xml";s:4:"role";s:3:"php";s:12:"installed_as";s:57:"/opt/alt/php56/usr/share/pear/PEAR/Installer/Role/Www.xml";}s:27:"PEAR/Installer/Role/Www.php";a:4:{s:6:"md5sum";s:32:"62699034e3186c2d68a6bb56a6cc23eb";s:4:"name";s:27:"PEAR/Installer/Role/Www.php";s:4:"role";s:3:"php";s:12:"installed_as";s:57:"/opt/alt/php56/usr/share/pear/PEAR/Installer/Role/Www.php";}s:23:"PEAR/Installer/Role.php";a:4:{s:6:"md5sum";s:32:"e95f2d850fce183e221912b2c2056d04";s:4:"name";s:23:"PEAR/Installer/Role.php";s:4:"role";s:3:"php";s:12:"installed_as";s:53:"/opt/alt/php56/usr/share/pear/PEAR/Installer/Role.php";}s:33:"PEAR/PackageFile/Generator/v1.php";a:4:{s:6:"md5sum";s:32:"cfa08685115d5e2d7635225d73a91f39";s:4:"name";s:33:"PEAR/PackageFile/Generator/v1.php";s:4:"role";s:3:"php";s:12:"installed_as";s:63:"/opt/alt/php56/usr/share/pear/PEAR/PackageFile/Generator/v1.php";}s:33:"PEAR/PackageFile/Generator/v2.php";a:4:{s:6:"md5sum";s:32:"8d264031153993866828e82129e389ab";s:4:"name";s:33:"PEAR/PackageFile/Generator/v2.php";s:4:"role";s:3:"php";s:12:"installed_as";s:63:"/opt/alt/php56/usr/share/pear/PEAR/PackageFile/Generator/v2.php";}s:30:"PEAR/PackageFile/Parser/v1.php";a:4:{s:6:"md5sum";s:32:"a2206e0e32ad2ba2f4e2a0c1797f295c";s:4:"name";s:30:"PEAR/PackageFile/Parser/v1.php";s:4:"role";s:3:"php";s:12:"installed_as";s:60:"/opt/alt/php56/usr/share/pear/PEAR/PackageFile/Parser/v1.php";}s:30:"PEAR/PackageFile/Parser/v2.php";a:4:{s:6:"md5sum";s:32:"3857f4b60878d64551a7cdae783437f7";s:4:"name";s:30:"PEAR/PackageFile/Parser/v2.php";s:4:"role";s:3:"php";s:12:"installed_as";s:60:"/opt/alt/php56/usr/share/pear/PEAR/PackageFile/Parser/v2.php";}s:26:"PEAR/PackageFile/v2/rw.php";a:4:{s:6:"md5sum";s:32:"a253999b2109460badc3c71ad2c069e7";s:4:"name";s:26:"PEAR/PackageFile/v2/rw.php";s:4:"role";s:3:"php";s:12:"installed_as";s:56:"/opt/alt/php56/usr/share/pear/PEAR/PackageFile/v2/rw.php";}s:33:"PEAR/PackageFile/v2/Validator.php";a:4:{s:6:"md5sum";s:32:"44dafa313204f68b5fb54b9f61a86d0c";s:4:"name";s:33:"PEAR/PackageFile/v2/Validator.php";s:4:"role";s:3:"php";s:12:"installed_as";s:63:"/opt/alt/php56/usr/share/pear/PEAR/PackageFile/v2/Validator.php";}s:23:"PEAR/PackageFile/v1.php";a:4:{s:6:"md5sum";s:32:"cc1ea307bb79c0cbcff4a90a4656e96e";s:4:"name";s:23:"PEAR/PackageFile/v1.php";s:4:"role";s:3:"php";s:12:"installed_as";s:53:"/opt/alt/php56/usr/share/pear/PEAR/PackageFile/v1.php";}s:23:"PEAR/PackageFile/v2.php";a:4:{s:6:"md5sum";s:32:"9e6012d4ef9cb8e12e2ccadcbdcf3d24";s:4:"name";s:23:"PEAR/PackageFile/v2.php";s:4:"role";s:3:"php";s:12:"installed_as";s:53:"/opt/alt/php56/usr/share/pear/PEAR/PackageFile/v2.php";}s:16:"PEAR/REST/10.php";a:4:{s:6:"md5sum";s:32:"ce77cc6593d8d4eda5ff8620ff09d6ec";s:4:"name";s:16:"PEAR/REST/10.php";s:4:"role";s:3:"php";s:12:"installed_as";s:46:"/opt/alt/php56/usr/share/pear/PEAR/REST/10.php";}s:16:"PEAR/REST/11.php";a:4:{s:6:"md5sum";s:32:"bdbd1f2e8afa2cddddecf2687579d316";s:4:"name";s:16:"PEAR/REST/11.php";s:4:"role";s:3:"php";s:12:"installed_as";s:46:"/opt/alt/php56/usr/share/pear/PEAR/REST/11.php";}s:16:"PEAR/REST/13.php";a:4:{s:6:"md5sum";s:32:"11179085b6efb577d37f45cc25e42a35";s:4:"name";s:16:"PEAR/REST/13.php";s:4:"role";s:3:"php";s:12:"installed_as";s:46:"/opt/alt/php56/usr/share/pear/PEAR/REST/13.php";}s:34:"PEAR/Task/Postinstallscript/rw.php";a:4:{s:6:"md5sum";s:32:"0eb57da4993a3cfed69fe8135f10b05a";s:4:"name";s:34:"PEAR/Task/Postinstallscript/rw.php";s:4:"role";s:3:"php";s:12:"installed_as";s:64:"/opt/alt/php56/usr/share/pear/PEAR/Task/Postinstallscript/rw.php";}s:24:"PEAR/Task/Replace/rw.php";a:4:{s:6:"md5sum";s:32:"46c1bdb9a7af8628643e639ec1c3bc58";s:4:"name";s:24:"PEAR/Task/Replace/rw.php";s:4:"role";s:3:"php";s:12:"installed_as";s:54:"/opt/alt/php56/usr/share/pear/PEAR/Task/Replace/rw.php";}s:24:"PEAR/Task/Unixeol/rw.php";a:4:{s:6:"md5sum";s:32:"50e20dbde7e51bb5e11545c56482b68a";s:4:"name";s:24:"PEAR/Task/Unixeol/rw.php";s:4:"role";s:3:"php";s:12:"installed_as";s:54:"/opt/alt/php56/usr/share/pear/PEAR/Task/Unixeol/rw.php";}s:27:"PEAR/Task/Windowseol/rw.php";a:4:{s:6:"md5sum";s:32:"340be01552844adb50f6e0fa37aa3ffe";s:4:"name";s:27:"PEAR/Task/Windowseol/rw.php";s:4:"role";s:3:"php";s:12:"installed_as";s:57:"/opt/alt/php56/usr/share/pear/PEAR/Task/Windowseol/rw.php";}s:20:"PEAR/Task/Common.php";a:4:{s:6:"md5sum";s:32:"ec7f8db335ad3b5a25d78682745185d1";s:4:"name";s:20:"PEAR/Task/Common.php";s:4:"role";s:3:"php";s:12:"installed_as";s:50:"/opt/alt/php56/usr/share/pear/PEAR/Task/Common.php";}s:31:"PEAR/Task/Postinstallscript.php";a:4:{s:6:"md5sum";s:32:"86f240c600447fdb86bd38bd32c66c02";s:4:"name";s:31:"PEAR/Task/Postinstallscript.php";s:4:"role";s:3:"php";s:12:"installed_as";s:61:"/opt/alt/php56/usr/share/pear/PEAR/Task/Postinstallscript.php";}s:21:"PEAR/Task/Replace.php";a:4:{s:6:"md5sum";s:32:"c993cdedc64084a1c4b735baec048d50";s:4:"name";s:21:"PEAR/Task/Replace.php";s:4:"role";s:3:"php";s:12:"installed_as";s:51:"/opt/alt/php56/usr/share/pear/PEAR/Task/Replace.php";}s:21:"PEAR/Task/Unixeol.php";a:4:{s:6:"md5sum";s:32:"76c4ca15858c005cda208a9da1f5eb2d";s:4:"name";s:21:"PEAR/Task/Unixeol.php";s:4:"role";s:3:"php";s:12:"installed_as";s:51:"/opt/alt/php56/usr/share/pear/PEAR/Task/Unixeol.php";}s:24:"PEAR/Task/Windowseol.php";a:4:{s:6:"md5sum";s:32:"d790eb3aa5ba22a33e42cb7c5f99fb25";s:4:"name";s:24:"PEAR/Task/Windowseol.php";s:4:"role";s:3:"php";s:12:"installed_as";s:54:"/opt/alt/php56/usr/share/pear/PEAR/Task/Windowseol.php";}s:23:"PEAR/Validator/PECL.php";a:4:{s:6:"md5sum";s:32:"b3c83ca826a4825ca2db726ed7d4b245";s:4:"name";s:23:"PEAR/Validator/PECL.php";s:4:"role";s:3:"php";s:12:"installed_as";s:53:"/opt/alt/php56/usr/share/pear/PEAR/Validator/PECL.php";}s:16:"PEAR/Builder.php";a:4:{s:6:"md5sum";s:32:"7d89f25a54d100c2afd562fb3bd7c308";s:4:"name";s:16:"PEAR/Builder.php";s:4:"role";s:3:"php";s:12:"installed_as";s:46:"/opt/alt/php56/usr/share/pear/PEAR/Builder.php";}s:20:"PEAR/ChannelFile.php";a:4:{s:6:"md5sum";s:32:"edcd484ecfd400875df90ee480c5384d";s:4:"name";s:20:"PEAR/ChannelFile.php";s:4:"role";s:3:"php";s:12:"installed_as";s:50:"/opt/alt/php56/usr/share/pear/PEAR/ChannelFile.php";}s:16:"PEAR/Command.php";a:4:{s:6:"md5sum";s:32:"a5d56f9d15ff6d22c12f7db851f281e8";s:4:"name";s:16:"PEAR/Command.php";s:4:"role";s:3:"php";s:12:"installed_as";s:46:"/opt/alt/php56/usr/share/pear/PEAR/Command.php";}s:15:"PEAR/Common.php";a:4:{s:6:"md5sum";s:32:"0af44a13df74291ac2f46949d2035e0e";s:4:"name";s:15:"PEAR/Common.php";s:4:"role";s:3:"php";s:12:"installed_as";s:45:"/opt/alt/php56/usr/share/pear/PEAR/Common.php";}s:15:"PEAR/Config.php";a:4:{s:6:"md5sum";s:32:"64d0f7b2737e5f182d0ab98bc77930d2";s:4:"name";s:15:"PEAR/Config.php";s:4:"role";s:3:"php";s:12:"installed_as";s:45:"/opt/alt/php56/usr/share/pear/PEAR/Config.php";}s:21:"PEAR/DependencyDB.php";a:4:{s:6:"md5sum";s:32:"7e8dfae09802be7f2e6170062bb80cbd";s:4:"name";s:21:"PEAR/DependencyDB.php";s:4:"role";s:3:"php";s:12:"installed_as";s:51:"/opt/alt/php56/usr/share/pear/PEAR/DependencyDB.php";}s:20:"PEAR/Dependency2.php";a:4:{s:6:"md5sum";s:32:"76fdabdee883fd16b986332552b9e3dc";s:4:"name";s:20:"PEAR/Dependency2.php";s:4:"role";s:3:"php";s:12:"installed_as";s:50:"/opt/alt/php56/usr/share/pear/PEAR/Dependency2.php";}s:19:"PEAR/Downloader.php";a:4:{s:6:"md5sum";s:32:"2ccb7bb2d00eae201ee7ae1eef49ad8a";s:4:"name";s:19:"PEAR/Downloader.php";s:4:"role";s:3:"php";s:12:"installed_as";s:49:"/opt/alt/php56/usr/share/pear/PEAR/Downloader.php";}s:19:"PEAR/ErrorStack.php";a:4:{s:6:"md5sum";s:32:"ea807632b63d2e0acd6924db23aaa0eb";s:4:"name";s:19:"PEAR/ErrorStack.php";s:4:"role";s:3:"php";s:12:"installed_as";s:49:"/opt/alt/php56/usr/share/pear/PEAR/ErrorStack.php";}s:18:"PEAR/Exception.php";a:4:{s:6:"md5sum";s:32:"544ed48cab9407a936d058d09e773e22";s:4:"name";s:18:"PEAR/Exception.php";s:4:"role";s:3:"php";s:12:"installed_as";s:48:"/opt/alt/php56/usr/share/pear/PEAR/Exception.php";}s:17:"PEAR/Frontend.php";a:4:{s:6:"md5sum";s:32:"31c0b91767550adf77f1c9bea92a0559";s:4:"name";s:17:"PEAR/Frontend.php";s:4:"role";s:3:"php";s:12:"installed_as";s:47:"/opt/alt/php56/usr/share/pear/PEAR/Frontend.php";}s:18:"PEAR/Installer.php";a:4:{s:6:"md5sum";s:32:"b8b85e42b840676ad3ae1c15e55b005b";s:4:"name";s:18:"PEAR/Installer.php";s:4:"role";s:3:"php";s:12:"installed_as";s:48:"/opt/alt/php56/usr/share/pear/PEAR/Installer.php";}s:20:"PEAR/PackageFile.php";a:4:{s:6:"md5sum";s:32:"2929765413405abf63574c8a544e4a04";s:4:"name";s:20:"PEAR/PackageFile.php";s:4:"role";s:3:"php";s:12:"installed_as";s:50:"/opt/alt/php56/usr/share/pear/PEAR/PackageFile.php";}s:17:"PEAR/Packager.php";a:4:{s:6:"md5sum";s:32:"ad25a29d464b62cbaaa3ca96e622526c";s:4:"name";s:17:"PEAR/Packager.php";s:4:"role";s:3:"php";s:12:"installed_as";s:47:"/opt/alt/php56/usr/share/pear/PEAR/Packager.php";}s:14:"PEAR/Proxy.php";a:4:{s:6:"md5sum";s:32:"ef9d00adaeccff7516f08170096026d3";s:4:"name";s:14:"PEAR/Proxy.php";s:4:"role";s:3:"php";s:12:"installed_as";s:44:"/opt/alt/php56/usr/share/pear/PEAR/Proxy.php";}s:17:"PEAR/Registry.php";a:4:{s:6:"md5sum";s:32:"ae8c1dcfddb6a2717e09239bb1430dc7";s:4:"name";s:17:"PEAR/Registry.php";s:4:"role";s:3:"php";s:12:"installed_as";s:47:"/opt/alt/php56/usr/share/pear/PEAR/Registry.php";}s:13:"PEAR/REST.php";a:4:{s:6:"md5sum";s:32:"389d1bad72267d3ed770abf0662d8086";s:4:"name";s:13:"PEAR/REST.php";s:4:"role";s:3:"php";s:12:"installed_as";s:43:"/opt/alt/php56/usr/share/pear/PEAR/REST.php";}s:16:"PEAR/RunTest.php";a:4:{s:6:"md5sum";s:32:"df0d7022e22fd78ecd82080ff4f108d5";s:4:"name";s:16:"PEAR/RunTest.php";s:4:"role";s:3:"php";s:12:"installed_as";s:46:"/opt/alt/php56/usr/share/pear/PEAR/RunTest.php";}s:17:"PEAR/Validate.php";a:4:{s:6:"md5sum";s:32:"3711c281e0234203ec7879f53bc766ab";s:4:"name";s:17:"PEAR/Validate.php";s:4:"role";s:3:"php";s:12:"installed_as";s:47:"/opt/alt/php56/usr/share/pear/PEAR/Validate.php";}s:18:"PEAR/XMLParser.php";a:4:{s:6:"md5sum";s:32:"da9510087eddd489945dde07260256ee";s:4:"name";s:18:"PEAR/XMLParser.php";s:4:"role";s:3:"php";s:12:"installed_as";s:48:"/opt/alt/php56/usr/share/pear/PEAR/XMLParser.php";}s:15:"scripts/pear.sh";a:6:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"9eeacc0bf06771acea2080151a70560e";s:4:"name";s:15:"scripts/pear.sh";s:4:"role";s:6:"script";s:10:"install-as";s:4:"pear";s:12:"installed_as";s:27:"/opt/alt/php56/usr/bin/pear";}s:18:"scripts/peardev.sh";a:6:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"b10935d92bc3f7ae6d08c8fa00c95506";s:4:"name";s:18:"scripts/peardev.sh";s:4:"role";s:6:"script";s:10:"install-as";s:7:"peardev";s:12:"installed_as";s:30:"/opt/alt/php56/usr/bin/peardev";}s:15:"scripts/pecl.sh";a:6:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"bf93d87c41e1244271c9f62a6526302d";s:4:"name";s:15:"scripts/pecl.sh";s:4:"role";s:6:"script";s:10:"install-as";s:4:"pecl";s:12:"installed_as";s:27:"/opt/alt/php56/usr/bin/pecl";}s:19:"scripts/pearcmd.php";a:6:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"e9eb3e2509e8e498fbba69432e1c8f48";s:4:"name";s:19:"scripts/pearcmd.php";s:4:"role";s:3:"php";s:10:"install-as";s:11:"pearcmd.php";s:12:"installed_as";s:41:"/opt/alt/php56/usr/share/pear/pearcmd.php";}s:19:"scripts/peclcmd.php";a:6:{s:14:"baseinstalldir";s:1:"/";s:6:"md5sum";s:32:"1f1ad189da9317ce926b1f473b708823";s:4:"name";s:19:"scripts/peclcmd.php";s:4:"role";s:3:"php";s:10:"install-as";s:11:"peclcmd.php";s:12:"installed_as";s:41:"/opt/alt/php56/usr/share/pear/peclcmd.php";}s:7:"LICENSE";a:4:{s:6:"md5sum";s:32:"45b44486d8090de17b2a8b4211fab247";s:4:"name";s:7:"LICENSE";s:4:"role";s:3:"doc";s:12:"installed_as";s:46:"/opt/alt/php56/usr/share/doc/pear/PEAR/LICENSE";}s:7:"INSTALL";a:4:{s:6:"md5sum";s:32:"eaac3d33068c6e67573ed44155b149ae";s:4:"name";s:7:"INSTALL";s:4:"role";s:3:"doc";s:12:"installed_as";s:46:"/opt/alt/php56/usr/share/doc/pear/PEAR/INSTALL";}s:11:"package.dtd";a:4:{s:6:"md5sum";s:32:"69341ea97af9c88956568f8e7e41d4c6";s:4:"name";s:11:"package.dtd";s:4:"role";s:4:"data";s:12:"installed_as";s:51:"/opt/alt/php56/usr/share/pear/data/PEAR/package.dtd";}s:8:"PEAR.php";a:4:{s:6:"md5sum";s:32:"47aeb7eaff6438beb60bc42bc0e6c658";s:4:"name";s:8:"PEAR.php";s:4:"role";s:3:"php";s:12:"installed_as";s:38:"/opt/alt/php56/usr/share/pear/PEAR.php";}s:10:"README.rst";a:4:{s:6:"md5sum";s:32:"cd10521cc4054923a3d2b6e15b4df493";s:4:"name";s:10:"README.rst";s:4:"role";s:3:"doc";s:12:"installed_as";s:49:"/opt/alt/php56/usr/share/doc/pear/PEAR/README.rst";}s:10:"System.php";a:4:{s:6:"md5sum";s:32:"ba9e5c5a567e51b440808a8ed53cd76d";s:4:"name";s:10:"System.php";s:4:"role";s:3:"php";s:12:"installed_as";s:40:"/opt/alt/php56/usr/share/pear/System.php";}s:13:"template.spec";a:4:{s:6:"md5sum";s:32:"acd010e3bc43c0f72df584acde7b9158";s:4:"name";s:13:"template.spec";s:4:"role";s:4:"data";s:12:"installed_as";s:53:"/opt/alt/php56/usr/share/pear/data/PEAR/template.spec";}}s:12:"_lastversion";N;s:7:"dirtree";a:23:{s:32:"/opt/alt/php56/usr/share/pear/OS";b:1;s:46:"/opt/alt/php56/usr/share/pear/PEAR/ChannelFile";b:1;s:34:"/opt/alt/php56/usr/share/pear/PEAR";b:1;s:42:"/opt/alt/php56/usr/share/pear/PEAR/Command";b:1;s:45:"/opt/alt/php56/usr/share/pear/PEAR/Downloader";b:1;s:43:"/opt/alt/php56/usr/share/pear/PEAR/Frontend";b:1;s:49:"/opt/alt/php56/usr/share/pear/PEAR/Installer/Role";b:1;s:44:"/opt/alt/php56/usr/share/pear/PEAR/Installer";b:1;s:56:"/opt/alt/php56/usr/share/pear/PEAR/PackageFile/Generator";b:1;s:46:"/opt/alt/php56/usr/share/pear/PEAR/PackageFile";b:1;s:53:"/opt/alt/php56/usr/share/pear/PEAR/PackageFile/Parser";b:1;s:49:"/opt/alt/php56/usr/share/pear/PEAR/PackageFile/v2";b:1;s:39:"/opt/alt/php56/usr/share/pear/PEAR/REST";b:1;s:57:"/opt/alt/php56/usr/share/pear/PEAR/Task/Postinstallscript";b:1;s:39:"/opt/alt/php56/usr/share/pear/PEAR/Task";b:1;s:47:"/opt/alt/php56/usr/share/pear/PEAR/Task/Replace";b:1;s:47:"/opt/alt/php56/usr/share/pear/PEAR/Task/Unixeol";b:1;s:50:"/opt/alt/php56/usr/share/pear/PEAR/Task/Windowseol";b:1;s:44:"/opt/alt/php56/usr/share/pear/PEAR/Validator";b:1;s:22:"/opt/alt/php56/usr/bin";b:1;s:29:"/opt/alt/php56/usr/share/pear";b:1;s:38:"/opt/alt/php56/usr/share/doc/pear/PEAR";b:1;s:39:"/opt/alt/php56/usr/share/pear/data/PEAR";b:1;}s:3:"old";a:7:{s:7:"version";s:7:"1.10.16";s:12:"release_date";s:10:"2024-11-24";s:13:"release_state";s:6:"stable";s:15:"release_license";s:15:"New BSD License";s:13:"release_notes";s:164:"* PR #141: Fix bug #27796: "Array to string" conversion warnings on installs/other actions * PR #145: Never reference E_STRICT on PHP 8.4+ * PR #147: Fix tests 8.1+";s:12:"release_deps";a:8:{i:0;a:4:{s:4:"type";s:3:"php";s:3:"rel";s:2:"ge";s:7:"version";s:5:"5.4.0";s:8:"optional";s:2:"no";}i:1;a:6:{s:4:"type";s:3:"pkg";s:7:"channel";s:12:"pear.php.net";s:4:"name";s:4:"PEAR";s:3:"rel";s:2:"ge";s:7:"version";s:6:"1.10.1";s:8:"optional";s:2:"no";}i:2;a:6:{s:4:"type";s:3:"pkg";s:7:"channel";s:12:"pear.php.net";s:4:"name";s:11:"Archive_Tar";s:3:"rel";s:2:"ge";s:7:"version";s:5:"1.4.9";s:8:"optional";s:2:"no";}i:3;a:6:{s:4:"type";s:3:"pkg";s:7:"channel";s:12:"pear.php.net";s:4:"name";s:16:"Structures_Graph";s:3:"rel";s:2:"ge";s:7:"version";s:5:"1.1.0";s:8:"optional";s:2:"no";}i:4;a:6:{s:4:"type";s:3:"pkg";s:7:"channel";s:12:"pear.php.net";s:4:"name";s:14:"Console_Getopt";s:3:"rel";s:2:"ge";s:7:"version";s:5:"1.4.1";s:8:"optional";s:2:"no";}i:5;a:6:{s:4:"type";s:3:"pkg";s:7:"channel";s:12:"pear.php.net";s:4:"name";s:8:"XML_Util";s:3:"rel";s:2:"ge";s:7:"version";s:5:"1.4.0";s:8:"optional";s:2:"no";}i:6;a:4:{s:4:"type";s:3:"ext";s:4:"name";s:3:"xml";s:3:"rel";s:3:"has";s:8:"optional";s:2:"no";}i:7;a:4:{s:4:"type";s:3:"ext";s:4:"name";s:4:"pcre";s:3:"rel";s:3:"has";s:8:"optional";s:2:"no";}}s:11:"maintainers";a:11:{i:0;a:5:{s:4:"name";s:11:"Greg Beaver";s:5:"email";s:14:"cellog@php.net";s:6:"active";s:2:"no";s:6:"handle";s:6:"cellog";s:4:"role";s:4:"lead";}i:1;a:5:{s:4:"name";s:17:"Pierre-Alain Joye";s:5:"email";s:14:"pierre@php.net";s:6:"active";s:2:"no";s:6:"handle";s:6:"pajoye";s:4:"role";s:4:"lead";}i:2;a:5:{s:4:"name";s:11:"Stig Bakken";s:5:"email";s:12:"stig@php.net";s:6:"active";s:2:"no";s:6:"handle";s:3:"ssb";s:4:"role";s:4:"lead";}i:3;a:5:{s:4:"name";s:13:"Tomas V.V.Cox";s:5:"email";s:15:"cox@idecnet.com";s:6:"active";s:2:"no";s:6:"handle";s:3:"cox";s:4:"role";s:4:"lead";}i:4;a:5:{s:4:"name";s:13:"Helgi Thormar";s:5:"email";s:13:"dufuz@php.net";s:6:"active";s:2:"no";s:6:"handle";s:5:"dufuz";s:4:"role";s:4:"lead";}i:5;a:5:{s:4:"name";s:16:"Christian Weiske";s:5:"email";s:15:"cweiske@php.net";s:6:"active";s:2:"no";s:6:"handle";s:7:"cweiske";s:4:"role";s:4:"lead";}i:6;a:5:{s:4:"name";s:13:"Chuck Burgess";s:5:"email";s:15:"ashnazg@php.net";s:6:"active";s:3:"yes";s:6:"handle";s:7:"ashnazg";s:4:"role";s:4:"lead";}i:7;a:5:{s:4:"name";s:9:"Tias Guns";s:5:"email";s:12:"tias@php.net";s:6:"active";s:2:"no";s:6:"handle";s:4:"tias";s:4:"role";s:9:"developer";}i:8;a:5:{s:4:"name";s:11:"Tim Jackson";s:5:"email";s:12:"timj@php.net";s:6:"active";s:2:"no";s:6:"handle";s:4:"timj";s:4:"role";s:6:"helper";}i:9;a:5:{s:4:"name";s:15:"Bertrand Gugger";s:5:"email";s:13:"toggg@php.net";s:6:"active";s:2:"no";s:6:"handle";s:5:"toggg";s:4:"role";s:6:"helper";}i:10;a:5:{s:4:"name";s:13:"Martin Jansen";s:5:"email";s:10:"mj@php.net";s:6:"active";s:2:"no";s:6:"handle";s:2:"mj";s:4:"role";s:6:"helper";}}}s:10:"xsdversion";s:3:"2.0";s:13:"_lastmodified";i:1747068539;}PK�����u]'7,������PEAR.phpnu�[��������<?php /** * PEAR, the PHP Extension and Application Repository * * PEAR class and PEAR_Error class * * PHP versions 4 and 5 * * @category pear * @package PEAR * @author Sterling Hughes <sterling@php.net> * @author Stig Bakken <ssb@php.net> * @author Tomas V.V.Cox <cox@idecnet.com> * @author Greg Beaver <cellog@php.net> * @copyright 1997-2010 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 0.1 */ /**#@+ * ERROR constants */ define('PEAR_ERROR_RETURN', 1); define('PEAR_ERROR_PRINT', 2); define('PEAR_ERROR_TRIGGER', 4); define('PEAR_ERROR_DIE', 8); define('PEAR_ERROR_CALLBACK', 16); /** * WARNING: obsolete * @deprecated */ define('PEAR_ERROR_EXCEPTION', 32); /**#@-*/ if (substr(PHP_OS, 0, 3) == 'WIN') { define('OS_WINDOWS', true); define('OS_UNIX', false); define('PEAR_OS', 'Windows'); } else { define('OS_WINDOWS', false); define('OS_UNIX', true); define('PEAR_OS', 'Unix'); // blatant assumption } $GLOBALS['_PEAR_default_error_mode'] = PEAR_ERROR_RETURN; $GLOBALS['_PEAR_default_error_options'] = E_USER_NOTICE; $GLOBALS['_PEAR_destructor_object_list'] = array(); $GLOBALS['_PEAR_shutdown_funcs'] = array(); $GLOBALS['_PEAR_error_handler_stack'] = array(); if(function_exists('ini_set')) { @ini_set('track_errors', true); } /** * Base class for other PEAR classes. Provides rudimentary * emulation of destructors. * * If you want a destructor in your class, inherit PEAR and make a * destructor method called _yourclassname (same name as the * constructor, but with a "_" prefix). Also, in your constructor you * have to call the PEAR constructor: $this->PEAR();. * The destructor method will be called without parameters. Note that * at in some SAPI implementations (such as Apache), any output during * the request shutdown (in which destructors are called) seems to be * discarded. If you need to get any debug information from your * destructor, use error_log(), syslog() or something similar. * * IMPORTANT! To use the emulated destructors you need to create the * objects by reference: $obj =& new PEAR_child; * * @category pear * @package PEAR * @author Stig Bakken <ssb@php.net> * @author Tomas V.V. Cox <cox@idecnet.com> * @author Greg Beaver <cellog@php.net> * @copyright 1997-2006 The PHP Group * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @see PEAR_Error * @since Class available since PHP 4.0.2 * @link http://pear.php.net/manual/en/core.pear.php#core.pear.pear */ class PEAR { /** * Whether to enable internal debug messages. * * @var bool * @access private */ var $_debug = false; /** * Default error mode for this object. * * @var int * @access private */ var $_default_error_mode = null; /** * Default error options used for this object when error mode * is PEAR_ERROR_TRIGGER. * * @var int * @access private */ var $_default_error_options = null; /** * Default error handler (callback) for this object, if error mode is * PEAR_ERROR_CALLBACK. * * @var string * @access private */ var $_default_error_handler = ''; /** * Which class to use for error objects. * * @var string * @access private */ var $_error_class = 'PEAR_Error'; /** * An array of expected errors. * * @var array * @access private */ var $_expected_errors = array(); /** * List of methods that can be called both statically and non-statically. * @var array */ protected static $bivalentMethods = array( 'setErrorHandling' => true, 'raiseError' => true, 'throwError' => true, 'pushErrorHandling' => true, 'popErrorHandling' => true, ); /** * Constructor. Registers this object in * $_PEAR_destructor_object_list for destructor emulation if a * destructor object exists. * * @param string $error_class (optional) which class to use for * error objects, defaults to PEAR_Error. * @access public * @return void */ function __construct($error_class = null) { $classname = strtolower(get_class($this)); if ($this->_debug) { print "PEAR constructor called, class=$classname\n"; } if ($error_class !== null) { $this->_error_class = $error_class; } while ($classname && strcasecmp($classname, "pear")) { $destructor = "_$classname"; if (method_exists($this, $destructor)) { global $_PEAR_destructor_object_list; $_PEAR_destructor_object_list[] = $this; if (!isset($GLOBALS['_PEAR_SHUTDOWN_REGISTERED'])) { register_shutdown_function("_PEAR_call_destructors"); $GLOBALS['_PEAR_SHUTDOWN_REGISTERED'] = true; } break; } else { $classname = get_parent_class($classname); } } } /** * Only here for backwards compatibility. * E.g. Archive_Tar calls $this->PEAR() in its constructor. * * @param string $error_class Which class to use for error objects, * defaults to PEAR_Error. */ public function PEAR($error_class = null) { self::__construct($error_class); } /** * Destructor (the emulated type of...). Does nothing right now, * but is included for forward compatibility, so subclass * destructors should always call it. * * See the note in the class desciption about output from * destructors. * * @access public * @return void */ function _PEAR() { if ($this->_debug) { printf("PEAR destructor called, class=%s\n", strtolower(get_class($this))); } } public function __call($method, $arguments) { if (!isset(self::$bivalentMethods[$method])) { trigger_error( 'Call to undefined method PEAR::' . $method . '()', E_USER_ERROR ); } return call_user_func_array( array(__CLASS__, '_' . $method), array_merge(array($this), $arguments) ); } public static function __callStatic($method, $arguments) { if (!isset(self::$bivalentMethods[$method])) { trigger_error( 'Call to undefined method PEAR::' . $method . '()', E_USER_ERROR ); } return call_user_func_array( array(__CLASS__, '_' . $method), array_merge(array(null), $arguments) ); } /** * If you have a class that's mostly/entirely static, and you need static * properties, you can use this method to simulate them. Eg. in your method(s) * do this: $myVar = &PEAR::getStaticProperty('myclass', 'myVar'); * You MUST use a reference, or they will not persist! * * @param string $class The calling classname, to prevent clashes * @param string $var The variable to retrieve. * @return mixed A reference to the variable. If not set it will be * auto initialised to NULL. */ public static function &getStaticProperty($class, $var) { static $properties; if (!isset($properties[$class])) { $properties[$class] = array(); } if (!array_key_exists($var, $properties[$class])) { $properties[$class][$var] = null; } return $properties[$class][$var]; } /** * Use this function to register a shutdown method for static * classes. * * @param mixed $func The function name (or array of class/method) to call * @param mixed $args The arguments to pass to the function * * @return void */ public static function registerShutdownFunc($func, $args = array()) { // if we are called statically, there is a potential // that no shutdown func is registered. Bug #6445 if (!isset($GLOBALS['_PEAR_SHUTDOWN_REGISTERED'])) { register_shutdown_function("_PEAR_call_destructors"); $GLOBALS['_PEAR_SHUTDOWN_REGISTERED'] = true; } $GLOBALS['_PEAR_shutdown_funcs'][] = array($func, $args); } /** * Tell whether a value is a PEAR error. * * @param mixed $data the value to test * @param int $code if $data is an error object, return true * only if $code is a string and * $obj->getMessage() == $code or * $code is an integer and $obj->getCode() == $code * * @return bool true if parameter is an error */ public static function isError($data, $code = null) { if (!is_a($data, 'PEAR_Error')) { return false; } if (is_null($code)) { return true; } elseif (is_string($code)) { return $data->getMessage() == $code; } return $data->getCode() == $code; } /** * Sets how errors generated by this object should be handled. * Can be invoked both in objects and statically. If called * statically, setErrorHandling sets the default behaviour for all * PEAR objects. If called in an object, setErrorHandling sets * the default behaviour for that object. * * @param object $object * Object the method was called on (non-static mode) * * @param int $mode * One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT, * PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE, * PEAR_ERROR_CALLBACK or PEAR_ERROR_EXCEPTION. * * @param mixed $options * When $mode is PEAR_ERROR_TRIGGER, this is the error level (one * of E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR). * * When $mode is PEAR_ERROR_CALLBACK, this parameter is expected * to be the callback function or method. A callback * function is a string with the name of the function, a * callback method is an array of two elements: the element * at index 0 is the object, and the element at index 1 is * the name of the method to call in the object. * * When $mode is PEAR_ERROR_PRINT or PEAR_ERROR_DIE, this is * a printf format string used when printing the error * message. * * @access public * @return void * @see PEAR_ERROR_RETURN * @see PEAR_ERROR_PRINT * @see PEAR_ERROR_TRIGGER * @see PEAR_ERROR_DIE * @see PEAR_ERROR_CALLBACK * @see PEAR_ERROR_EXCEPTION * * @since PHP 4.0.5 */ protected static function _setErrorHandling( $object, $mode = null, $options = null ) { if ($object !== null) { $setmode = &$object->_default_error_mode; $setoptions = &$object->_default_error_options; } else { $setmode = &$GLOBALS['_PEAR_default_error_mode']; $setoptions = &$GLOBALS['_PEAR_default_error_options']; } switch ($mode) { case PEAR_ERROR_EXCEPTION: case PEAR_ERROR_RETURN: case PEAR_ERROR_PRINT: case PEAR_ERROR_TRIGGER: case PEAR_ERROR_DIE: case null: $setmode = $mode; $setoptions = $options; break; case PEAR_ERROR_CALLBACK: $setmode = $mode; // class/object method callback if (is_callable($options)) { $setoptions = $options; } else { trigger_error("invalid error callback", E_USER_WARNING); } break; default: trigger_error("invalid error mode", E_USER_WARNING); break; } } /** * This method is used to tell which errors you expect to get. * Expected errors are always returned with error mode * PEAR_ERROR_RETURN. Expected error codes are stored in a stack, * and this method pushes a new element onto it. The list of * expected errors are in effect until they are popped off the * stack with the popExpect() method. * * Note that this method can not be called statically * * @param mixed $code a single error code or an array of error codes to expect * * @return int the new depth of the "expected errors" stack * @access public */ function expectError($code = '*') { if (is_array($code)) { array_push($this->_expected_errors, $code); } else { array_push($this->_expected_errors, array($code)); } return count($this->_expected_errors); } /** * This method pops one element off the expected error codes * stack. * * @return array the list of error codes that were popped */ function popExpect() { return array_pop($this->_expected_errors); } /** * This method checks unsets an error code if available * * @param mixed error code * @return bool true if the error code was unset, false otherwise * @access private * @since PHP 4.3.0 */ function _checkDelExpect($error_code) { $deleted = false; foreach ($this->_expected_errors as $key => $error_array) { if (in_array($error_code, $error_array)) { unset($this->_expected_errors[$key][array_search($error_code, $error_array)]); $deleted = true; } // clean up empty arrays if (0 == count($this->_expected_errors[$key])) { unset($this->_expected_errors[$key]); } } return $deleted; } /** * This method deletes all occurrences of the specified element from * the expected error codes stack. * * @param mixed $error_code error code that should be deleted * @return mixed list of error codes that were deleted or error * @access public * @since PHP 4.3.0 */ function delExpect($error_code) { $deleted = false; if ((is_array($error_code) && (0 != count($error_code)))) { // $error_code is a non-empty array here; we walk through it trying // to unset all values foreach ($error_code as $key => $error) { $deleted = $this->_checkDelExpect($error) ? true : false; } return $deleted ? true : PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME } elseif (!empty($error_code)) { // $error_code comes alone, trying to unset it if ($this->_checkDelExpect($error_code)) { return true; } return PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME } // $error_code is empty return PEAR::raiseError("The expected error you submitted is empty"); // IMPROVE ME } /** * This method is a wrapper that returns an instance of the * configured error class with this object's default error * handling applied. If the $mode and $options parameters are not * specified, the object's defaults are used. * * @param mixed $message a text error message or a PEAR error object * * @param int $code a numeric error code (it is up to your class * to define these if you want to use codes) * * @param int $mode One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT, * PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE, * PEAR_ERROR_CALLBACK, PEAR_ERROR_EXCEPTION. * * @param mixed $options If $mode is PEAR_ERROR_TRIGGER, this parameter * specifies the PHP-internal error level (one of * E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR). * If $mode is PEAR_ERROR_CALLBACK, this * parameter specifies the callback function or * method. In other error modes this parameter * is ignored. * * @param string $userinfo If you need to pass along for example debug * information, this parameter is meant for that. * * @param string $error_class The returned error object will be * instantiated from this class, if specified. * * @param bool $skipmsg If true, raiseError will only pass error codes, * the error message parameter will be dropped. * * @return object a PEAR error object * @see PEAR::setErrorHandling * @since PHP 4.0.5 */ protected static function _raiseError($object, $message = null, $code = null, $mode = null, $options = null, $userinfo = null, $error_class = null, $skipmsg = false) { // The error is yet a PEAR error object if (is_object($message)) { $code = $message->getCode(); $userinfo = $message->getUserInfo(); $error_class = $message->getType(); $message->error_message_prefix = ''; $message = $message->getMessage(); } if ( $object !== null && isset($object->_expected_errors) && count($object->_expected_errors) > 0 && count($exp = end($object->_expected_errors)) ) { if ($exp[0] === "*" || (is_int(reset($exp)) && in_array($code, $exp)) || (is_string(reset($exp)) && in_array($message, $exp)) ) { $mode = PEAR_ERROR_RETURN; } } // No mode given, try global ones if ($mode === null) { // Class error handler if ($object !== null && isset($object->_default_error_mode)) { $mode = $object->_default_error_mode; $options = $object->_default_error_options; // Global error handler } elseif (isset($GLOBALS['_PEAR_default_error_mode'])) { $mode = $GLOBALS['_PEAR_default_error_mode']; $options = $GLOBALS['_PEAR_default_error_options']; } } if ($error_class !== null) { $ec = $error_class; } elseif ($object !== null && isset($object->_error_class)) { $ec = $object->_error_class; } else { $ec = 'PEAR_Error'; } if ($skipmsg) { $a = new $ec($code, $mode, $options, $userinfo); } else { $a = new $ec($message, $code, $mode, $options, $userinfo); } return $a; } /** * Simpler form of raiseError with fewer options. In most cases * message, code and userinfo are enough. * * @param mixed $message a text error message or a PEAR error object * * @param int $code a numeric error code (it is up to your class * to define these if you want to use codes) * * @param string $userinfo If you need to pass along for example debug * information, this parameter is meant for that. * * @return object a PEAR error object * @see PEAR::raiseError */ protected static function _throwError($object, $message = null, $code = null, $userinfo = null) { if ($object !== null) { $a = $object->raiseError($message, $code, null, null, $userinfo); return $a; } $a = PEAR::raiseError($message, $code, null, null, $userinfo); return $a; } public static function staticPushErrorHandling($mode, $options = null) { $stack = &$GLOBALS['_PEAR_error_handler_stack']; $def_mode = &$GLOBALS['_PEAR_default_error_mode']; $def_options = &$GLOBALS['_PEAR_default_error_options']; $stack[] = array($def_mode, $def_options); switch ($mode) { case PEAR_ERROR_EXCEPTION: case PEAR_ERROR_RETURN: case PEAR_ERROR_PRINT: case PEAR_ERROR_TRIGGER: case PEAR_ERROR_DIE: case null: $def_mode = $mode; $def_options = $options; break; case PEAR_ERROR_CALLBACK: $def_mode = $mode; // class/object method callback if (is_callable($options)) { $def_options = $options; } else { trigger_error("invalid error callback", E_USER_WARNING); } break; default: trigger_error("invalid error mode", E_USER_WARNING); break; } $stack[] = array($mode, $options); return true; } public static function staticPopErrorHandling() { $stack = &$GLOBALS['_PEAR_error_handler_stack']; $setmode = &$GLOBALS['_PEAR_default_error_mode']; $setoptions = &$GLOBALS['_PEAR_default_error_options']; array_pop($stack); list($mode, $options) = $stack[sizeof($stack) - 1]; array_pop($stack); switch ($mode) { case PEAR_ERROR_EXCEPTION: case PEAR_ERROR_RETURN: case PEAR_ERROR_PRINT: case PEAR_ERROR_TRIGGER: case PEAR_ERROR_DIE: case null: $setmode = $mode; $setoptions = $options; break; case PEAR_ERROR_CALLBACK: $setmode = $mode; // class/object method callback if (is_callable($options)) { $setoptions = $options; } else { trigger_error("invalid error callback", E_USER_WARNING); } break; default: trigger_error("invalid error mode", E_USER_WARNING); break; } return true; } /** * Push a new error handler on top of the error handler options stack. With this * you can easily override the actual error handler for some code and restore * it later with popErrorHandling. * * @param mixed $mode (same as setErrorHandling) * @param mixed $options (same as setErrorHandling) * * @return bool Always true * * @see PEAR::setErrorHandling */ protected static function _pushErrorHandling($object, $mode, $options = null) { $stack = &$GLOBALS['_PEAR_error_handler_stack']; if ($object !== null) { $def_mode = &$object->_default_error_mode; $def_options = &$object->_default_error_options; } else { $def_mode = &$GLOBALS['_PEAR_default_error_mode']; $def_options = &$GLOBALS['_PEAR_default_error_options']; } $stack[] = array($def_mode, $def_options); if ($object !== null) { $object->setErrorHandling($mode, $options); } else { PEAR::setErrorHandling($mode, $options); } $stack[] = array($mode, $options); return true; } /** * Pop the last error handler used * * @return bool Always true * * @see PEAR::pushErrorHandling */ protected static function _popErrorHandling($object) { $stack = &$GLOBALS['_PEAR_error_handler_stack']; array_pop($stack); list($mode, $options) = $stack[sizeof($stack) - 1]; array_pop($stack); if ($object !== null) { $object->setErrorHandling($mode, $options); } else { PEAR::setErrorHandling($mode, $options); } return true; } /** * OS independent PHP extension load. Remember to take care * on the correct extension name for case sensitive OSes. * * @param string $ext The extension name * @return bool Success or not on the dl() call */ public static function loadExtension($ext) { if (extension_loaded($ext)) { return true; } // if either returns true dl() will produce a FATAL error, stop that if ( function_exists('dl') === false || ini_get('enable_dl') != 1 ) { return false; } if (OS_WINDOWS) { $suffix = '.dll'; } elseif (PHP_OS == 'HP-UX') { $suffix = '.sl'; } elseif (PHP_OS == 'AIX') { $suffix = '.a'; } elseif (PHP_OS == 'OSX') { $suffix = '.bundle'; } else { $suffix = '.so'; } return @dl('php_'.$ext.$suffix) || @dl($ext.$suffix); } /** * Get SOURCE_DATE_EPOCH environment variable * See https://reproducible-builds.org/specs/source-date-epoch/ * * @return int * @access public */ static function getSourceDateEpoch() { if ($source_date_epoch = getenv('SOURCE_DATE_EPOCH')) { if (preg_match('/^\d+$/', $source_date_epoch)) { return (int) $source_date_epoch; } else { // "If the value is malformed, the build process SHOULD exit with a non-zero error code." self::raiseError("Invalid SOURCE_DATE_EPOCH: $source_date_epoch"); exit(1); } } else { return time(); } } } function _PEAR_call_destructors() { global $_PEAR_destructor_object_list; if (is_array($_PEAR_destructor_object_list) && sizeof($_PEAR_destructor_object_list)) { reset($_PEAR_destructor_object_list); $destructLifoExists = PEAR::getStaticProperty('PEAR', 'destructlifo'); if ($destructLifoExists) { $_PEAR_destructor_object_list = array_reverse($_PEAR_destructor_object_list); } foreach ($_PEAR_destructor_object_list as $k => $objref) { $classname = get_class($objref); while ($classname) { $destructor = "_$classname"; if (method_exists($objref, $destructor)) { $objref->$destructor(); break; } else { $classname = get_parent_class($classname); } } } // Empty the object list to ensure that destructors are // not called more than once. $_PEAR_destructor_object_list = array(); } // Now call the shutdown functions if ( isset($GLOBALS['_PEAR_shutdown_funcs']) && is_array($GLOBALS['_PEAR_shutdown_funcs']) && !empty($GLOBALS['_PEAR_shutdown_funcs']) ) { foreach ($GLOBALS['_PEAR_shutdown_funcs'] as $value) { call_user_func_array($value[0], $value[1]); } } } /** * Standard PEAR error class for PHP 4 * * This class is supserseded by {@link PEAR_Exception} in PHP 5 * * @category pear * @package PEAR * @author Stig Bakken <ssb@php.net> * @author Tomas V.V. Cox <cox@idecnet.com> * @author Gregory Beaver <cellog@php.net> * @copyright 1997-2006 The PHP Group * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/manual/en/core.pear.pear-error.php * @see PEAR::raiseError(), PEAR::throwError() * @since Class available since PHP 4.0.2 */ class PEAR_Error { var $error_message_prefix = ''; var $mode = PEAR_ERROR_RETURN; var $level = E_USER_NOTICE; var $code = -1; var $message = ''; var $userinfo = ''; var $backtrace = null; var $callback = null; /** * PEAR_Error constructor * * @param string $message message * * @param int $code (optional) error code * * @param int $mode (optional) error mode, one of: PEAR_ERROR_RETURN, * PEAR_ERROR_PRINT, PEAR_ERROR_DIE, PEAR_ERROR_TRIGGER, * PEAR_ERROR_CALLBACK or PEAR_ERROR_EXCEPTION * * @param mixed $options (optional) error level, _OR_ in the case of * PEAR_ERROR_CALLBACK, the callback function or object/method * tuple. * * @param string $userinfo (optional) additional user/debug info * * @access public * */ function __construct($message = 'unknown error', $code = null, $mode = null, $options = null, $userinfo = null) { if ($mode === null) { $mode = PEAR_ERROR_RETURN; } $this->message = $message; $this->code = $code; $this->mode = $mode; $this->userinfo = $userinfo; $skiptrace = PEAR::getStaticProperty('PEAR_Error', 'skiptrace'); if (!$skiptrace) { $this->backtrace = debug_backtrace(); if (isset($this->backtrace[0]) && isset($this->backtrace[0]['object'])) { unset($this->backtrace[0]['object']); } } if ($mode & PEAR_ERROR_CALLBACK) { $this->level = E_USER_NOTICE; $this->callback = $options; } else { if ($options === null) { $options = E_USER_NOTICE; } $this->level = $options; $this->callback = null; } if ($this->mode & PEAR_ERROR_PRINT) { if (is_null($options) || is_int($options)) { $format = "%s"; } else { $format = $options; } printf($format, $this->getMessage()); } if ($this->mode & PEAR_ERROR_TRIGGER) { trigger_error($this->getMessage(), $this->level); } if ($this->mode & PEAR_ERROR_DIE) { $msg = $this->getMessage(); if (is_null($options) || is_int($options)) { $format = "%s"; if (substr($msg, -1) != "\n") { $msg .= "\n"; } } else { $format = $options; } printf($format, $msg); exit($code); } if ($this->mode & PEAR_ERROR_CALLBACK && is_callable($this->callback)) { call_user_func($this->callback, $this); } if ($this->mode & PEAR_ERROR_EXCEPTION) { trigger_error("PEAR_ERROR_EXCEPTION is obsolete, use class PEAR_Exception for exceptions", E_USER_WARNING); eval('$e = new Exception($this->message, $this->code);throw($e);'); } } /** * Only here for backwards compatibility. * * Class "Cache_Error" still uses it, among others. * * @param string $message Message * @param int $code Error code * @param int $mode Error mode * @param mixed $options See __construct() * @param string $userinfo Additional user/debug info */ public function PEAR_Error( $message = 'unknown error', $code = null, $mode = null, $options = null, $userinfo = null ) { self::__construct($message, $code, $mode, $options, $userinfo); } /** * Get the error mode from an error object. * * @return int error mode * @access public */ function getMode() { return $this->mode; } /** * Get the callback function/method from an error object. * * @return mixed callback function or object/method array * @access public */ function getCallback() { return $this->callback; } /** * Get the error message from an error object. * * @return string full error message * @access public */ function getMessage() { return ($this->error_message_prefix . $this->message); } /** * Get error code from an error object * * @return int error code * @access public */ function getCode() { return $this->code; } /** * Get the name of this error/exception. * * @return string error/exception name (type) * @access public */ function getType() { return get_class($this); } /** * Get additional user-supplied information. * * @return string user-supplied information * @access public */ function getUserInfo() { return $this->userinfo; } /** * Get additional debug information supplied by the application. * * @return string debug information * @access public */ function getDebugInfo() { return $this->getUserInfo(); } /** * Get the call backtrace from where the error was generated. * Supported with PHP 4.3.0 or newer. * * @param int $frame (optional) what frame to fetch * @return array Backtrace, or NULL if not available. * @access public */ function getBacktrace($frame = null) { if (defined('PEAR_IGNORE_BACKTRACE')) { return null; } if ($frame === null) { return $this->backtrace; } return $this->backtrace[$frame]; } function addUserInfo($info) { if (empty($this->userinfo)) { $this->userinfo = $info; } else { $this->userinfo .= " ** $info"; } } function __toString() { return $this->getMessage(); } /** * Make a string representation of this object. * * @return string a string with an object summary * @access public */ function toString() { $modes = array(); $levels = array(E_USER_NOTICE => 'notice', E_USER_WARNING => 'warning', E_USER_ERROR => 'error'); if ($this->mode & PEAR_ERROR_CALLBACK) { if (is_array($this->callback)) { $callback = (is_object($this->callback[0]) ? strtolower(get_class($this->callback[0])) : $this->callback[0]) . '::' . $this->callback[1]; } else { $callback = $this->callback; } return sprintf('[%s: message="%s" code=%d mode=callback '. 'callback=%s prefix="%s" info="%s"]', strtolower(get_class($this)), $this->message, $this->code, $callback, $this->error_message_prefix, $this->userinfo); } if ($this->mode & PEAR_ERROR_PRINT) { $modes[] = 'print'; } if ($this->mode & PEAR_ERROR_TRIGGER) { $modes[] = 'trigger'; } if ($this->mode & PEAR_ERROR_DIE) { $modes[] = 'die'; } if ($this->mode & PEAR_ERROR_RETURN) { $modes[] = 'return'; } return sprintf('[%s: message="%s" code=%d mode=%s level=%s '. 'prefix="%s" info="%s"]', strtolower(get_class($this)), $this->message, $this->code, implode("|", $modes), $levels[$this->level], $this->error_message_prefix, $this->userinfo); } } /* * Local Variables: * mode: php * tab-width: 4 * c-basic-offset: 4 * End: */ PK�����u]0AC5��C5����Console/Getopt.phpnu�[��������<?php /* vim: set expandtab tabstop=4 shiftwidth=4: */ /** * PHP Version 5 * * Copyright (c) 2001-2015, The PEAR developers * * This source file is subject to the BSD-2-Clause license, * that is bundled with this package in the file LICENSE, and is * available through the world-wide-web at the following url: * http://opensource.org/licenses/bsd-license.php. * * @category Console * @package Console_Getopt * @author Andrei Zmievski <andrei@php.net> * @license http://opensource.org/licenses/bsd-license.php BSD-2-Clause * @version CVS: $Id$ * @link http://pear.php.net/package/Console_Getopt */ require_once 'PEAR.php'; /** * Command-line options parsing class. * * @category Console * @package Console_Getopt * @author Andrei Zmievski <andrei@php.net> * @license http://opensource.org/licenses/bsd-license.php BSD-2-Clause * @link http://pear.php.net/package/Console_Getopt */ class Console_Getopt { /** * Parses the command-line options. * * The first parameter to this function should be the list of command-line * arguments without the leading reference to the running program. * * The second parameter is a string of allowed short options. Each of the * option letters can be followed by a colon ':' to specify that the option * requires an argument, or a double colon '::' to specify that the option * takes an optional argument. * * The third argument is an optional array of allowed long options. The * leading '--' should not be included in the option name. Options that * require an argument should be followed by '=', and options that take an * option argument should be followed by '=='. * * The return value is an array of two elements: the list of parsed * options and the list of non-option command-line arguments. Each entry in * the list of parsed options is a pair of elements - the first one * specifies the option, and the second one specifies the option argument, * if there was one. * * Long and short options can be mixed. * * Most of the semantics of this function are based on GNU getopt_long(). * * @param array $args an array of command-line arguments * @param string $short_options specifies the list of allowed short options * @param array $long_options specifies the list of allowed long options * @param boolean $skip_unknown suppresses Console_Getopt: unrecognized option * * @return array two-element array containing the list of parsed options and * the non-option arguments */ public static function getopt2($args, $short_options, $long_options = null, $skip_unknown = false) { return Console_Getopt::doGetopt(2, $args, $short_options, $long_options, $skip_unknown); } /** * This function expects $args to start with the script name (POSIX-style). * Preserved for backwards compatibility. * * @param array $args an array of command-line arguments * @param string $short_options specifies the list of allowed short options * @param array $long_options specifies the list of allowed long options * * @see getopt2() * @return array two-element array containing the list of parsed options and * the non-option arguments */ public static function getopt($args, $short_options, $long_options = null, $skip_unknown = false) { return Console_Getopt::doGetopt(1, $args, $short_options, $long_options, $skip_unknown); } /** * The actual implementation of the argument parsing code. * * @param int $version Version to use * @param array $args an array of command-line arguments * @param string $short_options specifies the list of allowed short options * @param array $long_options specifies the list of allowed long options * @param boolean $skip_unknown suppresses Console_Getopt: unrecognized option * * @return array */ public static function doGetopt($version, $args, $short_options, $long_options = null, $skip_unknown = false) { // in case you pass directly readPHPArgv() as the first arg if (PEAR::isError($args)) { return $args; } if (empty($args)) { return array(array(), array()); } $non_opts = $opts = array(); settype($args, 'array'); if ($long_options) { sort($long_options); } /* * Preserve backwards compatibility with callers that relied on * erroneous POSIX fix. */ if ($version < 2) { if (isset($args[0][0]) && $args[0][0] != '-') { array_shift($args); } } for ($i = 0; $i < count($args); $i++) { $arg = $args[$i]; /* The special element '--' means explicit end of options. Treat the rest of the arguments as non-options and end the loop. */ if ($arg == '--') { $non_opts = array_merge($non_opts, array_slice($args, $i + 1)); break; } if ($arg[0] != '-' || (strlen($arg) > 1 && $arg[1] == '-' && !$long_options)) { $non_opts = array_merge($non_opts, array_slice($args, $i)); break; } elseif (strlen($arg) > 1 && $arg[1] == '-') { $error = Console_Getopt::_parseLongOption(substr($arg, 2), $long_options, $opts, $i, $args, $skip_unknown); if (PEAR::isError($error)) { return $error; } } elseif ($arg == '-') { // - is stdin $non_opts = array_merge($non_opts, array_slice($args, $i)); break; } else { $error = Console_Getopt::_parseShortOption(substr($arg, 1), $short_options, $opts, $i, $args, $skip_unknown); if (PEAR::isError($error)) { return $error; } } } return array($opts, $non_opts); } /** * Parse short option * * @param string $arg Argument * @param string[] $short_options Available short options * @param string[][] &$opts * @param int &$argIdx * @param string[] $args * @param boolean $skip_unknown suppresses Console_Getopt: unrecognized option * * @return void */ protected static function _parseShortOption($arg, $short_options, &$opts, &$argIdx, $args, $skip_unknown) { for ($i = 0; $i < strlen($arg); $i++) { $opt = $arg[$i]; $opt_arg = null; /* Try to find the short option in the specifier string. */ if (($spec = strstr($short_options, $opt)) === false || $arg[$i] == ':') { if ($skip_unknown === true) { break; } $msg = "Console_Getopt: unrecognized option -- $opt"; return PEAR::raiseError($msg); } if (strlen($spec) > 1 && $spec[1] == ':') { if (strlen($spec) > 2 && $spec[2] == ':') { if ($i + 1 < strlen($arg)) { /* Option takes an optional argument. Use the remainder of the arg string if there is anything left. */ $opts[] = array($opt, substr($arg, $i + 1)); break; } } else { /* Option requires an argument. Use the remainder of the arg string if there is anything left. */ if ($i + 1 < strlen($arg)) { $opts[] = array($opt, substr($arg, $i + 1)); break; } else if (isset($args[++$argIdx])) { $opt_arg = $args[$argIdx]; /* Else use the next argument. */; if (Console_Getopt::_isShortOpt($opt_arg) || Console_Getopt::_isLongOpt($opt_arg)) { $msg = "option requires an argument --$opt"; return PEAR::raiseError("Console_Getopt: " . $msg); } } else { $msg = "option requires an argument --$opt"; return PEAR::raiseError("Console_Getopt: " . $msg); } } } $opts[] = array($opt, $opt_arg); } } /** * Checks if an argument is a short option * * @param string $arg Argument to check * * @return bool */ protected static function _isShortOpt($arg) { return strlen($arg) == 2 && $arg[0] == '-' && preg_match('/[a-zA-Z]/', $arg[1]); } /** * Checks if an argument is a long option * * @param string $arg Argument to check * * @return bool */ protected static function _isLongOpt($arg) { return strlen($arg) > 2 && $arg[0] == '-' && $arg[1] == '-' && preg_match('/[a-zA-Z]+$/', substr($arg, 2)); } /** * Parse long option * * @param string $arg Argument * @param string[] $long_options Available long options * @param string[][] &$opts * @param int &$argIdx * @param string[] $args * * @return void|PEAR_Error */ protected static function _parseLongOption($arg, $long_options, &$opts, &$argIdx, $args, $skip_unknown) { @list($opt, $opt_arg) = explode('=', $arg, 2); $opt_len = strlen($opt); for ($i = 0; $i < count($long_options); $i++) { $long_opt = $long_options[$i]; $opt_start = substr($long_opt, 0, $opt_len); $long_opt_name = str_replace('=', '', $long_opt); /* Option doesn't match. Go on to the next one. */ if ($long_opt_name != $opt) { continue; } $opt_rest = substr($long_opt, $opt_len); /* Check that the options uniquely matches one of the allowed options. */ if ($i + 1 < count($long_options)) { $next_option_rest = substr($long_options[$i + 1], $opt_len); } else { $next_option_rest = ''; } if ($opt_rest != '' && $opt[0] != '=' && $i + 1 < count($long_options) && $opt == substr($long_options[$i+1], 0, $opt_len) && $next_option_rest != '' && $next_option_rest[0] != '=') { $msg = "Console_Getopt: option --$opt is ambiguous"; return PEAR::raiseError($msg); } if (substr($long_opt, -1) == '=') { if (substr($long_opt, -2) != '==') { /* Long option requires an argument. Take the next argument if one wasn't specified. */; if (!strlen($opt_arg)) { if (!isset($args[++$argIdx])) { $msg = "Console_Getopt: option requires an argument --$opt"; return PEAR::raiseError($msg); } $opt_arg = $args[$argIdx]; } if (Console_Getopt::_isShortOpt($opt_arg) || Console_Getopt::_isLongOpt($opt_arg)) { $msg = "Console_Getopt: option requires an argument --$opt"; return PEAR::raiseError($msg); } } } else if ($opt_arg) { $msg = "Console_Getopt: option --$opt doesn't allow an argument"; return PEAR::raiseError($msg); } $opts[] = array('--' . $opt, $opt_arg); return; } if ($skip_unknown === true) { return; } return PEAR::raiseError("Console_Getopt: unrecognized option --$opt"); } /** * Safely read the $argv PHP array across different PHP configurations. * Will take care on register_globals and register_argc_argv ini directives * * @return mixed the $argv PHP array or PEAR error if not registered */ public static function readPHPArgv() { global $argv; if (!is_array($argv)) { if (!@is_array($_SERVER['argv'])) { if (!@is_array($GLOBALS['HTTP_SERVER_VARS']['argv'])) { $msg = "Could not read cmd args (register_argc_argv=Off?)"; return PEAR::raiseError("Console_Getopt: " . $msg); } return $GLOBALS['HTTP_SERVER_VARS']['argv']; } return $_SERVER['argv']; } return $argv; } } PK�����u]��������������.locknu�[��������PK�����u]������������ ��.depdblocknu�[��������PK�����u]C +�� +����Structures/Graph/Node.phpnu�[��������<?php /* vim: set expandtab tabstop=4 shiftwidth=4 foldmethod=marker: */ // +-----------------------------------------------------------------------------+ // | Copyright (c) 2003 Srgio Gonalves Carvalho | // +-----------------------------------------------------------------------------+ // | This file is part of Structures_Graph. | // | | // | Structures_Graph is free software; you can redistribute it and/or modify | // | it under the terms of the GNU Lesser General Public License as published by | // | the Free Software Foundation; either version 2.1 of the License, or | // | (at your option) any later version. | // | | // | Structures_Graph is distributed in the hope that it will be useful, | // | but WITHOUT ANY WARRANTY; without even the implied warranty of | // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | // | GNU Lesser General Public License for more details. | // | | // | You should have received a copy of the GNU Lesser General Public License | // | along with Structures_Graph; if not, write to the Free Software | // | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | // | 02111-1307 USA | // +-----------------------------------------------------------------------------+ // | Author: Srgio Carvalho <sergio.carvalho@portugalmail.com> | // +-----------------------------------------------------------------------------+ // /** * This file contains the definition of the Structures_Graph_Node class * * @see Structures_Graph_Node * @package Structures_Graph */ /* dependencies {{{ */ /** */ require_once 'PEAR.php'; /** */ require_once 'Structures/Graph.php'; /* }}} */ /* class Structures_Graph_Node {{{ */ /** * The Structures_Graph_Node class represents a Node that can be member of a * graph node set. * * A graph node can contain data. Under this API, the node contains default data, * and key index data. It behaves, thus, both as a regular data node, and as a * dictionary (or associative array) node. * * Regular data is accessed via getData and setData. Key indexed data is accessed * via getMetadata and setMetadata. * * @author Srgio Carvalho <sergio.carvalho@portugalmail.com> * @copyright (c) 2004 by Srgio Carvalho * @package Structures_Graph */ /* }}} */ class Structures_Graph_Node { /* fields {{{ */ /** * @access private */ var $_data = null; /** @access private */ var $_metadata = array(); /** @access private */ var $_arcs = array(); /** @access private */ var $_graph = null; /* }}} */ /* Constructor {{{ */ /** * * Constructor * * @access public */ function __construct() { } /* }}} */ /* getGraph {{{ */ /** * * Node graph getter * * @return Structures_Graph Graph where node is stored * @access public */ function &getGraph() { return $this->_graph; } /* }}} */ /* setGraph {{{ */ /** * * Node graph setter. This method should not be called directly. Use Graph::addNode instead. * * @param Structures_Graph Set the graph for this node. * @see Structures_Graph::addNode() * @access public */ function setGraph(&$graph) { $this->_graph =& $graph; } /* }}} */ /* getData {{{ */ /** * * Node data getter. * * Each graph node can contain a reference to one variable. This is the getter for that reference. * * @return mixed Data stored in node * @access public */ function &getData() { return $this->_data; } /* }}} */ /* setData {{{ */ /** * * Node data setter * * Each graph node can contain a reference to one variable. This is the setter for that reference. * * @return mixed Data to store in node * @access public */ function setData(&$data) { $this->_data =& $data; } /* }}} */ /* metadataKeyExists {{{ */ /** * * Test for existence of metadata under a given key. * * Each graph node can contain multiple 'metadata' entries, each stored under a different key, as in an * associative array or in a dictionary. This method tests whether a given metadata key exists for this node. * * @param string Key to test * @return boolean * @access public */ function metadataKeyExists($key) { return array_key_exists($key, $this->_metadata); } /* }}} */ /* getMetadata {{{ */ /** * * Node metadata getter * * Each graph node can contain multiple 'metadata' entries, each stored under a different key, as in an * associative array or in a dictionary. This method gets the data under the given key. If the key does * not exist, an error will be thrown, so testing using metadataKeyExists might be needed. * * @param string Key * @param boolean nullIfNonexistent (defaults to false). * @return mixed Metadata Data stored in node under given key * @see metadataKeyExists * @access public */ function &getMetadata($key, $nullIfNonexistent = false) { if (array_key_exists($key, $this->_metadata)) { return $this->_metadata[$key]; } else { if ($nullIfNonexistent) { $a = null; return $a; } else { $a = Pear::raiseError('Structures_Graph_Node::getMetadata: Requested key does not exist', STRUCTURES_GRAPH_ERROR_GENERIC); return $a; } } } /* }}} */ /* unsetMetadata {{{ */ /** * * Delete metadata by key * * Each graph node can contain multiple 'metadata' entries, each stored under a different key, as in an * associative array or in a dictionary. This method removes any data that might be stored under the provided key. * If the key does not exist, no error is thrown, so it is safe using this method without testing for key existence. * * @param string Key * @access public */ function unsetMetadata($key) { if (array_key_exists($key, $this->_metadata)) unset($this->_metadata[$key]); } /* }}} */ /* setMetadata {{{ */ /** * * Node metadata setter * * Each graph node can contain multiple 'metadata' entries, each stored under a different key, as in an * associative array or in a dictionary. This method stores data under the given key. If the key already exists, * previously stored data is discarded. * * @param string Key * @param mixed Data * @access public */ function setMetadata($key, &$data) { $this->_metadata[$key] =& $data; } /* }}} */ /* _connectTo {{{ */ /** @access private */ function _connectTo(&$destinationNode) { $this->_arcs[] =& $destinationNode; } /* }}} */ /* connectTo {{{ */ /** * * Connect this node to another one. * * If the graph is not directed, the reverse arc, connecting $destinationNode to $this is also created. * * @param Structures_Graph_Node Node to connect to * @access public */ function connectTo(&$destinationNode) { // We only connect to nodes if (!is_a($destinationNode, 'Structures_Graph_Node')) return Pear::raiseError('Structures_Graph_Node::connectTo received an object that is not a Structures_Graph_Node', STRUCTURES_GRAPH_ERROR_GENERIC); // Nodes must already be in graphs to be connected if ($this->_graph == null) return Pear::raiseError('Structures_Graph_Node::connectTo Tried to connect a node that is not in a graph', STRUCTURES_GRAPH_ERROR_GENERIC); if ($destinationNode->getGraph() == null) return Pear::raiseError('Structures_Graph_Node::connectTo Tried to connect to a node that is not in a graph', STRUCTURES_GRAPH_ERROR_GENERIC); // Connect here $this->_connectTo($destinationNode); // If graph is undirected, connect back if (!$this->_graph->isDirected()) { $destinationNode->_connectTo($this); } } /* }}} */ /* getNeighbours {{{ */ /** * * Return nodes connected to this one. * * @return array Array of nodes * @access public */ function getNeighbours() { return $this->_arcs; } /* }}} */ /* connectsTo {{{ */ /** * * Test wether this node has an arc to the target node * * @return boolean True if the two nodes are connected * @access public */ function connectsTo(&$target) { if (version_compare(PHP_VERSION, '5.0.0') >= 0) { return in_array($target, $this->getNeighbours(), true); } $copy = $target; $arcKeys = array_keys($this->_arcs); foreach($arcKeys as $key) { /* ZE1 chokes on this expression: if ($target === $arc) return true; so, we'll use more convoluted stuff */ $arc =& $this->_arcs[$key]; $target = true; if ($arc === true) { $target = false; if ($arc === false) { $target = $copy; return true; } } } $target = $copy; return false; } /* }}} */ /* inDegree {{{ */ /** * * Calculate the in degree of the node. * * The indegree for a node is the number of arcs entering the node. For non directed graphs, * the indegree is equal to the outdegree. * * @return integer In degree of the node * @access public */ function inDegree() { if ($this->_graph == null) return 0; if (!$this->_graph->isDirected()) return $this->outDegree(); $result = 0; $graphNodes =& $this->_graph->getNodes(); foreach (array_keys($graphNodes) as $key) { if ($graphNodes[$key]->connectsTo($this)) $result++; } return $result; } /* }}} */ /* outDegree {{{ */ /** * * Calculate the out degree of the node. * * The outdegree for a node is the number of arcs exiting the node. For non directed graphs, * the outdegree is always equal to the indegree. * * @return integer Out degree of the node * @access public */ function outDegree() { if ($this->_graph == null) return 0; return sizeof($this->_arcs); } /* }}} */ } ?> PK�����u]~(ht��t��2��Structures/Graph/Manipulator/TopologicalSorter.phpnu�[��������<?php /* vim: set expandtab tabstop=4 shiftwidth=4 foldmethod=marker: */ // +-----------------------------------------------------------------------------+ // | Copyright (c) 2003 Srgio Gonalves Carvalho | // +-----------------------------------------------------------------------------+ // | This file is part of Structures_Graph. | // | | // | Structures_Graph is free software; you can redistribute it and/or modify | // | it under the terms of the GNU Lesser General Public License as published by | // | the Free Software Foundation; either version 2.1 of the License, or | // | (at your option) any later version. | // | | // | Structures_Graph is distributed in the hope that it will be useful, | // | but WITHOUT ANY WARRANTY; without even the implied warranty of | // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | // | GNU Lesser General Public License for more details. | // | | // | You should have received a copy of the GNU Lesser General Public License | // | along with Structures_Graph; if not, write to the Free Software | // | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | // | 02111-1307 USA | // +-----------------------------------------------------------------------------+ // | Author: Srgio Carvalho <sergio.carvalho@portugalmail.com> | // +-----------------------------------------------------------------------------+ // /** * This file contains the definition of the Structures_Graph_Manipulator_TopologicalSorter class. * * @package Structures_Graph */ require_once 'PEAR.php'; require_once 'Structures/Graph.php'; require_once 'Structures/Graph/Node.php'; require_once 'Structures/Graph/Manipulator/AcyclicTest.php'; /** * The Structures_Graph_Manipulator_TopologicalSorter is a manipulator * which is able to return the set of nodes in a graph, sorted by topological * order. * * A graph may only be sorted topologically iff it's a DAG. You can test it * with the Structures_Graph_Manipulator_AcyclicTest. * * @author Srgio Carvalho <sergio.carvalho@portugalmail.com> * @copyright (c) 2004 by Srgio Carvalho * @see Structures_Graph_Manipulator_AcyclicTest * @package Structures_Graph */ class Structures_Graph_Manipulator_TopologicalSorter { /** * This is a variant of Structures_Graph::inDegree which does * not count nodes marked as visited. * * @param object $node Node to check * * @return integer Number of non-visited nodes that link to this one */ protected static function _nonVisitedInDegree(&$node) { $result = 0; $graphNodes =& $node->_graph->getNodes(); foreach (array_keys($graphNodes) as $key) { if ((!$graphNodes[$key]->getMetadata('topological-sort-visited')) && $graphNodes[$key]->connectsTo($node) ) { $result++; } } return $result; } /** * Sort implementation * * @param object $graph Graph to sort * * @return void */ protected static function _sort(&$graph) { // Mark every node as not visited $nodes =& $graph->getNodes(); $nodeKeys = array_keys($nodes); $refGenerator = array(); foreach ($nodeKeys as $key) { $refGenerator[] = false; $nodes[$key]->setMetadata( 'topological-sort-visited', $refGenerator[sizeof($refGenerator) - 1] ); } // Iteratively peel off leaf nodes $topologicalLevel = 0; do { // Find out which nodes are leafs (excluding visited nodes) $leafNodes = array(); foreach ($nodeKeys as $key) { if ((!$nodes[$key]->getMetadata('topological-sort-visited')) && static::_nonVisitedInDegree($nodes[$key]) == 0 ) { $leafNodes[] =& $nodes[$key]; } } // Mark leafs as visited $refGenerator[] = $topologicalLevel; for ($i = sizeof($leafNodes) - 1; $i>=0; $i--) { $visited =& $leafNodes[$i]->getMetadata('topological-sort-visited'); $visited = true; $leafNodes[$i]->setMetadata('topological-sort-visited', $visited); $leafNodes[$i]->setMetadata( 'topological-sort-level', $refGenerator[sizeof($refGenerator) - 1] ); } $topologicalLevel++; } while (sizeof($leafNodes) > 0); // Cleanup visited marks foreach ($nodeKeys as $key) { $nodes[$key]->unsetMetadata('topological-sort-visited'); } } /** * Sort returns the graph's nodes, sorted by topological order. * * The result is an array with as many entries as topological levels. * Each entry in this array is an array of nodes within * the given topological level. * * @param object $graph Graph to sort * * @return array The graph's nodes, sorted by topological order. */ public static function sort(&$graph) { // We only sort graphs if (!is_a($graph, 'Structures_Graph')) { return Pear::raiseError( 'Structures_Graph_Manipulator_TopologicalSorter::sort received' . ' an object that is not a Structures_Graph', STRUCTURES_GRAPH_ERROR_GENERIC ); } if (!Structures_Graph_Manipulator_AcyclicTest::isAcyclic($graph)) { return Pear::raiseError( 'Structures_Graph_Manipulator_TopologicalSorter::sort' . ' received an graph that has cycles', STRUCTURES_GRAPH_ERROR_GENERIC ); } Structures_Graph_Manipulator_TopologicalSorter::_sort($graph); $result = array(); // Fill out result array $nodes =& $graph->getNodes(); $nodeKeys = array_keys($nodes); foreach ($nodeKeys as $key) { if (!array_key_exists($nodes[$key]->getMetadata('topological-sort-level'), $result)) { $result[$nodes[$key]->getMetadata('topological-sort-level')] = array(); } $result[$nodes[$key]->getMetadata('topological-sort-level')][] =& $nodes[$key]; $nodes[$key]->unsetMetadata('topological-sort-level'); } return $result; } } ?> PK�����u]9����,��Structures/Graph/Manipulator/AcyclicTest.phpnu�[��������<?php /* vim: set expandtab tabstop=4 shiftwidth=4 foldmethod=marker: */ // +-----------------------------------------------------------------------------+ // | Copyright (c) 2003 Srgio Gonalves Carvalho | // +-----------------------------------------------------------------------------+ // | This file is part of Structures_Graph. | // | | // | Structures_Graph is free software; you can redistribute it and/or modify | // | it under the terms of the GNU Lesser General Public License as published by | // | the Free Software Foundation; either version 2.1 of the License, or | // | (at your option) any later version. | // | | // | Structures_Graph is distributed in the hope that it will be useful, | // | but WITHOUT ANY WARRANTY; without even the implied warranty of | // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | // | GNU Lesser General Public License for more details. | // | | // | You should have received a copy of the GNU Lesser General Public License | // | along with Structures_Graph; if not, write to the Free Software | // | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | // | 02111-1307 USA | // +-----------------------------------------------------------------------------+ // | Author: Srgio Carvalho <sergio.carvalho@portugalmail.com> | // +-----------------------------------------------------------------------------+ // /** * This file contains the definition of the Structures_Graph_Manipulator_AcyclicTest graph manipulator. * * @see Structures_Graph_Manipulator_AcyclicTest * @package Structures_Graph */ /* dependencies {{{ */ /** */ require_once 'PEAR.php'; /** */ require_once 'Structures/Graph.php'; /** */ require_once 'Structures/Graph/Node.php'; /* }}} */ /* class Structures_Graph_Manipulator_AcyclicTest {{{ */ /** * The Structures_Graph_Manipulator_AcyclicTest is a graph manipulator * which tests whether a graph contains a cycle. * * The definition of an acyclic graph used in this manipulator is that of a * DAG. The graph must be directed, or else it is considered cyclic, even when * there are no arcs. * * @author Srgio Carvalho <sergio.carvalho@portugalmail.com> * @copyright (c) 2004 by Srgio Carvalho * @package Structures_Graph */ class Structures_Graph_Manipulator_AcyclicTest { /* _nonVisitedInDegree {{{ */ /** * * This is a variant of Structures_Graph::inDegree which does * not count nodes marked as visited. * * @return integer Number of non-visited nodes that link to this one */ protected static function _nonVisitedInDegree(&$node) { $result = 0; $graphNodes =& $node->_graph->getNodes(); foreach (array_keys($graphNodes) as $key) { if ((!$graphNodes[$key]->getMetadata('acyclic-test-visited')) && $graphNodes[$key]->connectsTo($node)) $result++; } return $result; } /* }}} */ /* _isAcyclic {{{ */ /** * Check if the graph is acyclic */ protected static function _isAcyclic(&$graph) { // Mark every node as not visited $nodes =& $graph->getNodes(); $nodeKeys = array_keys($nodes); $refGenerator = array(); foreach($nodeKeys as $key) { $refGenerator[] = false; $nodes[$key]->setMetadata('acyclic-test-visited', $refGenerator[sizeof($refGenerator) - 1]); } // Iteratively peel off leaf nodes do { // Find out which nodes are leafs (excluding visited nodes) $leafNodes = array(); foreach($nodeKeys as $key) { if ((!$nodes[$key]->getMetadata('acyclic-test-visited')) && Structures_Graph_Manipulator_AcyclicTest::_nonVisitedInDegree($nodes[$key]) == 0) { $leafNodes[] =& $nodes[$key]; } } // Mark leafs as visited for ($i=sizeof($leafNodes) - 1; $i>=0; $i--) { $visited =& $leafNodes[$i]->getMetadata('acyclic-test-visited'); $visited = true; $leafNodes[$i]->setMetadata('acyclic-test-visited', $visited); } } while (sizeof($leafNodes) > 0); // If graph is a DAG, there should be no non-visited nodes. Let's try to prove otherwise $result = true; foreach($nodeKeys as $key) if (!$nodes[$key]->getMetadata('acyclic-test-visited')) $result = false; // Cleanup visited marks foreach($nodeKeys as $key) $nodes[$key]->unsetMetadata('acyclic-test-visited'); return $result; } /* }}} */ /* isAcyclic {{{ */ /** * * isAcyclic returns true if a graph contains no cycles, false otherwise. * * @return boolean true iff graph is acyclic */ public static function isAcyclic(&$graph) { // We only test graphs if (!is_a($graph, 'Structures_Graph')) return Pear::raiseError('Structures_Graph_Manipulator_AcyclicTest::isAcyclic received an object that is not a Structures_Graph', STRUCTURES_GRAPH_ERROR_GENERIC); if (!$graph->isDirected()) return false; // Only directed graphs may be acyclic return Structures_Graph_Manipulator_AcyclicTest::_isAcyclic($graph); } /* }}} */ } /* }}} */ ?> PK�����u]Uyv������Structures/Graph.phpnu�[��������<?php /* vim: set expandtab tabstop=4 shiftwidth=4 foldmethod=marker: */ // +-----------------------------------------------------------------------------+ // | Copyright (c) 2003 Srgio Gonalves Carvalho | // +-----------------------------------------------------------------------------+ // | This file is part of Structures_Graph. | // | | // | Structures_Graph is free software; you can redistribute it and/or modify | // | it under the terms of the GNU Lesser General Public License as published by | // | the Free Software Foundation; either version 2.1 of the License, or | // | (at your option) any later version. | // | | // | Structures_Graph is distributed in the hope that it will be useful, | // | but WITHOUT ANY WARRANTY; without even the implied warranty of | // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | // | GNU Lesser General Public License for more details. | // | | // | You should have received a copy of the GNU Lesser General Public License | // | along with Structures_Graph; if not, write to the Free Software | // | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | // | 02111-1307 USA | // +-----------------------------------------------------------------------------+ // | Author: Srgio Carvalho <sergio.carvalho@portugalmail.com> | // +-----------------------------------------------------------------------------+ // /** * The Graph.php file contains the definition of the Structures_Graph class * * @package Structures_Graph */ /* dependencies {{{ */ require_once 'PEAR.php'; require_once 'Structures/Graph/Node.php'; /* }}} */ define('STRUCTURES_GRAPH_ERROR_GENERIC', 100); /* class Structures_Graph {{{ */ /** * The Structures_Graph class represents a graph data structure. * * A Graph is a data structure composed by a set of nodes, connected by arcs. * Graphs may either be directed or undirected. In a directed graph, arcs are * directional, and can be traveled only one way. In an undirected graph, arcs * are bidirectional, and can be traveled both ways. * * @author Srgio Carvalho <sergio.carvalho@portugalmail.com> * @copyright (c) 2004 by Srgio Carvalho * @package Structures_Graph */ /* }}} */ class Structures_Graph { /** * List of node objects in this graph * @access private */ var $_nodes = array(); /** * If the graph is directed or not * @access private */ var $_directed = false; /** * Constructor * * @param boolean $directed Set to true if the graph is directed. * Set to false if it is not directed. */ public function __construct($directed = true) { $this->_directed = $directed; } /** * Old constructor (PHP4-style; kept for BC with extending classes) * * @param boolean $directed Set to true if the graph is directed. * Set to false if it is not directed. * * @return void */ public function Structures_Graph($directed = true) { $this->__construct($directed); } /** * Return true if a graph is directed * * @return boolean true if the graph is directed */ public function isDirected() { return (boolean) $this->_directed; } /** * Add a Node to the Graph * * @param Structures_Graph_Node $newNode The node to be added. * * @return void */ public function addNode(&$newNode) { // We only add nodes if (!is_a($newNode, 'Structures_Graph_Node')) { return Pear::raiseError( 'Structures_Graph::addNode received an object that is not' . ' a Structures_Graph_Node', STRUCTURES_GRAPH_ERROR_GENERIC ); } //Graphs are node *sets*, so duplicates are forbidden. // We allow nodes that are exactly equal, but disallow equal references. foreach ($this->_nodes as $key => $node) { /* ZE1 equality operators choke on the recursive cycle introduced by the _graph field in the Node object. So, we'll check references the hard way (change $this->_nodes[$key] and check if the change reflects in $node) */ $savedData = $this->_nodes[$key]; $referenceIsEqualFlag = false; $this->_nodes[$key] = true; if ($node === true) { $this->_nodes[$key] = false; if ($node === false) { $referenceIsEqualFlag = true; } } $this->_nodes[$key] = $savedData; if ($referenceIsEqualFlag) { return Pear::raiseError( 'Structures_Graph::addNode received an object that is' . ' a duplicate for this dataset', STRUCTURES_GRAPH_ERROR_GENERIC ); } } $this->_nodes[] =& $newNode; $newNode->setGraph($this); } /** * Remove a Node from the Graph * * @param Structures_Graph_Node $node The node to be removed from the graph * * @return void * @todo This is unimplemented */ public function removeNode(&$node) { } /** * Return the node set, in no particular order. * For ordered node sets, use a Graph Manipulator insted. * * @return array The set of nodes in this graph * @see Structures_Graph_Manipulator_TopologicalSorter */ public function &getNodes() { return $this->_nodes; } } ?> PK�����u]*z%-��%-�� ��Structures/LinkedList/Double.phpnu�[��������<?php /* vim: set expandtab shiftwidth=4 tabstop=4 softtabstop=4 foldmethod=marker textwidth=80: */ /** * Linked list structure * * This package implements a doubly linked list structure. Each node * (Structures_LinkedList_DoubleNode object) in the list * (Structures_LinkedList_Double) knows the previous node and the next * node in the list. Unlike an array, you can insert or delete nodes at * arbitrary points in the list. * * If your application normally traverses the linked list in a forward-only * direction, use the singly-linked list implemented by * {@link Structures_LinkedList_Single}. If, however, your application * needs to traverse the list backwards, or insert nodes into the list before * other nodes in the list, use the double-linked list implemented by * {@link Structures_LinkedList_Double} to give your application better * performance at the cost of a slightly larger memory footprint. * * Structures_LinkedList_Double implements the Iterator interface so control * structures like foreach($list as $node) and while($list->next()) work * as expected. * * To use this package, derive a child class from * Structures_LinkedList_DoubleNode and add data to the object. Then use the * Structures_LinkedList_Double class to access the nodes. * * PHP version 5 * * LICENSE: Copyright 2006 Dan Scott * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. You may obtain * a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @category Structures * @package Structures_LinkedList_Double * @author Dan Scott <dscott@laurentian.ca> * @copyright 2006 Dan Scott * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0 * @version CVS: $Id: Double.php -1 $ * @link http://pear.php.net/package/Structures_LinkedList * @example double_link_example.php * * @todo Add some actual error conditions **/ require_once 'PEAR/Exception.php'; require_once 'Single.php'; // {{{ class Structures_LinkedList_Double /** * The Structures_LinkedList_Double class represents a linked list structure * composed of {@link Structures_LinkedList_DoubleNode} objects. * * @category Structures * @package Structures_LinkedList_Double * @author Dan Scott <dscott@laurentian.ca> * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0 * @link http://pear.php.net/package/Structures_LinkedList */ class Structures_LinkedList_Double extends Structures_LinkedList_Single implements Iterator { // {{{ properties /** * Tail node of the linked list * @var Structures_LinkedList_DoubleNode */ protected $tail_node; // }}} // {{{ Constructor: function __construct() /** * Structures_LinkedList_Double constructor * * @param Structures_LinkedList_DoubleNode $root root node for the * linked list */ function __construct(Structures_LinkedList_DoubleNode $root = null) { if ($root) { $this->tail_node = $root; } else { $this->tail_node = null; } parent::__construct($root); } // }}} // {{{ Destructor: function __destruct() /** * Structures_LinkedList_Double destructor * * If we do not destroy all of the references in the linked list, * we will quickly run out of memory for large / complex structures. * */ function __destruct() { /* * Starting with root node, set last node = root_node * get next node * if next node exists: * delete last node's references to next node and previous node * make the old next node the new last node */ if (!$last_node = $this->root_node) { return; } while (($next_node = $last_node->next()) !== false) { $last_node->setNext(null); $last_node->setPrevious(null); $last_node = $next_node; } $this->current = null; $this->root_node = null; $this->tail_node = null; $last_node = null; $next_node = null; } // }}} // {{{ function end() /** * Sets the pointer for the linked list to its last node * * @return Structures_LinkedList_DoubleNode last node in the linked list */ public function end() { if ($this->tail_node) { $this->current = $this->tail_node; } else { $this->current = null; } return $this->current; } // }}} // {{{ function previous() /** * Sets the pointer for the linked list to the previous node and * returns that node * * @return Structures_LinkedList_DoubleNode previous node in the linked list */ public function previous() { if (!$this->current()->previous()) { return false; } $this->current = $this->current()->previous(); return $this->current(); } // }}} // {{{ function insertNode() /** * Inserts a {@link Structures_LinkedList_DoubleNode} object into the linked * list, based on a reference node that already exists in the list. * * @param Structures_LinkedList_DoubleNode $new_node New node to add to the list * @param Structures_LinkedList_DoubleNode $existing_node Reference position node * @param bool $before Insert new node before or after the existing node * * @return bool Success or failure **/ public function insertNode($new_node, $existing_node, $before = false) { if (!$this->root_node) { $this->__construct($new_node); } // Now add the node according to the requested mode switch ($before) { case true: $previous_node = $existing_node->previous(); if ($previous_node) { $previous_node->setNext($new_node); $new_node->setPrevious($previous_node); } else { // The existing node must be root node; make new node root $this->root_node = $new_node; $new_node->setPrevious(); } $new_node->setNext($existing_node); $existing_node->setPrevious($new_node); break; case false: $new_node->setPrevious($existing_node); $next_node = $existing_node->next(); if ($next_node) { $new_node->setNext($next_node); $next_node->setPrevious($new_node); } else { // The existing node must have been the tail node $this->tail_node = $new_node; } $existing_node->setNext($new_node); break; } return true; } // }}} // {{{ protected function getTailNode() /** * Returns the tail node of the linked list. * * This is a cheap operation for a doubly-linked list. * * @return bool Success or failure **/ protected function getTailNode() { return $this->tail_node; } // }}} // {{{ function deleteNode() /** * Deletes a {@link Structures_LinkedList_DoubleNode} from the list. * * @param Structures_LinkedList_DoubleNode $node Node to delete. * * @return null */ public function deleteNode($node) { /* If this is the root node, and there are more nodes in the list, * make the next node the new root node before deleting this node. */ if ($node === $this->root_node) { $this->root_node = $node->next(); } /* If this is the tail node, and there are more nodes in the list, * make the previous node the tail node before deleting this node */ if ($node === $this->tail_node) { $this->tail_node = $node->previous(); } /* If this is the current node, and there are other nodes in the list, * try making the previous node the current node so that next() works * as expected. * * If that fails, make the next node the current node. * * If that fails, null isn't such a bad place to be. */ if ($node === $this->current) { if ($node->previous()) { $this->current = $node->previous(); } elseif ($node->next()) { $this->current = $node->next(); } else { $this->current = null; } } $node->__destruct(); } // }}} } // }}} // {{{ class Structures_LinkedList_DoubleNode /** * The Structures_LinkedList_DoubleNode class represents a node in a * {@link Structures_LinkedList_Double} linked list structure. * * @category Structures * @package Structures_LinkedList_Double * @author Dan Scott <dscott@laurentian.ca> * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0 * @link http://pear.php.net/package/Structures_LinkedList */ class Structures_LinkedList_DoubleNode extends Structures_LinkedList_SingleNode { // {{{ properties /** * Previous node in the linked list * @var Structures_LinkedList_DoubleNode */ protected $previous; // }}} // {{{ Constructor: function __construct() /** * Structures_LinkedList_DoubleNode constructor */ public function __construct() { $this->next = null; $this->previous = null; } // }}} // {{{ Destructor: function __destruct() /** * Removes node from the list, adjusting the related nodes accordingly. * * This is a problem if the node is the root node for the list. * At this point, however, we do not have access to the list itself. Hmm. */ public function __destruct() { $next = $this->next(); $previous = $this->previous(); if ($previous && $next) { $previous->setNext($next); $next->setPrevious($previous); } elseif ($previous) { $previous->setNext(); } elseif ($next) { $next->setPrevious(); } } // }}} // {{{ function previous() /** * Return the previous node in the linked list * * @return Structures_LinkedList_DoubleNode previous node in the linked list */ public function previous() { if ($this->previous) { return $this->previous; } else { return false; } } // }}} // {{{ function setPrevious() /** * Sets the pointer for the previous node in the linked list * to the specified node * * @param Structures_LinkedList_DoubleNode $node new previous node * in the linked list * * @return Structures_LinkedList_DoubleNode new previous node in * the linked list */ public function setPrevious($node = null) { $this->previous = $node; return $this->previous; } // }}} } // }}} ?> PK�����u]p:��p:�� ��Structures/LinkedList/Single.phpnu�[��������<?php /* vim: set expandtab shiftwidth=4 tabstop=4 softtabstop=4 foldmethod=marker textwidth=80: */ /** * Linked list structure * * This package implements a singly linked list structure. Each node * (Structures_LinkedList_SingleNode object) in the list * (Structures_LinkedList_Single) knows the the next node in the list. * Unlike an array, you can insert or delete nodes at arbitrary points * in the list. * * If your application normally traverses the linked list in a forward-only * direction, use the singly-linked list implemented by * {@link Structures_LinkedList_Single}. If, however, your application * needs to traverse the list backwards, or insert nodes into the list before * other nodes in the list, use the double-linked list implemented by * {@link Structures_LinkedList_Double} to give your application better * performance at the cost of a slightly larger memory footprint. * * Structures_LinkedList_Single implements the Iterator interface so control * structures like foreach($list as $node) and while($list->next()) work * as expected. * * To use this package, derive a child class from * Structures_LinkedList_SingleNode and add data to the object. Then use the * Structures_LinkedList_Single class to access the nodes. * * PHP version 5 * * LICENSE: Copyright 2006 Dan Scott * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. You may obtain * a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @category Structures * @package Structures_LinkedList_Single * @author Dan Scott <dscott@laurentian.ca> * @copyright 2006 Dan Scott * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0 * @version CVS: $Id: Single.php -1 $ * @link http://pear.php.net/package/Structures_LinkedList_Single * @example single_link_example.php * * @todo Add some actual error conditions **/ require_once 'PEAR/Exception.php'; // {{{ class Structures_LinkedList_Single /** * The Structures_LinkedList_Single class represents a linked list structure * composed of {@link Structures_LinkedList_SingleNode} objects. * * @category Structures * @package Structures_LinkedList_Single * @author Dan Scott <dscott@laurentian.ca> * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0 * @link http://pear.php.net/package/Structures_LinkedList_Single */ class Structures_LinkedList_Single implements Iterator { // {{{ properties /** * Current node in the linked list * @var Structures_LinkedList_SingleNode */ protected $current; /** * Root node of the linked list * @var Structures_LinkedList_SingleNode */ protected $root_node; /** * The linked list contains no nodes */ const ERROR_EMPTY = -1; public static $messages = array( self::ERROR_EMPTY => 'No nodes in this linked list' ); // }}} // {{{ Constructor: function __construct() /** * Structures_LinkedList_Single constructor * * @param Structures_LinkedList_SingleNode $root root node for the * linked list */ function __construct(Structures_LinkedList_SingleNode $root = null) { if ($root) { $this->root_node = $root; $this->current = $root; } else { $this->root_node = null; $this->current = null; } } // }}} // {{{ Destructor: function __destruct() /** * Structures_LinkedList_Single destructor * * If we do not destroy all of the references in the linked list, * we will quickly run out of memory for large / complex structures. * */ function __destruct() { /* * Starting with root node, set last node = root_node * get next node * if next node exists, delete last node reference to next node */ if (!$last_node = $this->root_node) { return; } while (($next_node = $last_node->next()) !== false) { $last_node->setNext(null); $temp_node = $last_node; $last_node = $next_node; unset($temp_node); } $this->current = null; $this->root_node = null; $last_node = null; $next_node = null; } // }}} // {{{ function current() /** * Returns the current node in the linked list * * @return Structures_LinkedList_SingleNode current node in the linked list */ public function current() { return $this->current; } // }}} // {{{ function rewind() /** * Sets the pointer for the linked list to the root node * * @return Structures_LinkedList_SingleNode root node in the linked list */ public function rewind() { if ($this->root_node) { $this->current = $this->root_node; } else { $this->current = null; } return $this->current; } // }}} // {{{ function end() /** * Sets the pointer for the linked list to the root node * * @return Structures_LinkedList_SingleNode root node in the linked list */ public function end() { $this->current = $this->getTailNode(); return $this->current; } // }}} // {{{ function key() /** * Stub for Iterator interface that simply returns the current node * * @return Structures_LinkedList_SingleNode current node in the linked list */ public function key() { return $this->current; } // }}} // {{{ function valid() /** * Stub for Iterator interface that simply returns the current node * * @return Structures_LinkedList_SingleNode current node in the linked list */ public function valid() { return $this->current(); } // }}} // {{{ function next() /** * Sets the pointer for the linked list to the next node and * returns that node * * @return Structures_LinkedList_SingleNode next node in the linked list */ public function next() { if (!$this->current) { return false; } $this->current = $this->current()->next(); return $this->current; } // }}} // {{{ function previous() /** * Sets the pointer for the linked list to the previous node and * returns that node * * @return Structures_LinkedList_SingleNode previous node in the linked list */ public function previous() { if (!$this->current) { return false; } $this->current = $this->_getPreviousNode(); return $this->current; } // }}} // {{{ protected function getTailNode() /** * Returns the tail node of the linked list. * * This is an expensive operation! * * @return bool Success or failure **/ protected function getTailNode() { $tail_node = $this->root_node; while (($y = $tail_node->next()) !== false) { $tail_node = $y; } return $tail_node; } // }}} // {{{ private function _getPreviousNode() /** * Returns the node prior to the current node in the linked list. * * This is an expensive operation for a singly linked list! * * @param Structures_LinkedList_SingleNode $node (Optional) Specific node * for which we want to find the previous node * * @return Structures_LinkedList_SingleNode Previous node **/ private function _getPreviousNode($node = null) { if (!$node) { $node = $this->current; } $prior_node = $this->root_node; while (($y = $prior_node->next()) !== false) { if ($y == $node) { return $prior_node; } $prior_node = $y; } return null; } // }}} // {{{ function appendNode() /** * Adds a {@link Structures_LinkedList_SingleNode} object to the end of * the linked list. * * @param Structures_LinkedList_SingleNode $new_node New node to append * * @return bool Success or failure **/ public function appendNode(Structures_LinkedList_SingleNode $new_node) { if (!$this->root_node) { $this->__construct($new_node); return true; } // This is just a special case of insertNode() $this->insertNode($new_node, $this->getTailNode()); return true; } // }}} // {{{ function insertNode() /** * Inserts a {@link Structures_LinkedList_SingleNode} object into the linked * list, based on a reference node that already exists in the list. * * @param Structures_LinkedList_SingleNode $new_node New node to add to * the list * @param Structures_LinkedList_SingleNode $existing_node Reference * position node * @param bool $before Insert new node * before or after the existing node * * @return bool Success or failure **/ public function insertNode($new_node, $existing_node, $before = false) { if (!$this->root_node) { $this->__construct($new_node); return true; } // Now add the node according to the requested mode switch ($before) { case true: if ($existing_node === $this->root_node) { $this->root_node = $new_node; } $previous_node = $this->_getPreviousNode($existing_node); if ($previous_node) { $previous_node->setNext($new_node); } $new_node->setNext($existing_node); break; case false: $next_node = $existing_node->next(); if ($next_node) { $new_node->setNext($next_node); } $existing_node->setNext($new_node); break; } return true; } // }}} // {{{ function prependNode() /** * Adds a {@link Structures_LinkedList_SingleNode} object to the start * of the linked list. * * @param Structures_LinkedList_SingleNode $new_node Node to prepend * to the list * * @return bool Success or failure **/ public function prependNode(Structures_LinkedList_SingleNode $new_node) { if (!$this->root_node) { $this->__construct($new_node); return true; } // This is just a special case of insertNode() $this->insertNode($new_node, $this->root_node, true); return true; } // }}} // {{{ function deleteNode() /** * Deletes a {@link Structures_LinkedList_SingleNode} from the list. * * @param Structures_LinkedList_SingleNode $node Node to delete. * * @return null */ public function deleteNode($node) { /* If this is the root node, and there are more nodes in the list, * make the next node the new root node before deleting this node. */ if ($node === $this->root_node) { $this->root_node = $node->next(); } /* If this is the current node, make the next node the current node. * * If that fails, null isn't such a bad place to be. */ if ($node === $this->current) { if ($node->next()) { $this->current = $node->next(); } else { $this->current = null; } } $node->__destruct(); } // }}} } // }}} // {{{ class Structures_LinkedList_SingleNode /** * The Structures_LinkedList_SingleNode class represents a node in a * {@link Structures_LinkedList_Single} linked list structure. * * @category Structures * @package Structures_LinkedList_Single * @author Dan Scott <dscott@laurentian.ca> * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0 * @link http://pear.php.net/package/Structures_LinkedList_Single */ class Structures_LinkedList_SingleNode { // {{{ properties /** * Next node in the linked list * @var Structures_LinkedList_SingleNode */ protected $next; // }}} // {{{ Constructor: function __construct() /** * Structures_LinkedList_SingleNode constructor */ public function __construct() { $this->next = null; } // }}} // {{{ Destructor: function __destruct() /** * Removes node from the list, adjusting the related nodes accordingly. * * This is a problem if the node is the root node for the list. * At this point, however, we do not have access to the list itself. Hmm. */ public function __destruct() { } // }}} // {{{ function next() /** * Return the next node in the linked list * * @return Structures_LinkedList_SingleNode next node in the linked list */ public function next() { if ($this->next) { return $this->next; } else { return false; } } // }}} // {{{ function previous() /** * Return the previous node in the linked list * * Stub method for Structures_LinkedList_DoubleNode to override. * * @return Structures_LinkedList_SingleNode previous node in the linked list */ public function previous() { return false; } // }}} // {{{ function setNext() /** * Sets the pointer for the next node in the linked list to the * specified node * * @param Structures_LinkedList_SingleNode $node new next node in * the linked list * * @return Structures_LinkedList_SingleNode new next node in the linked list */ public function setNext($node = null) { $this->next = $node; return $this->next; } // }}} // {{{ function setPrevious() /** * Sets the pointer for the next node in the linked list to the * specified node * * Stub method for Structures_LinkedList_DoubleNode to override. * * @param Structures_LinkedList_SingleNode $node new next node in * the linked list * * @return Structures_LinkedList_SingleNode new next node in the linked list */ public function setPrevious($node = null) { return false; } // }}} } // }}} ?> PK�����u]3-��-��,��.pkgxml/Pear_Structures_LinkedList-0.2.2.xmlnu�[��������<?xml version="1.0" encoding="UTF-8"?> <package packagerversion="1.9.0" version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd"> <name>Structures_LinkedList</name> <channel>pear.php.net</channel> <summary>Implements singly and doubly-linked lists</summary> <description>A singly-linked list offers the ability to insert or delete nodes at any point within the list. A doubly-linked list also offers the ability to request previous nodes in the list.</description> <lead> <name>Dan Scott</name> <user>dbs</user> <email>dbs@php.net</email> <active>yes</active> </lead> <date>2010-08-15</date> <time>10:13:00</time> <version> <release>0.2.2</release> <api>0.2.0</api> </version> <stability> <release>beta</release> <api>beta</api> </stability> <license uri="http://apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</license> <notes> * Fix package layout </notes> <contents> <dir baseinstalldir="Structures/LinkedList" name="/"> <file baseinstalldir="/" md5sum="b7ac5a9d6d9a3eb2c3cbb1db76ad75a3" name="Structures/LinkedList/Double.php" role="php" /> <file baseinstalldir="/" md5sum="310eefdff99016e4a3282dd02d5a7efa" name="Structures/LinkedList/Single.php" role="php" /> <file baseinstalldir="Structures/LinkedList" md5sum="9b1565a45687bb631a452b152e0d3d15" name="examples/double_link_example.php" role="doc" /> <file baseinstalldir="Structures/LinkedList" md5sum="56d8c9a65cf967f09136a1b5b42fb787" name="examples/single_link_example.php" role="doc" /> <file baseinstalldir="Structures/LinkedList" md5sum="54a63c64625c0b1785d890cc0ecb6957" name="tests/LinkTester.php" role="test" /> <file baseinstalldir="Structures/LinkedList" md5sum="6138a89189609d8b0c35a69ce6995457" name="tests/SingleLinkTester.php" role="test" /> <file baseinstalldir="Structures/LinkedList" md5sum="c7a6ad89f79222cf62148893e88a0b5a" name="tests/link_001.phpt" role="test" /> <file baseinstalldir="Structures/LinkedList" md5sum="960408b3ea85cfe453f7d4b1814784ea" name="tests/link_002.phpt" role="test" /> <file baseinstalldir="Structures/LinkedList" md5sum="392d4c38523f764091433fdf19cf4943" name="tests/link_003.phpt" role="test" /> <file baseinstalldir="Structures/LinkedList" md5sum="88bfd20fe97800c4f69ec7577abd2ecd" name="tests/link_004.phpt" role="test" /> <file baseinstalldir="Structures/LinkedList" md5sum="dac8403b1df9d64e16e45e87121a74fa" name="tests/link_005.phpt" role="test" /> <file baseinstalldir="Structures/LinkedList" md5sum="bfc84666dbe64008101adadecf008677" name="tests/link_006.phpt" role="test" /> <file baseinstalldir="Structures/LinkedList" md5sum="1a7eb8c8a63ec97fdb0154214c679cfa" name="tests/link_007.phpt" role="test" /> <file baseinstalldir="Structures/LinkedList" md5sum="86f0c12acf2706a82d0d0dc625ab3608" name="tests/single_link_001.phpt" role="test" /> <file baseinstalldir="Structures/LinkedList" md5sum="19c3e9b406dffe9c315e0264e0d257f8" name="tests/single_link_002.phpt" role="test" /> <file baseinstalldir="Structures/LinkedList" md5sum="d4029576a49c41f18c35f72bdb37da7e" name="tests/single_link_003.phpt" role="test" /> <file baseinstalldir="Structures/LinkedList" md5sum="574cb63523d7716f37fad368eefc695b" name="tests/single_link_004.phpt" role="test" /> <file baseinstalldir="Structures/LinkedList" md5sum="4712a8421da2369e72ec789e0fe3993f" name="tests/single_link_005.phpt" role="test" /> <file baseinstalldir="Structures/LinkedList" md5sum="a7f31515a9a3260aa1c17e003a4c352c" name="tests/single_link_006.phpt" role="test" /> <file baseinstalldir="Structures/LinkedList" md5sum="6fe94be57c862475367ed91a7284a6b2" name="tests/single_link_007.phpt" role="test" /> <file baseinstalldir="Structures/LinkedList" md5sum="6e8edc55d5a37acbe96ed9860b8680cc" name="CHANGELOG" role="doc" /> <file baseinstalldir="Structures/LinkedList" md5sum="3b83ef96387f14655fc854ddc3c6bd57" name="LICENSE" role="doc" /> </dir> </contents> <dependencies> <required> <php> <min>5.0</min> </php> <pearinstaller> <min>1.4.0</min> </pearinstaller> </required> </dependencies> <phprelease /> </package> PK�����u]7pK��K����.pkgxml/XML_Util.xmlnu�[��������<?xml version="1.0" encoding="UTF-8"?> <package packagerversion="1.10.5" version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd"> <name>XML_Util</name> <channel>pear.php.net</channel> <summary>XML utility class</summary> <description>Selection of methods that are often needed when working with XML documents. Functionality includes creating of attribute lists from arrays, creation of tags, validation of XML names and more.</description> <lead> <name>Chuck Burgess</name> <user>ashnazg</user> <email>ashnazg@php.net</email> <active>yes</active> </lead> <lead> <name>Stephan Schmidt</name> <user>schst</user> <email>schst@php-tools.net</email> <active>no</active> </lead> <helper> <name>Davey Shafik</name> <user>davey</user> <email>davey@php.net</email> <active>no</active> </helper> <date>2020-04-19</date> <time>14:54:10</time> <version> <release>1.4.5</release> <api>1.4.0</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <license uri="http://opensource.org/licenses/bsd-license">BSD License</license> <notes> * PR #12: fix Trying to access array offset on value of type int </notes> <contents> <dir baseinstalldir="/" name="/"> <file baseinstalldir="/" md5sum="af2746028ae4395f549855a5e444ada7" name="examples/example.php" role="doc" /> <file baseinstalldir="/" md5sum="b9e52f4aa372c4067c609f49c2285b8f" name="examples/example2.php" role="doc" /> <file baseinstalldir="/" md5sum="d0af9354df0962e70e9e2215b5611b9c" name="tests/AbstractUnitTests.php" role="test" /> <file baseinstalldir="/" md5sum="57ce547d64d6e1f2986c313407deffef" name="tests/ApiVersionTests.php" role="test" /> <file baseinstalldir="/" md5sum="2d0427db94790df7ada24a744547edf5" name="tests/AttributesToStringTests.php" role="test" /> <file baseinstalldir="/" md5sum="673d1438c4718a70c5da3fe019027db4" name="tests/CollapseEmptyTagsTests.php" role="test" /> <file baseinstalldir="/" md5sum="46b981f91edd163f1cd021cfef5d1bb1" name="tests/CreateCDataSectionTests.php" role="test" /> <file baseinstalldir="/" md5sum="6aa925b879572e9b3f1885b7cdbb223b" name="tests/CreateCommentTests.php" role="test" /> <file baseinstalldir="/" md5sum="dbc083b62a020fa245fde5a7828a4806" name="tests/CreateEndElementTests.php" role="test" /> <file baseinstalldir="/" md5sum="f58e38343ecf60811c842d4cfc8194ae" name="tests/CreateStartElementTests.php" role="test" /> <file baseinstalldir="/" md5sum="9385fba272f4ebccf4c95d43d16dcff4" name="tests/CreateTagTests.php" role="test" /> <file baseinstalldir="/" md5sum="51e7ba1390e6dadc3c0be0c960bf171d" name="tests/CreateTagFromArrayTests.php" role="test" /> <file baseinstalldir="/" md5sum="6bbb54ef4cf56dc2c0b558b295de5668" name="tests/GetDocTypeDeclarationTests.php" role="test" /> <file baseinstalldir="/" md5sum="825b440b0ee8abd10b4df017c08bf15f" name="tests/GetXmlDeclarationTests.php" role="test" /> <file baseinstalldir="/" md5sum="e6783bb330f8f2ae7225f02d56f194e4" name="tests/IsValidNameTests.php" role="test" /> <file baseinstalldir="/" md5sum="b273525b905ae6d5fc53adcb3ce0b8d9" name="tests/RaiseErrorTests.php" role="test" /> <file baseinstalldir="/" md5sum="20befbef5e55639539336761a17c64f3" name="tests/ReplaceEntitiesTests.php" role="test" /> <file baseinstalldir="/" md5sum="a3ceff3302e31f90130be01c312b33b3" name="tests/ReverseEntitiesTests.php" role="test" /> <file baseinstalldir="/" md5sum="aeb95108896180ef77a7dce3c310a3b8" name="tests/SplitQualifiedNameTests.php" role="test" /> <file baseinstalldir="/" md5sum="e93010b1eff68f889fefcb006bf20b63" name="tests/Bug4950Tests.php" role="test" /> <file baseinstalldir="/" md5sum="748ffb640e13e7b960385c7e12413782" name="tests/Bug5392Tests.php" role="test" /> <file baseinstalldir="/" md5sum="01e68b66e27a6fdb197d572c67ae6bc5" name="tests/Bug18343Tests.php" role="test" /> <file baseinstalldir="/" md5sum="d945220c38344bc773b18244439bb0cc" name="tests/Bug21177Tests.php" role="test" /> <file baseinstalldir="/" md5sum="af2672bb90875c2e00f93f563bfafe70" name="tests/Bug21184Tests.php" role="test" /> <file baseinstalldir="/" md5sum="0db6fa9c169bf6904aa7e588c2325a13" name="XML/Util.php" role="php"> <tasks:replace from="@version@" to="version" type="package-info" /> </file> </dir> </contents> <dependencies> <required> <php> <min>5.4.0</min> </php> <pearinstaller> <min>1.9.0</min> </pearinstaller> <extension> <name>pcre</name> </extension> </required> </dependencies> <phprelease /> <changelog> <release> <version> <release>0.1</release> <api>0.1</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <date>2003-08-01</date> <license uri="http://www.php.net/license">PHP License</license> <notes> inital release </notes> </release> <release> <version> <release>0.1.1</release> <api>0.1.1</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <date>2003-08-02</date> <license uri="http://www.php.net/license">PHP License</license> <notes> bugfix: removed bug in createTagFromArray </notes> </release> <release> <version> <release>0.2</release> <api>0.2</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <date>2003-08-12</date> <license uri="http://www.php.net/license">PHP License</license> <notes> added XML_Util::getDocTypeDeclaration() </notes> </release> <release> <version> <release>0.2.1</release> <api>0.2.1</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <date>2003-09-05</date> <license uri="http://www.php.net/license">PHP License</license> <notes> fixed bug with zero as tag content in createTagFromArray and createTag </notes> </release> <release> <version> <release>0.3</release> <api>0.3</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <date>2003-09-12</date> <license uri="http://www.php.net/license">PHP License</license> <notes> added createStartElement() and createEndElement() </notes> </release> <release> <version> <release>0.4</release> <api>0.4</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <date>2003-09-21</date> <license uri="http://www.php.net/license">PHP License</license> <notes> added createCDataSection(), added support for CData sections in createTag* methods, fixed bug #23, fixed bug in splitQualifiedName() </notes> </release> <release> <version> <release>0.5</release> <api>0.5</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <date>2003-09-23</date> <license uri="http://www.php.net/license">PHP License</license> <notes> added support for multiline attributes in attributesToString(), createTag*() and createStartElement (requested by Yavor Shahpasov for XML_Serializer), added createComment </notes> </release> <release> <version> <release>0.5.1</release> <api>0.5.1</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <date>2003-09-26</date> <license uri="http://www.php.net/license">PHP License</license> <notes> added default namespace parameter (optional) in splitQualifiedName() (requested by Sebastian Bergmann) </notes> </release> <release> <version> <release>0.5.2</release> <api>0.5.2</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <date>2003-11-22</date> <license uri="http://www.php.net/license">PHP License</license> <notes> now creates XHTML compliant empty tags (Davey), minor whitespace fixes (Davey) </notes> </release> <release> <version> <release>0.6.0beta1</release> <api>0.6.0beta1</api> </version> <stability> <release>beta</release> <api>beta</api> </stability> <date>2004-05-24</date> <license uri="http://www.php.net/license">PHP License</license> <notes> - Fixed bug 1438 (namespaces not accepted for isValidName()) (thanks to davey) - added optional parameter to replaceEntities() to define the set of entities to replace - added optional parameter to attributesToString() to define, whether entities should be replaced (requested by Sebastian Bergmann) - allowed second parameter to XML_Util::attributesToString() to be an array containing options (easier to use, if you only need to set the last parameter) - introduced XML_Util::raiseError() to avoid the necessity of including PEAR.php, will only be included on error </notes> </release> <release> <version> <release>0.6.0</release> <api>0.6.0</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <date>2004-06-07</date> <license uri="http://www.php.net/license">PHP License</license> <notes> - Fixed bug 1438 (namespaces not accepted for isValidName()) (thanks to davey) - added optional parameter to replaceEntities() to define the set of entities to replace - added optional parameter to attributesToString() to define, whether entities should be replaced (requested by Sebastian Bergmann) - allowed second parameter to XML_Util::attributesToString() to be an array containing options (easier to use, if you only need to set the last parameter) - introduced XML_Util::raiseError() to avoid the necessity of including PEAR.php, will only be included on error </notes> </release> <release> <version> <release>0.6.1</release> <api>0.6.1</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <date>2004-10-28</date> <license uri="http://www.php.net/license">PHP License</license> <notes> - Added check for tag name (either as local part or qualified name) in createTagFromArray() (bug #1083) </notes> </release> <release> <version> <release>1.0.0</release> <api>1.0.0</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <date>2004-10-28</date> <license uri="http://www.php.net/license">PHP License</license> <notes> - Added reverseEntities() (request #2639) </notes> </release> <release> <version> <release>1.1.0</release> <api>1.1.0</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <date>2004-11-19</date> <license uri="http://www.php.net/license">PHP License</license> <notes> - Added collapseEmptyTags (patch by Sebastian Bergmann and Thomas Duffey) </notes> </release> <release> <version> <release>1.1.1</release> <api>1.1.1</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <date>2004-12-23</date> <license uri="http://www.php.net/license">PHP License</license> <notes> - fixed bug in replaceEntities() and reverseEntities() in conjunction with XML_UTIL_ENTITIES_HTML - createTag() and createTagFromArray() now accept XML_UTIL_ENTITIES_XML, XML_UTIL_ENTITIES_XML_REQUIRED, XML_UTIL_ENTITIES_HTML, XML_UTIL_ENTITIES_NONE and XML_UTIL_CDATA_SECTION as $replaceEntities parameter </notes> </release> <release> <version> <release>1.1.2</release> <api>1.1.2</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <date>2006-12-01</date> <license uri="http://www.php.net/license">PHP License</license> <notes> - fixed bug #5419: isValidName() now checks for character classes - implemented request #8196: added optional parameter to influence array sorting to createTag() createTagFromArray() and createStartElement() </notes> </release> <release> <version> <release>1.1.4</release> <api>1.1.4</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <date>2006-12-16</date> <license uri="http://www.php.net/license">PHP License</license> <notes> - Fixed bug #9561: Not allowing underscores in middle of tags </notes> </release> <release> <version> <release>1.2.0a1</release> <api>1.2.0</api> </version> <stability> <release>alpha</release> <api>alpha</api> </stability> <date>2008-05-04</date> <license uri="http://opensource.org/licenses/bsd-license">BSD License</license> <notes> Changed license to New BSD License (Req #13826 [ashnazg]) Added a test suite against all API methods [ashnazg] Switch to package.xml v2 [ashnazg] Fixed Bug #4950: Incorrect CDATA serializing [ashnazg|ja.doma] </notes> </release> <release> <version> <release>1.2.0a2</release> <api>1.2.0</api> </version> <stability> <release>alpha</release> <api>alpha</api> </stability> <date>2008-05-22</date> <license uri="http://opensource.org/licenses/bsd-license">BSD License</license> <notes> Changed license to New BSD License (Req #13826 [ashnazg]) Added a test suite against all API methods [ashnazg] Switch to package.xml v2 [ashnazg] Added Req #13839: Missing XHTML empty tags to collapse [ashnazg|drry] Fixed Bug #5392: encoding of ISO-8859-1 is the only supported encoding [ashnazg] Fixed Bug #4950: Incorrect CDATA serializing [ashnazg|drry] -- (this fix differs from the one in v1.2.0a1) </notes> </release> <release> <version> <release>1.2.0RC1</release> <api>1.2.0</api> </version> <stability> <release>beta</release> <api>beta</api> </stability> <date>2008-07-12</date> <license uri="http://opensource.org/licenses/bsd-license">BSD License</license> <notes> Changed license to New BSD License (Req #13826 [ashnazg]) Added a test suite against all API methods [ashnazg] Switch to package.xml v2 [ashnazg] Added Req #13839: Missing XHTML empty tags to collapse [ashnazg|drry] Fixed Bug #5392: encoding of ISO-8859-1 is the only supported encoding [ashnazg] Fixed Bug #4950: Incorrect CDATA serializing [ashnazg|drry] -- (this fix differs from the one in v1.2.0a1) </notes> </release> <release> <version> <release>1.2.0</release> <api>1.2.0</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <date>2008-07-26</date> <license uri="http://opensource.org/licenses/bsd-license">BSD License</license> <notes> Changed license to New BSD License (Req #13826 [ashnazg]) Added a test suite against all API methods [ashnazg] Switch to package.xml v2 [ashnazg] Added Req #13839: Missing XHTML empty tags to collapse [ashnazg|drry] Fixed Bug #5392: encoding of ISO-8859-1 is the only supported encoding [ashnazg] Fixed Bug #4950: Incorrect CDATA serializing [ashnazg|drry] -- (this fix differs from the one in v1.2.0a1) </notes> </release> <release> <version> <release>1.2.1</release> <api>1.2.0</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <date>2011-12-31</date> <license uri="http://opensource.org/licenses/bsd-license">BSD License</license> <notes> Fixed Bug #14760: Bug in getDocTypeDeclaration() [ashnazg|fpospisil] </notes> </release> <release> <version> <release>1.2.2</release> <api>1.2.0</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <date>2014-06-07</date> <license uri="http://opensource.org/licenses/bsd-license">BSD License</license> <notes> QA release Bug #18343 Entities in file names decoded during packaging Bug #19174 upgrade PHPUnit require statements & other fixes (for PEAR QA Team) Request #19750 examples/example.php encoding </notes> </release> <release> <version> <release>1.2.3</release> <api>1.2.0</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <date>2014-06-07</date> <license uri="http://opensource.org/licenses/bsd-license">BSD License</license> <notes> Bug #20293 Broken installation for 1.2.2 </notes> </release> <release> <version> <release>1.3.0</release> <api>1.3.0</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <date>2015-02-27</date> <license uri="http://opensource.org/licenses/bsd-license">BSD License</license> <notes> * Set minimum PHP version to 5.3.0 * Mark static methods with static keyword </notes> </release> <release> <version> <release>1.4.0</release> <api>1.4.0</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <date>2017-02-03</date> <license uri="http://opensource.org/licenses/bsd-license">BSD License</license> <notes> * Set minimum PHP version to 5.4.0 * Set minimum PEAR version to 1.10.1 * Adds a new XML_UTIL_COLLAPSE_NONE option for preventing empty tag collapsing. * Request #15467 CDATA sections and blank nodes </notes> </release> <release> <version> <release>1.4.1</release> <api>1.4.0</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <date>2017-02-07</date> <license uri="http://opensource.org/licenses/bsd-license">BSD License</license> <notes> * Bug #21177 XML_Util::collapseEmptyTags() can return NULL </notes> </release> <release> <version> <release>1.4.2</release> <api>1.4.0</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <date>2017-02-22</date> <license uri="http://opensource.org/licenses/bsd-license">BSD License</license> <notes> * Bug #21184 Collapse issue </notes> </release> <release> <version> <release>1.4.3</release> <api>1.4.0</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <date>2017-06-28</date> <license uri="http://opensource.org/licenses/bsd-license">BSD License</license> <notes> * Decrease minimum PEAR version to 1.9.0 to allow PEAR upgrades </notes> </release> <release> <version> <release>1.4.4</release> <api>1.4.0</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <date>2019-12-05</date> <license uri="http://opensource.org/licenses/bsd-license">BSD License</license> <notes> * PR #11: fix phplint warning </notes> </release> <release> <version> <release>1.4.5</release> <api>1.4.0</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <date>2020-04-19</date> <license uri="http://opensource.org/licenses/bsd-license">BSD License</license> <notes> * PR #12: fix Trying to access array offset on value of type int </notes> </release> </changelog> </package> PK�����u]Q?��?�� ��.pkgxml/Pear_Net_Sieve-1.4.5.xmlnu�[��������<?xml version="1.0" encoding="UTF-8"?> <package packagerversion="1.10.12" version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd"> <name>Net_Sieve</name> <channel>pear.php.net</channel> <summary>Handles talking to a sieve server.</summary> <description>This package provides an API to talk to servers implementing the managesieve protocol. It can be used to install and remove sieve scripts, mark them active etc.</description> <lead> <name>Aleksander Machniak</name> <user>alec</user> <email>alec@alec.pl</email> <active>yes</active> </lead> <lead> <name>Jan Schneider</name> <user>yunosh</user> <email>jan@horde.org</email> <active>no</active> </lead> <lead> <name>Richard Heyes</name> <user>richard</user> <email>richard@php.net</email> <active>no</active> </lead> <lead> <name>Damian Fernandez Sosa</name> <user>damian</user> <email>damlists@cnba.uba.ar</email> <active>no</active> </lead> <lead> <name>Anish Mistry</name> <user>amistry</user> <email>amistry@am-productions.biz</email> <active>no</active> </lead> <date>2021-04-24</date> <time>13:33:52</time> <version> <release>1.4.5</release> <api>1.4.3</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD</license> <notes> * Support XOAUTH2 authorization method </notes> <contents> <dir baseinstalldir="Net" name="/"> <file baseinstalldir="Net" md5sum="ef8cd688674fba85cc067e06c221e43b" name="tests/largescript.siv" role="test" /> <file baseinstalldir="Net" md5sum="7d772fe47ee45bdb521dd581281f38c3" name="tests/config.php.dist" role="test" /> <file baseinstalldir="Net" md5sum="6050fac5e66a4a6bbed7913f826974ed" name="tests/SieveTest.php" role="test" /> <file baseinstalldir="Net" md5sum="2a45a03c042351957f3435929a17bca3" name="Sieve.php" role="php"> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file> </dir> </contents> <dependencies> <required> <php> <min>5.0.0</min> </php> <pearinstaller> <min>1.4.0b1</min> </pearinstaller> <package> <name>Net_Socket</name> <channel>pear.php.net</channel> <min>1.0</min> </package> </required> <optional> <package> <name>Auth_SASL</name> <channel>pear.php.net</channel> <min>1.0</min> </package> </optional> </dependencies> <phprelease /> <changelog> <release> <date>2018-03-04</date> <version> <release>1.4.3</release> <api>1.4.1</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD</license> <notes> * Support GSSAPI authentication </notes> </release> <release> <date>2018-02-14</date> <version> <release>1.4.2</release> <api>1.4.0</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD</license> <notes> * Composer: Fix license identifier, don't use unbound version numbers for deps </notes> </release> <release> <date>2017-05-26</date> <version> <release>1.4.1</release> <api>1.4.0</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD</license> <notes> * Use 8bit instead of latin1 for string length in bytes calculation * Extend listScripts() so it's possible to get an active script name in one go * Request #20491: Skip redundant CAPABILITY requests </notes> </release> <release> <date>2017-05-21</date> <version> <release>1.4.0</release> <api>1.4.0</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD</license> <notes> * Dropped PHP4 support, fixed PHP7 warnings * Fixed E_DEPRECATED warning on Auth_SASL::factory() call * Enable later TLS versions </notes> </release> <release> <date>2015-01-20</date> <version> <release>1.3.4</release> <api>1.3.0</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD</license> <notes> * Remove erroneous and unnecessary active script caching (Bug #20472). </notes> </release> <release> <date>2014-09-24</date> <version> <release>1.3.3</release> <api>1.3.0</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD</license> <notes> * Fix notices from non-static calling of PEAR methods. * Fix reading OK responses with string literal messages. </notes> </release> <release> <date>2011-08-06</date> <version> <release>1.3.2</release> <api>1.3.0</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD</license> <notes> * Fix referrals if host data or user credentials are passed to connect() and login() instead of the constructor (Aleksander Machniak, Bug #17107). </notes> </release> <release> <date>2011-08-05</date> <version> <release>1.3.1</release> <api>1.3.0</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD</license> <notes> * Query capabilities again after successful authentication (Jesse Crawford, Request #18382). * Escape quotes and backslashes in script names, and use literal strings for script names with non-ASCII characters (Aleksander Machniak, Bug #16691). * Work around broken STARTTLS behavior in Cyrus versions before 2.3.10 (Aleksander Machniak, Bug #18241). * Improve string literal parsing (Aleksander Machniak, Bug #18228). </notes> </release> <release> <date>2010-07-01</date> <version> <release>1.3.0</release> <api>1.3.0</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD</license> <notes> * Add debug handler parameter to constructor. * Fix LOGIN authentication (Agustín Eijo, Aleksander Machniak, Bug #17527). </notes> </release> <release> <date>2010-06-13</date> <version> <release>1.2.2</release> <api>1.2.0</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD</license> <notes> * Fix SASL authentication without Auth_SASL (Bug #17489). </notes> </release> <release> <date>2010-04-19</date> <version> <release>1.2.1</release> <api>1.2.0</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD</license> <notes> * Fix DIGEST-MD5 authentication with Dovecot (Stef Simoens, Bug #17320). </notes> </release> <release> <date>2010-04-01</date> <version> <release>1.2.0</release> <api>1.2.0</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD</license> <notes> Changes since version 1.2.0b1: * Fix DIGEST-MD5 authentication (Aleksander Machniak, Bug #17285). * Don't try to call dl() if mbstring extension isn't loaded (Bug #17038). Changes since version 1.1.7: * Added support for adding a custom debug handler (Aleksander Machniak, Request #16681). * Fix breakage with certain locales, especially Turkish. * Fix reading authentication responses without literals (Bug #16647). * Code cleanup. </notes> </release> <release> <date>2009-10-07</date> <version> <release>1.2.0b1</release> <api>1.2.0</api> </version> <stability> <release>beta</release> <api>stable</api> </stability> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD</license> <notes> * Added support for adding a custom debug handler (Aleksander Machniak, Request #16681). * Fix breakage with certain locales, especially Turkish. * Fix reading authentication responses without literals (Bug #16647). * Code cleanup. </notes> </release> <release> <date>2009-07-24</date> <version> <release>1.1.7</release> <api>1.1.6</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD</license> <notes> * Fixed STARTTLS support (Bug #14205). * Added connect options and EXTERNAL authentication. </notes> </release> <release> <date>2008-03-22</date> <version> <release>1.1.6</release> <api>1.1.6</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD</license> <notes> * Fixed Bug #9273 * Fixed copy/paste error in CRAM and DIGEST authentication error case. </notes> </release> <release> <date>2006-10-24</date> <version> <release>1.1.5</release> <api>1.1.5</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD</license> <notes> * Fixed Bug connect() bug * Fixed Request #8071 </notes> </release> <release> <date>2006-09-09</date> <version> <release>1.1.4</release> <api>1.1.4</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD</license> <notes> * Fixed Bug #8452 Unterminated read loop * Fixed Bug #7845 Add mbstring support * Added Request #8071 Enable the ability to toggle TLS support if available. * Added Request #8453 Clean up PHPDoc and comments </notes> </release> <release> <date>2006-05-21</date> <version> <release>1.1.3</release> <api>1.1.3</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD</license> <notes> * Correctly Fixed Bug #3519 Net_Sieve w/ externally established sockets * Fixed Bug #7197 getScript() truncates long scripts * Added PHPUnit2 regression test script </notes> </release> <release> <date>2006-02-09</date> <version> <release>1.1.2</release> <api>1.1.2</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD</license> <notes> * Fixed Request #4053 Added STARTTLS support for PHP 5.1 and above * Fixed Bug #3519 Net_Sieve w/ externally established sockets * Fixed Bug #4794 drops protocol prefix, e.g. "ssl://" in referrals * Fixed STARTTLS detection * Allow $options[] to be passed to Net_Socket </notes> </release> <release> <version> <release>1.1.1</release> <api>1.1.1</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <date>2005-02-02</date> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD</license> <notes> * Fixed Bug #3242 cyrus murder referrals not followed </notes> </release> <release> <version> <release>1.1.0</release> <api>1.1.0</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <date>2004-12-18</date> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD</license> <notes> * Fixed Bug #2728 Linebreaks not being read using getScript() </notes> </release> <release> <version> <release>1.0.1</release> <api>1.0.1</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <date>2004-03-13</date> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD</license> <notes> * Fixed BUG #1006 </notes> </release> <release> <version> <release>1.0.0</release> <api>1.0.0</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <date>2004-03-10</date> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD</license> <notes> * Fixed DIGEST-MD5 sasl version handling (sasl v1.xx responses are diferent than v2.xx) * Fixed LOGIN Method </notes> </release> <release> <version> <release>0.9.1</release> <api>0.9.1</api> </version> <stability> <release>beta</release> <api>beta</api> </stability> <date>2004-02-29</date> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD</license> <notes> * There is an issue whith the DIGEST-MD5 method. in one installation it does not work but in my server it works perfect! please send me debug info to solve the problem if it affects you or disable DIGEST-MD5 * some optimizations to the code * added haveSpace() to check if the server has space to store the script. Use with care HAVESPACE seems to be broken in cyrus 2.0.16 * added hasExtension() * added getExtensions() * added referral support and automatic following of them. (it also handles the following of multireferrals). * removed _getResponse replaced by _doCmd. (thanks to Etienne Goyer for this) * added supportsAuthMech() * if installed automatically uses Auth_SASL * added CRAM-MD5 auth Method * added DIGEST-MD5 auth Method * added getAuthMechs() returns an array containing all the auth methods the server supports * added hasAuthMech() to check if the server has a particular auth method * _connect --> connect: now is a public method (without breaking BC) * _login --> login: now is a public method (without breaking BC) * fix typo cmdAuthenticate() ---> _cmdAuthenticate() * _doCmd() now parses string responses also. </notes> </release> <release> <version> <release>0.9.0</release> <api>0.9.0</api> </version> <stability> <release>beta</release> <api>beta</api> </stability> <date>2004-01-31</date> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD</license> <notes> * Added setDebug() method and debugging capabilities * added disconnect() method * added sample file test_sieve.php * fixed bug #591 * automagically selects the best auth method </notes> </release> <release> <version> <release>0.8.1</release> <api>0.8.1</api> </version> <stability> <release>beta</release> <api>beta</api> </stability> <date>2002-07-27</date> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD</license> <notes> Initial release </notes> </release> <release> <version> <release>0.8</release> <api>0.8</api> </version> <stability> <release>beta</release> <api>beta</api> </stability> <date>2002-05-10</date> <license uri="http://www.php.net/license">PHP</license> <notes> Initial release </notes> </release> <release> <date>2018-09-09</date> <version> <release>1.4.4</release> <api>1.4.2</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD</license> <notes> * Fix PHP 7.3: Declaration of case-insensitive constants is deprecated </notes> </release> </changelog> </package> PK�����u]/h����"��.pkgxml/Pear_Mail_Mime-1.10.11.xmlnu�[��������<?xml version="1.0" encoding="UTF-8"?> <package packagerversion="1.10.12" version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd"> <name>Mail_Mime</name> <channel>pear.php.net</channel> <summary>Mail_Mime provides classes to create MIME messages.</summary> <description>Mail_Mime provides classes to deal with the creation and manipulation of MIME messages. It allows people to create e-mail messages consisting of: * Text Parts * HTML Parts * Inline HTML Images * Attachments * Attached messages It supports big messages, base64 and quoted-printable encodings and non-ASCII characters in filenames, subjects, recipients, etc. encoded using RFC2047 and/or RFC2231.</description> <lead> <name>Cipriano Groenendal</name> <user>cipri</user> <email>cipri@php.net</email> <active>no</active> </lead> <lead> <name>Aleksander Machniak</name> <user>alec</user> <email>alec@php.net</email> <active>yes</active> </lead> <date>2021-09-05</date> <time>08:43:21</time> <version> <release>1.10.11</release> <api>1.10.0</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD Style</license> <notes> * Fix PHP 8.1: strlen(): Passing null to parameter #1 ($string) of type string is deprecated [alec] * Fix encoding recipient names with @ character and no space between name and address [alec] * Fix the license label in composer.json [jnkowa-gfk] </notes> <contents> <dir name="/"> <file baseinstalldir="Mail" md5sum="edd138f6c5497ae2b5d63620a67a931e" name="tests/class-filename.phpt" role="test" /> <file baseinstalldir="Mail" md5sum="7ec986391d0af058316f66e5a507e059" name="tests/content_transfer_encoding.phpt" role="test" /> <file baseinstalldir="Mail" md5sum="c1a43360d9b2cb5f9542503a4355c277" name="tests/encoding_case.phpt" role="test" /> <file baseinstalldir="Mail" md5sum="bf50a200190cad5e2d4aae4e120ea09f" name="tests/headers_with_mbstring.phpt" role="test" /> <file baseinstalldir="Mail" md5sum="9a2d207f873317125ff43c092f3f0d25" name="tests/headers_without_mbstring.phpt" role="test" /> <file baseinstalldir="Mail" md5sum="25d4c5b9fdeaabc7810c26e6f89e95ca" name="tests/qp_encoding_test.phpt" role="test" /> <file baseinstalldir="Mail" md5sum="958197f31b4a20c91dd42662595e7516" name="tests/sleep_wakeup_EOL-bug3488-part1.phpt" role="test" /> <file baseinstalldir="Mail" md5sum="46675529f1f021b51a1aa0ae6c971cd2" name="tests/sleep_wakeup_EOL-bug3488-part2.phpt" role="test" /> <file baseinstalldir="Mail" md5sum="f8c05910737e451c7a9d4737b8d9f095" name="tests/test_Bug_3513_1.phpt" role="test" /> <file baseinstalldir="Mail" md5sum="edb467a375ddf09e777a9388e2e8cbb5" name="tests/test_Bug_3513_2.phpt" role="test" /> <file baseinstalldir="Mail" md5sum="70c2456445eaaa80779206e9e245d685" name="tests/test_Bug_3513_3.phpt" role="test" /> <file baseinstalldir="Mail" md5sum="4cda500d0d7925e81a299f1d3db132a9" name="tests/test_Bug_7561_1.phpt" role="test" /> <file baseinstalldir="Mail" md5sum="42a214e7e3d3afa07f8996b235222611" name="tests/test_Bug_8386_1.phpt" role="test" /> <file baseinstalldir="Mail" md5sum="ed78099563499f60386a128cb7b96925" name="tests/test_Bug_8541_1.phpt" role="test" /> <file baseinstalldir="Mail" md5sum="5250a0693599b945e8642a1a289d7275" name="tests/test_Bug_9722_1.phpt" role="test" /> <file baseinstalldir="Mail" md5sum="b7f58f54e1485c23a60c83cd3cc5563e" name="tests/test_Bug_10596_1.phpt" role="test" /> <file baseinstalldir="Mail" md5sum="ccb53d80e7f5c9f28b11abce5fe5d490" name="tests/test_Bug_10816_1.phpt" role="test" /> <file baseinstalldir="Mail" md5sum="f3d92a1fff099173b8600fb3646d0614" name="tests/test_Bug_10999_1.phpt" role="test" /> <file baseinstalldir="Mail" md5sum="3f2757d5db43abd8f177f094f4d53625" name="tests/test_Bug_11381.phpt" role="test" /> <file baseinstalldir="Mail" md5sum="c64d675e73bc02fc94f5d03b3117cfa0" name="tests/test_Bug_11731.phpt" role="test" /> <file baseinstalldir="Mail" md5sum="8c9305ca05f5ed2d7cd7e31e4836f17a" name="tests/test_Bug_12165.phpt" role="test" /> <file baseinstalldir="Mail" md5sum="2aa2c3dfbe44500809e79da994272611" name="tests/test_Bug_12385_1.phpt" role="test" /> <file baseinstalldir="Mail" md5sum="ef1d726233dbd3360c540fd6a959b0d0" name="tests/test_Bug_12411.phpt" role="test" /> <file baseinstalldir="Mail" md5sum="a862a57ff622fcbb2328be6c805e2d05" name="tests/test_Bug_12466.phpt" role="test" /> <file baseinstalldir="Mail" md5sum="4eddeeac08f351feb147ab6fda439526" name="tests/test_Bug_13032.phpt" role="test" /> <file baseinstalldir="Mail" md5sum="de15a0657a83694bc6991c4184ccf9bd" name="tests/test_Bug_13444.phpt" role="test" /> <file baseinstalldir="Mail" md5sum="80afe9fced03288884e9d302d1e65b2d" name="tests/test_Bug_13962.phpt" role="test" /> <file baseinstalldir="Mail" md5sum="89bf87e798f4a149a150d4c2a505f976" name="tests/test_Bug_14529.phpt" role="test" /> <file baseinstalldir="Mail" md5sum="5f9100adb1c609110ed495fafa819975" name="tests/test_Bug_14779.phpt" role="test" /> <file baseinstalldir="Mail" md5sum="45eb42fe4e325da64f1ae8f149e2a396" name="tests/test_Bug_14780.phpt" role="test" /> <file baseinstalldir="Mail" md5sum="609dad2083c54ba56ea691c488ca20e2" name="tests/test_Bug_15320.phpt" role="test" /> <file baseinstalldir="Mail" md5sum="f4ef08e416e775558e8075b531bbc814" name="tests/test_Bug_16539.phpt" role="test" /> <file baseinstalldir="Mail" md5sum="ed1bd0fc9067b3fb8b95808bfa315916" name="tests/test_Bug_17025.phpt" role="test" /> <file baseinstalldir="Mail" md5sum="8a37de74fb39fed4566617a7ea38bb69" name="tests/test_Bug_17175.phpt" role="test" /> <file baseinstalldir="Mail" md5sum="b9dee3c7c45d8c6c22f860e93c3769b9" name="tests/test_Bug_18083.phpt" role="test" /> <file baseinstalldir="Mail" md5sum="96ce23ad1a1d6417facfcdd2baa9c8eb" name="tests/test_Bug_18772.phpt" role="test" /> <file baseinstalldir="Mail" md5sum="dd98307b3224b173f7b54f7e403865a4" name="tests/test_Bug_19497.phpt" role="test" /> <file baseinstalldir="Mail" md5sum="e1194180cb6a218fab69db90f88d1cb2" name="tests/test_Bug_20226.phpt" role="test" /> <file baseinstalldir="Mail" md5sum="1b7919174edcd1cf5d5fd5a622fdac9b" name="tests/test_Bug_20273.phpt" role="test" /> <file baseinstalldir="Mail" md5sum="6513c4b0c9e962c900d020124752333e" name="tests/test_Bug_20563.phpt" role="test" /> <file baseinstalldir="Mail" md5sum="7c7a00818cb0f01fa6c52c920b9e76c6" name="tests/test_Bug_20564.phpt" role="test" /> <file baseinstalldir="Mail" md5sum="b9e31a9c24b05dfb6166512e04e2f056" name="tests/test_Bug_21027.phpt" role="test" /> <file baseinstalldir="Mail" md5sum="b634a5e99aa26a8b6df8fcfae07051b4" name="tests/test_Bug_21098.phpt" role="test" /> <file baseinstalldir="Mail" md5sum="b21be5b099a69428bd37e60589cdd485" name="tests/test_Bug_21205.phpt" role="test" /> <file baseinstalldir="Mail" md5sum="bc152c12839964fba15da5673d25c4db" name="tests/test_Bug_21206.phpt" role="test" /> <file baseinstalldir="Mail" md5sum="ccf732525be42c955eea18e78490c3e1" name="tests/test_Bug_21255.phpt" role="test" /> <file baseinstalldir="Mail" md5sum="579f1e11da6c8074dbf508dc1f1dedfa" name="tests/test_Bug_GH16.phpt" role="test" /> <file baseinstalldir="Mail" md5sum="df32d66d9fccf7a0956422811283272a" name="tests/test_Bug_GH19.phpt" role="test" /> <file baseinstalldir="Mail" md5sum="b7b5b5bacc6a599cfaece35ad202ad1a" name="tests/test_Bug_GH26.phpt" role="test" /> <file baseinstalldir="Mail" md5sum="e08958f1bb60561f072a3508b8fd3e2e" name="tests/test_linebreak_dot.phpt" role="test" /> <file baseinstalldir="Mail" md5sum="8398e9bfea0bc7c4ff0770ae3d6279fe" name="tests/test_linebreak_larger_76.phpt" role="test" /> <file baseinstalldir="/" md5sum="e5c9ac7f32e53afdeafd1a84343a89ae" name="Mail/mime.php" role="php" /> <file baseinstalldir="/" md5sum="36128789ad1101d39d13b06ca2585576" name="Mail/mimePart.php" role="php" /> </dir> </contents> <dependencies> <required> <php> <min>5.2.0</min> </php> <pearinstaller> <min>1.6.0</min> </pearinstaller> </required> </dependencies> <phprelease /> <changelog> <release> <version> <release>1.0</release> <api>1.0</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <date>2001-12-28</date> <license uri="http://www.php.net/license">PHP</license> <notes> This is the initial release of the Mime_Mail package. </notes> </release> <release> <version> <release>1.1</release> <api>1.1</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <date>2002-04-03</date> <license uri="http://www.php.net/license">PHP</license> <notes> This is a maintenance release with various bugfixes and minor enhancements. </notes> </release> <release> <version> <release>1.2</release> <api>1.2</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <date>2002-07-14</date> <license uri="http://www.php.net/license">PHP</license> <notes> * Added header encoding * Altered mimePart to put boundary parameter on newline * Changed addFrom() to setFrom() * Added setSubject() * Made mimePart inherit crlf setting from mime </notes> </release> <release> <version> <release>1.2.1</release> <api>1.2.1</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <date>2002-07-27</date> <license uri="http://www.php.net/license">PHP</license> <notes> * License change * Applied a few changes From Ilia Alshanetsky </notes> </release> <release> <version> <release>1.3.0RC1</release> <api>1.3.0RC1</api> </version> <stability> <release>beta</release> <api>beta</api> </stability> <date>2005-03-20</date> <license uri="http://www.php.net/license">PHP</license> <notes> * First release in over 2.5 years (!) * MANY bugfixes (see the bugtracker) * added a few tests </notes> </release> <release> <version> <release>1.3.0</release> <api>1.3.0</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <date>2005-04-01</date> <license uri="http://www.php.net/license">PHP</license> <notes> * First (stable) release in over 2.5 years (!) * MANY bugfixes (see the bugtracker) * added a few tests * one small fix after RC1 (bug #3940) </notes> </release> <release> <version> <release>1.3.1</release> <api>1.3.1</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <date>2005-07-13</date> <license uri="http://www.php.net/license">PHP</license> <notes> </notes> </release> <release> <version> <release>1.4.0a1</release> <api>1.3.1</api> </version> <stability> <release>alpha</release> <api>stable</api> </stability> <date>2007-03-08</date> <license uri="http://www.opensource.org/licenses/bsd-license.php">bsd style</license> <notes> * Changed License to BSD Style license, as that's what the code was since the beginning [cipri] * Fix Bug #30: Mail_Mime: _encodeHeaders is not RFC-2047 compliant. [cipri] * Fix Bug #3513: support of RFC2231 in header fields. [cipri] * Fix Bug #4696: addAttachment crash [cipri] * Fix Bug #5333: Only variables should be returned by reference; triggers notices since php 4.4.0 [cipri] * Fix Bug #7561: Mail_mimePart::_quotedPrintableEncode() misbehavior with mbstring overload [cipri] * Fix Bug #8223: Incorrectly encoded quoted-printable headers [cipri] * Fix Bug #8386: HTML body not correctly encoded if attachments present [cipri] * Fix Bug #8541: mimePart.php line delimiter is \r [cipri] * Fix Bug #9347: Notices about references [cweiske] * Fix Bug #9558: Broken multiline headers [cipri] * Fix Bug #9956: Notices being thrown [cipri] * Fix Bug #9976: Subject encoded twice [cipri] * Implement Feature #2952: Mail_mime::headers() saves extra headers [cipri] * Implement Feature #3636: Allow specification of charsets and encoding [cipri] * Implement Feature #4057: Mail_Mime: Add name parameter for Content-Type [cipri] * Implement Feature #4504: addHTMLImage does not work in cases when filename contains a path [cipri] * Implement Feature #5837: Mail_Mime: Build message for Net_SMTP [cipri] * Implement Feature #5934: Mail_Mime: choice for content disposition [cipri] * Implement Feature #6568: Mail_Mime: inline images referenced in CSS definitions not replaced. [cipri] </notes> </release> <release> <version> <release>1.4.0a2</release> <api>1.3.1</api> </version> <stability> <release>alpha</release> <api>stable</api> </stability> <date>2007-04-05</date> <license uri="http://www.opensource.org/licenses/bsd-license.php">bsd style</license> <notes> * Fix Bug #9722: _quotedPrintableEncode does not encode dot at start of line on Windows platform [cipri] * Fix Bug #9725: multipart/related & alternative wrong order [cipri] * Fix Bug #10146: mbstring fails to recognize encodings. [cipri] * Fix Bug #10158: Inline images not displayed on Mozilla Thunderbird [cipri] * Fix Bug #10298: Mail_mime, double Quotes and Specialchars in from and to Adress [cipri] * Fix Bug #10306: Strings with Double Quotes get encoded wrongly [cipri] * Fix Bug #10596: Incorrect handling of text and html '0' bodies [cipri] </notes> </release> <release> <version> <release>1.4.0a3</release> <api>1.3.1</api> </version> <stability> <release>alpha</release> <api>stable</api> </stability> <date>2007-04-05</date> <license uri="http://www.opensource.org/licenses/bsd-license.php">bsd style</license> <notes> * Fix Bug #10298: Mail_mime, double Quotes and Specialchars in from and to Adress [cipri] * Fix Bug #10306: Strings with Double Quotes get encoded wrongly [cipri] </notes> </release> <release> <version> <release>1.4.0RC1</release> <api>1.3.1</api> </version> <stability> <release>beta</release> <api>stable</api> </stability> <date>2007-04-12</date> <license uri="http://www.opensource.org/licenses/bsd-license.php">bsd style</license> <notes> * Fix Bug #10232: Gmail creates double line break when \r\n is used [cipri] </notes> </release> <release> <version> <release>1.4.0RC2</release> <api>1.3.1</api> </version> <stability> <release>beta</release> <api>stable</api> </stability> <date>2007-04-22</date> <license uri="http://www.opensource.org/licenses/bsd-license.php">bsd style</license> <notes> * Fix Bug #10791: Unit tests fail [cipri] * Fix Bug #10792: No unit tests for recently fixed bugs [cipri] * Fix Bug #10793: Long headers don't get wrapped since fix for Bug #10298 [cipri] </notes> </release> <release> <version> <release>1.4.0RC3</release> <api>1.3.1</api> </version> <stability> <release>beta</release> <api>stable</api> </stability> <date>2007-04-24</date> <license uri="http://www.opensource.org/licenses/bsd-license.php">bsd style</license> <notes> * Fix Bug #10816: Unwanted linebreak at the end of output [cipri] </notes> </release> <release> <version> <release>1.4.0RC4</release> <api>1.3.1</api> </version> <stability> <release>beta</release> <api>stable</api> </stability> <date>2007-04-28</date> <license uri="http://www.opensource.org/licenses/bsd-license.php">bsd style</license> <notes> * Fix Bug #3513: support of RFC2231 in header fields. [cipri] * Fix Bug #10838: bad use of MIME encoding in header. [cipri] </notes> </release> <release> <version> <release>1.4.0</release> <api>1.3.1</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <date>2007-05-05</date> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD Style</license> <notes> Release notes: * No more notices in PHP 5 /4.4.0. * Improved inline HTML image function. * Improved header encoding with foreign charsets. * Improved long header rendering. * More control over used Charsets and encoding schemes. * More configurable attachments and inline images. * Full RFC 2047 Support * Full RFC 2231 Support * Unit-tests Fixed bugs: * Fix Bug #30: Mail_Mime: _encodeHeaders is not RFC-2047 compliant. [cipri] * Fix Bug #3513: support of RFC2231 in header fields. [cipri] * Fix Bug #4696: addAttachment crash [cipri] * Fix Bug #5333: Only variables should be returned by reference; triggers notices since php 4.4.0 [cipri] * Fix Bug #5400: Do not return function reference [cipri] * Fix Bug #5710: Little reference bugs [cipri] * Fix Bug #5890: Only variable references should be returned by reference [cipri] * Fix Bug #6260: Just a notice with PHP5 [cipri] * Fix Bug #6261: php 5.1.1 upgrade [cipri] * Fix Bug #6663: Notice about reference passing [cipri] * Fix Bug #7561: Mail_mimePart::_quotedPrintableEncode() misbehavior with mbstring overload [cipri] * Fix Bug #7713: PHP5 Notice: Only variable references should be returned by reference [cipri] * Fix Bug #8223: Incorrectly encoded quoted-printable headers [cipri] * Fix Bug #8386: HTML body not correctly encoded if attachments present [cipri] * Fix Bug #8541: mimePart.php line delimiter is \r [cipri] * Fix Bug #8812: user header updates overwritten [cipri] * Fix Bug #9347: Notices about references [cweiske] * Fix Bug #9558: Broken multiline headers [cipri] * Fix Bug #9722: _quotedPrintableEncode does not encode dot at start of line on Windows platform [cipri] * Fix Bug #9725: multipart/related & alternative wrong order [cipri] * Fix Bug #9956: Notices being thrown [cipri] * Fix Bug #9976: Subject encoded twice [cipri] * Fix Bug #10146: mbstring fails to recognize encodings. [cipri] * Fix Bug #10158: Inline images not displayed on Mozilla Thunderbird [cipri] * Fix Bug #10232: Gmail creates double line break when \r\n is used [cipri] * Fix Bug #10298: Mail_mime, double Quotes and Specialchars in from and to Adress [cipri] * Fix Bug #10306: Strings with Double Quotes get encoded wrongly [cipri] * Fix Bug #10596: Incorrect handling of text and html '0' bodies [cipri] * Fix Bug #10791: Unit tests fail [cipri] * Fix Bug #10792: No unit tests for recently fixed bugs [cipri] * Fix Bug #10793: Long headers don't get wrapped since fix for Bug #10298 [cipri] * Fix Bug #10816: Unwanted linebreak at the end of output [cipri] * Fix Bug #10838: bad use of MIME encoding in header. [cipri] Implemented Features: * Implement Feature #2952: Mail_mime::headers() saves extra headers [cipri] * Implement Feature #3636: Allow specification of charsets and encoding [cipri] * Implement Feature #4057: Mail_Mime: Add name parameter for Content-Type [cipri] * Implement Feature #4504: addHTMLImage does not work in cases when filename contains a path [cipri] * Implement Feature #5837: Mail_Mime: Build message for Net_SMTP [cipri] * Implement Feature #5934: Mail_Mime: choice for content disposition [cipri] * Implement Feature #6568: Mail_Mime: inline images referenced in CSS definitions not replaced. [cipri] * Implement Feature #10604: Put an option to specify Content-Location in the header [cipri] </notes> </release> <release> <version> <release>1.5.0a1</release> <api>1.3.1</api> </version> <stability> <release>alpha</release> <api>stable</api> </stability> <date>2007-06-10</date> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD Style</license> <notes> Split off mail_MimeDecode </notes> </release> <release> <version> <release>1.5.0RC1</release> <api>1.3.1</api> </version> <stability> <release>beta</release> <api>stable</api> </stability> <date>2007-06-10</date> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD Style</license> <notes> Split off mail_MimeDecode </notes> </release> <release> <version> <release>1.5.0</release> <api>1.3.1</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <date>2007-06-17</date> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD Style</license> <notes> Split off Mail_MimeDecode </notes> </release> <release> <version> <release>1.5.1</release> <api>1.3.1</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <date>2007-06-20</date> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD Style</license> <notes> * Fix Bug #11344: Error at line 644 in mime.php [cipri] </notes> </release> <release> <version> <release>1.5.2</release> <api>1.3.1</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <date>2007-06-21</date> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD Style</license> <notes> * Fix Bug #11381: domain name is attached to content-id, trailing greater-than sign is not remove [cipri] </notes> </release> <release> <version> <release>1.5.3</release> <api>1.3.2</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <date>2009-12-29</date> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD Style</license> <notes> Fixed bugs: * Fix Bug #14678: srand() lowers security [clockwerx] * Fix Bug #12921: _file2str not binary safe [walter] * Fix Bug #12385: Bad regex when replacing css style attachments [cipri] * Fix Bug #16911: Excessive semicolon in MIME header [alec] * Fix Bug #15320: Attachment charset is not set in Content-Type header [alec] * Fix Bug #16911: Lack of semicolon separator for MIME header parameters [alec] * Fix Bug #16846: Use preg_replace_callback() instead of /e modifier [alec] * Fix Bug #14779: Problem with an empty attachment [alec] * Fix Bug #15913: Optimize the memory used by Mail_mimePart::encode. Avoid having attachments data duplicated in memory [alec] * Fix Bug #16539: Headers longer than 998 characters aren't wrapped [alec] * Fix Bug #11238: Wrong encoding of structured headers [alec] * Fix Bug #13641: iconv_mime_encode() seems to work different/errorious than the build in logic. Removed 'ignore_iconv' param. [alec] * Fix Bug #16706: Incorrect double-quotes RFC 2231-encoded parameter values [alec] * Fix Bug #14232: RFC2231: tspecials encoding in _buildHeaderParam() [alec] Implemented Features: * Implement Feature #10438: Function (encodeHeader) for encoding of given header [alec] </notes> </release> <release> <version> <release>1.6.0</release> <api>1.4.0</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <date>2010-01-27</date> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD Style</license> <notes> Bugs Fixed: * Don't break specified headers folding [alec] * Bug #17025: Wrong headers() result for long unwrapable header value [alec] Implemented Features: * Allow setting Content-ID for HTML Images [alec] * Added one setParam() in place of many set*() functions [alec] * Added getParam(), getTXTBody(), getHTMLBody() [alec] * Skip RFC2231's charset if filename contains only ASCII characters [alec] * Make sure that Received: headers are returned on the top [alec] * Added saveMessageBody() and getMessageBody() functions [alec] </notes> </release> <release> <version> <release>1.6.1</release> <api>1.4.0</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <date>2010-03-08</date> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD Style</license> <notes> Bugs Fixed: * Fix encoding of Return-Receipt-To and Disposition-Notification-To headers [alec] Implemented Features: * Implement Feature #12466: Build parameters validation [alec] * Implement Feature #17175: Content-Description support for attachments [alec] </notes> </release> <release> <version> <release>1.6.2</release> <api>1.4.0</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <date>2010-03-23</date> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD Style</license> <notes> Bugs Fixed: * Fix Bug #17226: Non RFC-compliant quoted-printable encoding of structured headers [alec] </notes> </release> <release> <version> <release>1.7.0</release> <api>1.4.0</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <date>2010-04-12</date> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD Style</license> <notes> Implemented Features: * Added Mail_mime::setContentType() function with possibility to set various types in Content-Type header (also fixes problem with boundary parameter when Content-Type header was specified by user) [alec] </notes> </release> <release> <date>2010-07-29</date> <version> <release>1.8.0</release> <api>1.4.1</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD Style</license> <notes> Bugs Fixed: * Double-addition of e-mail domain to content ID in HTML images [alec] * #17311: Multi-octet characters are split across adjacent 'encoded-word's [alec] * #17573: Place charset parameter in first line of Content-Type header (if possible) [alec] Implemented Features: * #17518: addTo() method [alec] </notes> </release> <release> <date>2010-12-01</date> <version> <release>1.8.1</release> <api>1.4.1</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD Style</license> <notes> Bugs Fixed: * #18083: Not possible to set separate charset for attachment content and headers [alec] </notes> </release> <release> <date>2011-08-10</date> <version> <release>1.8.2</release> <api>1.4.1</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD Style</license> <notes> Bugs Fixed: * #18426: Fixed backward compatibility for "dfilename" parameter [alec] * Removed xmail.dtd, xmail.xsl from the package [alec] * Fixed handling of email addresses with quoted local part [alec] </notes> </release> <release> <date>2012-03-12</date> <version> <release>1.8.3</release> <api>1.4.1</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD Style</license> <notes> * Request #19009: Remove error_reporting from tests [alec] * Fixed Bug #19094: Email addresses do not have to contain a space between the name and address part [alec] * Fixed Bug #19328: Wrong encoding of filenames with comma [alec] </notes> </release> <release> <date>2012-05-17</date> <version> <release>1.8.4</release> <api>1.4.2</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD Style</license> <notes> * Request #19406: Allow to set individual attachment part headers [alec] * Fixed Bug #18982: Non-static method Mail_mimePart::encodeHeader() should not be called statically [alec] </notes> </release> <release> <date>2012-06-09</date> <version> <release>1.8.5</release> <api>1.4.3</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD Style</license> <notes> * Added possibility to set additional parameters of message part header, e.g. attachment size [alec] * Added automatic setting of attachment size via Content-Disposition header size parameter [alec] </notes> </release> <release> <date>2012-10-23</date> <version> <release>1.8.6</release> <api>1.4.3</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD Style</license> <notes> * Bug #19473: PEAR::isError() compatibility problem with PHP 5.4 [alec] * Bug #19497: Attachment filename is cut on slash character [alec] * Bug #19665: Add Mail-Reply-To and Mail-Followup-To to structured recipient headers list [alec] </notes> </release> <release> <date>2012-12-25</date> <version> <release>1.8.7</release> <api>1.4.3</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD Style</license> <notes> * Bug #5333: Fix more return by reference errors [alec] * Bug #19754: Fix compatibility with PHP4 [alec] </notes> </release> <release> <date>2013-07-05</date> <version> <release>1.8.8</release> <api>1.4.3</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD Style</license> <notes> * Fixed warning/notice on (static vs. non-static) PEAR::raiseError() usage [alec] * Fixed Bug #19761: PHP5 warnings about return by reference [alec] * Fixed Bug #19770: Make cid generator more unique on Windows [alec] * Fixed Bug #19987: E_STRICT warning when null is passed by reference [alec] </notes> </release> <release> <date>2014-05-14</date> <version> <release>1.8.9</release> <api>1.4.3</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD Style</license> <notes> * Fixed Bug #20273: Incorrect handling of HTAB in encodeHeader() [alec] * Fixed Bug #20226: Mail_mimePart::encodeHeader does not encode ISO-2022-JP string [alec] * Fixed Bug #20222: Broken Compatybility with PHP4 [alec] </notes> </release> <release> <date>2015-07-05</date> <time>12:50:00</time> <version> <release>1.9.0RC1</release> <api>2.0.0</api> </version> <stability> <release>beta</release> <api>beta</api> </stability> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD Style</license> <notes> * Drop PHP4 support, Fix warnings on PHP7 [alec] * Request #20564: Added possibility to unset headers [alec] * Request #20563: Added isMultipart() method [alec] * Request #20565: Accept also a file pointer in Mail_mimePart::encodeToFile(), Mail_mime::get() and Mail_mime::saveMessageBody() [alec] </notes> </release> <release> <date>2015-08-06</date> <time>12:00:00</time> <version> <release>1.9.0</release> <api>1.9.0</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD Style</license> <notes> * Bug #20921: Make Mail_mimePart::encodeHeaderValue() a static method [alec] * Bug #20931: Really remove unset headers [alec] * Request #18772: Added methods for creating text/calendar messages [alec] </notes> </release> <release> <date>2015-09-13</date> <time>12:00:00</time> <version> <release>1.10.0</release> <api>1.10.0</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD Style</license> <notes> * Add possibility to add externally created Mail_mimePart objects as attachments [alec] * Add possibility to set preamble text for multipart messages [alec] </notes> </release> <release> <date>2017-05-21</date> <time>12:00:00</time> <version> <release>1.10.1</release> <api>1.10.0</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD Style</license> <notes> * Fix Bug 21206: explodeQuotedString() does not handle quoted strings correctly [dfukagaw28] * Fix Bug 21205: Invalid encoding of headers with quoted multibyte strings in non-unicode charset [dfukagaw28] * Fix Bug 21098: Discrepancy in handling of empty (but set) plain text part [alec] </notes> </release> <release> <date>2017-11-17</date> <time>11:00:00</time> <version> <release>1.10.2</release> <api>1.10.0</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD Style</license> <notes> * Fix Bug #21255: Boundary gets added twice when using setContentType() [alec] * PHP 7.2 compatibility fixes [alec] </notes> </release> <release> <date>2019-09-25</date> <time>08:00:00</time> <version> <release>1.10.3</release> <api>1.10.0</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD Style</license> <notes> * Fix deprecation warning for get_magic_quotes_runtime() use on PHP 7.4 [alec] </notes> </release> <release> <date>2019-10-13</date> <time>11:00:00</time> <version> <release>1.10.4</release> <api>1.10.0</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD Style</license> <notes> * Fix E_STRICT errors introduced in the previous release [alec] </notes> </release> <release> <date>2020-01-24</date> <time>19:00:00</time> <version> <release>1.10.5</release> <api>1.10.0</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD Style</license> <notes> * Make sure to not set Content-Transfer-Encoding on multipart messages [alec] * Added support for calendar invitations with attachments/html/images [jacalben] </notes> </release> <release> <date>2020-01-30</date> <time>08:25:00</time> <version> <release>1.10.6</release> <api>1.10.0</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD Style</license> <notes> * Fix different boundary in headers and body when using headers() after get() [alec] * Removed phail.php script [alec] </notes> </release> <release> <date>2020-03-01</date> <time>08:50:00</time> <version> <release>1.10.7</release> <api>1.10.0</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD Style</license> <notes> * Fix invalid Content-Type for messages with only html part and inline images [alec] </notes> </release> <release> <date>2020-06-13</date> <time>08:50:00</time> <version> <release>1.10.8</release> <api>1.10.0</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD Style</license> <notes> * Fix encoding issues with ISO-2022-JP-MS input labelled with ISO-2022-JP [shirosaki] </notes> </release> <release> <date>2020-06-27</date> <time>10:30:00</time> <version> <release>1.10.9</release> <api>1.10.0</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD Style</license> <notes> * Added a workaround for an opcache bug on OpenSuse 15.1 [alec] </notes> </release> <release> <date>2021-01-17</date> <time>09:25:00</time> <version> <release>1.10.10</release> <api>1.10.0</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD Style</license> <notes> * Compatibility fixes for PHP 5.2 and 5.3 [alec] * Corrected soft line breaks handling to be RFC compliant [ixs] * Corrected line breaks for lines ending in dots and length more than 74 [ixs] </notes> </release> </changelog> </package> PK�����u]%ONO����&��.pkgxml/Pear_Mail_mimeDecode-1.5.6.xmlnu�[��������<?xml version="1.0" encoding="UTF-8"?> <package packagerversion="1.10.1" version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd"> <name>Mail_mimeDecode</name> <channel>pear.php.net</channel> <summary>Provides a class to decode mime messages.</summary> <description>Provides a class to deal with the decoding and interpreting of mime messages. This package used to be part of the Mail_Mime package, but has been split off.</description> <lead> <name>Cipriano Groenendal</name> <user>cipri</user> <email>cipri@php.net</email> <active>yes</active> </lead> <lead> <name>Alan Knowles</name> <user>alan_k</user> <email>alan@akbkhome.com</email> <active>yes</active> </lead> <developer> <name>George Schlossnagle</name> <user>gschlossnagle</user> <email>george@omniti.com</email> <active>no</active> </developer> <date>2016-08-29</date> <time>03:04:25</time> <version> <release>1.5.6</release> <api>1.3.1</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD Style</license> <notes> Minor Bug fix release. #20431 - support for android #19762 - multipart signed not split correctly on line breaks #20027 - replace /e with preg_replace_callback #19762 - multipart/signed eating of new line, and expose sig_hdr etc. </notes> <contents> <dir baseinstalldir="/" name="/"> <file baseinstalldir="/" md5sum="05c45d0b58718ebe73860ebfe494dcef" name="Mail/mimeDecode.php" role="php" /> <file baseinstalldir="Mail" md5sum="642acc06cdb217b6e64506182449d8f8" name="tests/parse_header_value.phpt" role="test" /> <file baseinstalldir="Mail" md5sum="a0bc0c9b68e62a19202bd8fb26104f3c" name="tests/semicolon_content_type_bug1724.phpt" role="test" /> <file baseinstalldir="Mail" md5sum="194810c478066eaeb28f51116b88e25a" name="xmail.dtd" role="data" /> <file baseinstalldir="Mail" md5sum="61cea06fb6b4bd3a4b5e2d37384e14a9" name="xmail.xsl" role="data" /> </dir> </contents> <dependencies> <required> <php> <min>4.3.0</min> </php> <pearinstaller> <min>1.6.0</min> </pearinstaller> <package> <name>Mail_Mime</name> <channel>pear.php.net</channel> <min>1.4.0</min> <exclude>1.4.0</exclude> </package> </required> </dependencies> <phprelease /> <changelog> <release> <version> <release>0.1.0</release> <api>1.3.1</api> </version> <stability> <release>alpha</release> <api>stable</api> </stability> <date>2007-06-10</date> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD Style</license> <notes> Initial Release </notes> </release> <release> <version> <release>1.0.0RC1</release> <api>1.3.1</api> </version> <stability> <release>beta</release> <api>stable</api> </stability> <date>2007-06-10</date> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD Style</license> <notes> Initial Release </notes> </release> <release> <date>2007-06-17</date> <time>17:20:44</time> <version> <release>1.5.0</release> <api>1.3.1</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD Style</license> <notes> First release of mail_mimeDecode as a seperate package. </notes> </release> <release> <date>2009-12-03</date> <version> <release>1.5.1</release> <api>1.3.1</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD Style</license> <notes> Minor Bugfix release. Bug Fixes #----- - fix bug in getSendArray() - not handling multiple recipents #14129 - E_NOTICE fixes Requests #12365 - Add option to also include raw attached messages patched on the request of till </notes> </release> <release> <date>2010-09-02</date> <version> <release>1.5.2</release> <api>1.3.1</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD Style</license> <notes> Minor Bugfix release. Bug Fixes #4739 - regexp parsing of header values does not balance quoting correctly - Fix sponsored by http://webyog.com #17325 - empty body messages are valid messages #17276 - remove &new usage which throws errors now </notes> </release> <release> <date>2010-09-05</date> <version> <release>1.5.3</release> <api>1.3.1</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD Style</license> <notes> Major Bugfix release. Apart from a major cleanout of the bug tracker for this package, this release includes a revamped parseHeaderValue which removes the rather flakey regex, with a real parser, which should be considerably more robust. Bug Fixes #17844 - all regression tests fixed - remove the last of the while list each() .. this is 2010 ;)... #11410 - support wap multipart #9616 - long strings as filename etc.. aaa*0=.... aaa*1=.... aaa*2=.... (merged into aaa=.....) #9100 - change to preg_split for mime boundary detection , in theory should catch boundaries in nested situations better... #7709 - check for last element on boundary split to see if its usable #7065 - wrapped header lines with encoding should be concated without spaces #6495 - missing body in decoded object #11537 - better decode and multi-line support </notes> </release> <release> <date>2010-09-14</date> <version> <release>1.5.4</release> <api>1.3.1</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD Style</license> <notes> Critical Security release. It is highly recommended that users of 1.5.3 upgrade to this release, a change in the boundary detection code introduced a potential denial of service attack. Bug Fixes #17862 - quote boundary preg_split code </notes> </release> <release> <version> <release>1.5.5</release> <api>1.3.1</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <date>2011-11-16</date> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD Style</license> <notes> Minor Bug fix release. #17959 - Boundaries ending with non-word characters - patch by Alex Adriaanese ------ - ignore whitespace and trailing cr/lf in last section of split ------ - correct spacing on multi-line headers. now only striped for encoded data. (on previous line) </notes> </release> </changelog> </package> PK�����u]ȗ����!��.pkgxml/Pear_Net_Socket-1.2.2.xmlnu�[��������<?xml version="1.0" encoding="UTF-8"?> <package packagerversion="1.10.3" version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd"> <name>Net_Socket</name> <channel>pear.php.net</channel> <summary>Network Socket Interface</summary> <description>Net_Socket is a class interface to TCP sockets. It provides blocking and non-blocking operation, with different reading and writing modes (byte-wise, block-wise, line-wise and special formats like network byte-order ip addresses).</description> <lead> <name>Chuck Hagenbuch</name> <user>chagenbu</user> <email>chuck@horde.org</email> <active>no</active> </lead> <lead> <name>Stig Bakken</name> <user>ssb</user> <email>stig@php.net</email> <active>no</active> </lead> <lead> <name>Aleksander Machniak</name> <user>alec</user> <email>alec@php.net</email> <active>no</active> </lead> <date>2017-04-13</date> <time>17:15:33</time> <version> <release>1.2.2</release> <api>1.2.0</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD-2-Clause</license> <notes> * Bug #21178: $php_errormsg is deprecated in PHP 7.2 </notes> <contents> <dir baseinstalldir="/" name="/"> <file baseinstalldir="/" md5sum="f99081ef3a69bcc1faa0d90a9a616788" name="Net/Socket.php" role="php" /> <file baseinstalldir="/" md5sum="61a9ed8d1604a739e6997149ea34e701" name="README.md" role="doc" /> <file baseinstalldir="/" md5sum="28575b04f4f2014316245d83e27343e1" name="LICENSE" role="doc" /> </dir> </contents> <dependencies> <required> <php> <min>5.4.0</min> </php> <pearinstaller> <min>1.10.1</min> </pearinstaller> </required> </dependencies> <phprelease /> </package> PK�����u]0$-��-�� ��.pkgxml/Pear_File_MARC-1.4.1.xmlnu�[��������<?xml version="1.0" encoding="UTF-8"?> <package packagerversion="1.10.9" version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd"> <name>File_MARC</name> <channel>pear.php.net</channel> <summary>Parse, modify, and create MARC records</summary> <description>The standard for machine-readable cataloging (MARC) records is documented at http://loc.gov/marc/. This package enables you to read existing MARC records from a file, string, or (using the YAZ extension), from a Z39.50 source. You can also use this package to create new MARC records. This package is based on the PHP MARC package, originally called "php-marc", that is part of the Emilda Project (http://www.emilda.org). Christoffer Landtman generously agreed to make the "php-marc" code available under the GNU LGPL so it could be used as the basis of this PEAR package.</description> <lead> <name>Dan Scott</name> <user>dbs</user> <email>dbs@php.net</email> <active>yes</active> </lead> <date>2019-11-13</date> <time>17:33:33</time> <version> <release>1.4.1</release> <api>1.4.0</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <license uri="http://www.gnu.org/copyleft/lesser.html">GNU Lesser General Public License</license> <notes> 1.4.1 * Reintroduce include_path to composer.json </notes> <contents> <dir baseinstalldir="File" name="/"> <file baseinstalldir="/" md5sum="ffe2590635f404af055fe731da105939" name="File/MARC/Lint/CodeData.php" role="php" /> <file baseinstalldir="/" md5sum="a3b9e1c817e67f59add05593500d463e" name="File/MARC/Control_Field.php" role="php" /> <file baseinstalldir="/" md5sum="acba4463f8e40d6ee4e7ba1f2dc53123" name="File/MARC/Data_Field.php" role="php" /> <file baseinstalldir="/" md5sum="378f483ec1fd161cd9dfb9b05db58d66" name="File/MARC/Exception.php" role="php" /> <file baseinstalldir="/" md5sum="a9ba69030cbf4847292b9975e9d922c6" name="File/MARC/Field.php" role="php" /> <file baseinstalldir="/" md5sum="c37351c7c80927ce6bb1e662510f9183" name="File/MARC/Lint.php" role="php" /> <file baseinstalldir="/" md5sum="c5ac39e3d25eb0108b9dd5ad8466c821" name="File/MARC/List.php" role="php" /> <file baseinstalldir="/" md5sum="7af6ce78cde4bb246e4e96709e90d2c0" name="File/MARC/Record.php" role="php" /> <file baseinstalldir="/" md5sum="df5f97139685f0ad04e47fdbb67e3968" name="File/MARC/Subfield.php" role="php" /> <file baseinstalldir="/" md5sum="6e102262dfd5d65d8d5a6221dfc74edd" name="File/MARC.php" role="php" /> <file baseinstalldir="/" md5sum="8b64040d2d18ac4b994595a148266a66" name="File/MARCBASE.php" role="php" /> <file baseinstalldir="/" md5sum="f5a17a60d34e84e2ee7ca1e5c5c6c620" name="File/MARCXML.php" role="php" /> <file baseinstalldir="File" md5sum="6af971fd9ff5ef3e5fcba8a64a0e7a49" name="examples/example.mrc" role="doc" /> <file baseinstalldir="File" md5sum="1aea40df9f1c2e32f8e065fe8da0a3b5" name="examples/marc_yaz.php" role="doc" /> <file baseinstalldir="File" md5sum="70ae317e0890d5896e3ffccdd293369a" name="examples/read.php" role="doc" /> <file baseinstalldir="File" md5sum="54efb9d920ac775bfc847a83a2dec73a" name="examples/subfields.php" role="doc" /> <file baseinstalldir="File" md5sum="14297da35b510c496cd1f328cf3bb301" name="tests/bad_example.mrc" role="test" /> <file baseinstalldir="File" md5sum="0dd4c6dbad6e8608d0ebf9d24425955d" name="tests/bad_example.xml" role="test" /> <file baseinstalldir="File" md5sum="216a6f9d53f6d3d8e22d81fdc10f4bc1" name="tests/camel.mrc" role="test" /> <file baseinstalldir="File" md5sum="6af971fd9ff5ef3e5fcba8a64a0e7a49" name="tests/example.mrc" role="test" /> <file baseinstalldir="File" md5sum="9455aec3371f79cf7d31281fd03f5171" name="tests/marc_001.phpt" role="test" /> <file baseinstalldir="File" md5sum="577e2f5f89fd48cf1a3576a29d2958f8" name="tests/marc_002.phpt" role="test" /> <file baseinstalldir="File" md5sum="a6a586354b9a06c880c2a7470dd828d7" name="tests/marc_003.phpt" role="test" /> <file baseinstalldir="File" md5sum="b1c7e2fc5572a0f9362a771c260a1fe3" name="tests/marc_004.phpt" role="test" /> <file baseinstalldir="File" md5sum="84f85ac7f8a2532e4e90ccde7764556a" name="tests/marc_005.phpt" role="test" /> <file baseinstalldir="File" md5sum="889e5e906a97de7a0e94b0c5f30e70e7" name="tests/marc_006.phpt" role="test" /> <file baseinstalldir="File" md5sum="be823dc8a8efb408de06371ab802efcc" name="tests/marc_007.phpt" role="test" /> <file baseinstalldir="File" md5sum="af44490aafea44e5120f881cb81cdad9" name="tests/marc_008.phpt" role="test" /> <file baseinstalldir="File" md5sum="ac9f2a7aeb24900a11f5102744179ae3" name="tests/marc_009.phpt" role="test" /> <file baseinstalldir="File" md5sum="5e43eb5cddbb4f2bd0d6405cd95b80aa" name="tests/marc_010.phpt" role="test" /> <file baseinstalldir="File" md5sum="2e1cd8509c0bf04ec77fc0f51375f611" name="tests/marc_011.phpt" role="test" /> <file baseinstalldir="File" md5sum="bc49ca48623102c8ac07679fa77a3dd9" name="tests/marc_012.phpt" role="test" /> <file baseinstalldir="File" md5sum="245a3b20e0da1973535503e28efd1d3a" name="tests/marc_013.phpt" role="test" /> <file baseinstalldir="File" md5sum="ce69aa734856dd40d60d30c77bdef53a" name="tests/marc_014.phpt" role="test" /> <file baseinstalldir="File" md5sum="7b61cdd31035e60682fa92c5d519d997" name="tests/marc_015.phpt" role="test" /> <file baseinstalldir="File" md5sum="7f4f597fe1adaa3507eb87fc4875dbd2" name="tests/marc_016.phpt" role="test" /> <file baseinstalldir="File" md5sum="4262efd5fcacbd7503323681f4552430" name="tests/marc_017.phpt" role="test" /> <file baseinstalldir="File" md5sum="ee1623d7bda54ba4f741b2319b158f82" name="tests/marc_018.phpt" role="test" /> <file baseinstalldir="File" md5sum="8006c03fbab0f04377342086fafd3982" name="tests/marc_019.phpt" role="test" /> <file baseinstalldir="File" md5sum="f5ae5b25e0ac1104314433d9e5b1f7fe" name="tests/marc_020.phpt" role="test" /> <file baseinstalldir="File" md5sum="94d8f99e86585671a1b2d3043aeb6360" name="tests/marc_021.phpt" role="test" /> <file baseinstalldir="File" md5sum="bb891a890effe0e77e1759043f4846d8" name="tests/marc_022.phpt" role="test" /> <file baseinstalldir="File" md5sum="faf77dcb5cdd002c09169a14bfded65e" name="tests/marc_023.phpt" role="test" /> <file baseinstalldir="File" md5sum="0e6c4a23f5da7df64fdd4b3b1149bbee" name="tests/marc_16783.phpt" role="test" /> <file baseinstalldir="File" md5sum="4ea8b3520beda378db15960f1c50493a" name="tests/marc_field_001.phpt" role="test" /> <file baseinstalldir="File" md5sum="743850ef61df69c4340be44a03bccb5a" name="tests/marc_field_002.phpt" role="test" /> <file baseinstalldir="File" md5sum="8c765f1398b49df257d86d22ac6e4f8d" name="tests/marc_field_003.phpt" role="test" /> <file baseinstalldir="File" md5sum="d4216cf930a308e0d02553bd3914f294" name="tests/marc_field_004.phpt" role="test" /> <file baseinstalldir="File" md5sum="dd59514b474b78371ad522a3e13b76b7" name="tests/marc_field_005.phpt" role="test" /> <file baseinstalldir="File" md5sum="5295bfd02a8424acac1c91de26b552c7" name="tests/marc_field_21246.phpt" role="test" /> <file baseinstalldir="File" md5sum="6f95f09442ccf6b93df92986f58b270d" name="tests/marc_lint_001.phpt" role="test" /> <file baseinstalldir="File" md5sum="18d721f8871edd925624ccbdd15444fb" name="tests/marc_lint_002.phpt" role="test" /> <file baseinstalldir="File" md5sum="4eb86a2f4e0a74dedcb0bf2511da6ca1" name="tests/marc_lint_003.phpt" role="test" /> <file baseinstalldir="File" md5sum="10430fee0a1352d0528f1507b34c57e1" name="tests/marc_lint_004.phpt" role="test" /> <file baseinstalldir="File" md5sum="0dcd07a18577d7b22392a2214cd6436c" name="tests/marc_lint_005.phpt" role="test" /> <file baseinstalldir="File" md5sum="fd17798fc535562e5e64461f449516b2" name="tests/marc_record_001.phpt" role="test" /> <file baseinstalldir="File" md5sum="141b455ccf67a60c4eac44c77960f2e2" name="tests/marc_subfield_001.phpt" role="test" /> <file baseinstalldir="File" md5sum="b1e23464ee0eec47ddca2af9a9922926" name="tests/marc_subfield_002.phpt" role="test" /> <file baseinstalldir="File" md5sum="1d7903e8c244d647220b318b4bc758d1" name="tests/marc_xml_001.phpt" role="test" /> <file baseinstalldir="File" md5sum="22cae3c752d843b78f583dcd92801534" name="tests/marc_xml_002.phpt" role="test" /> <file baseinstalldir="File" md5sum="c0716d23e0f960abf8d53ad6014a413a" name="tests/marc_xml_003.phpt" role="test" /> <file baseinstalldir="File" md5sum="7645fa19e28aca041a124fc5e2c12bd3" name="tests/marc_xml_004.phpt" role="test" /> <file baseinstalldir="File" md5sum="b08b28c3251625b8b6e4d7ab376b0185" name="tests/marc_xml_005.phpt" role="test" /> <file baseinstalldir="File" md5sum="6cd0934ddbf65d2d7e9ea5d108977ff7" name="tests/marc_xml_006.phpt" role="test" /> <file baseinstalldir="File" md5sum="ffdce4aa190268fa7cbbf3bb45383abf" name="tests/marc_xml_007.phpt" role="test" /> <file baseinstalldir="File" md5sum="998a4c1ce00ff100f39ffa9fc49a212f" name="tests/marc_xml_008.phpt" role="test" /> <file baseinstalldir="File" md5sum="a38a67c590869f2b0a4859a910fd9e89" name="tests/marc_xml_009.phpt" role="test" /> <file baseinstalldir="File" md5sum="db39c5055a570fcda12bb7c5fa1e3b4d" name="tests/marc_xml_16642.phpt" role="test" /> <file baseinstalldir="File" md5sum="dc075f4a271bd7182378a3874bd5b39e" name="tests/marc_xml_namespace.phpt" role="test" /> <file baseinstalldir="File" md5sum="208200d9a979ac360c4d326e9789b6b7" name="tests/marc_xml_namespace_prefix.phpt" role="test" /> <file baseinstalldir="File" md5sum="d87774ede82222cfc12b2c2a06f57a3a" name="tests/marc_xml_rsinger.phpt" role="test" /> <file baseinstalldir="File" md5sum="fb44e3eb69f1a37115235fc829c39542" name="tests/namespace.xml" role="test" /> <file baseinstalldir="File" md5sum="e6de4d809b0af5dd99fd352eb60616a1" name="tests/skipif.inc" role="test" /> <file baseinstalldir="File" md5sum="a0166a4ff0bc0bb283e854f11beaa793" name="tests/music.mrc" role="test" /> <file baseinstalldir="File" md5sum="993ce494befbc25dc1326527b30b4782" name="tests/music.xml" role="test" /> <file baseinstalldir="File" md5sum="6b0c87f0cd459ed7322c25d403b164cc" name="tests/bigarchive.xml" role="test" /> <file baseinstalldir="File" md5sum="be850aa6ab4ac52b8c6c214c30b574af" name="tests/onerecord.xml" role="test" /> <file baseinstalldir="File" md5sum="4f43fec7b276267eec5258044853ccc8" name="tests/sandburg.mrc" role="test" /> <file baseinstalldir="File" md5sum="e216b95f905dd240c9bde372950e4073" name="tests/sandburg.xml" role="test" /> <file baseinstalldir="File" md5sum="e81a92188ea0dcd9c108a63fb32b3f4f" name="tests/xmlescape.mrc" role="test" /> <file baseinstalldir="File" md5sum="8f9f63ed6a80191d89a2296fa4c1a30b" name="CHANGELOG" role="doc" /> <file baseinstalldir="File" md5sum="fbc093901857fcd118f065f900982c24" name="LICENSE" role="doc" /> </dir> </contents> <dependencies> <required> <php> <min>5.6</min> </php> <pearinstaller> <min>1.4.0</min> </pearinstaller> </required> <optional> <package> <name>Validate_ISPN</name> <channel>pear.php.net</channel> </package> </optional> </dependencies> <phprelease /> </package> PK�����u]zWzD ��D �� ��.pkgxml/Pear_Net_IDNA2-0.2.0.xmlnu�[��������<?xml version="1.0" encoding="UTF-8"?> <package packagerversion="1.10.3" version="2.0" xmlns="https://pear.php.net/dtd/package-2.0" xmlns:tasks="https://pear.php.net/dtd/tasks-1.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://pear.php.net/dtd/tasks-1.0 https://pear.php.net/dtd/tasks-1.0.xsd https://pear.php.net/dtd/package-2.0 https://pear.php.net/dtd/package-2.0.xsd"> <name>Net_IDNA2</name> <channel>pear.php.net</channel> <summary>Punycode encoding and decoding.</summary> <description>This package helps you to encode and decode punycode strings easily.</description> <lead> <name>Stefan Neufeind</name> <user>neufeind</user> <email>pear.neufeind@speedpartner.de</email> <active>yes</active> </lead> <lead> <name>Daniel O'Connor</name> <user>doconnor</user> <email>daniel.oconnor@gmail.com</email> <active>no</active> </lead> <date>2017-03-06</date> <time>20:40:58</time> <version> <release>0.2.0</release> <api>0.2.0</api> </version> <stability> <release>beta</release> <api>beta</api> </stability> <license uri="https://www.gnu.org/copyleft/lesser.html">LGPL</license> <notes> * Set minimum PHP version to 5.4.0 * Set minimum PEAR version to 1.10.1 * Bug #19375: Add static to the fuction getInstance * Bug #21123: Signing the source package </notes> <contents> <dir baseinstalldir="/" name="/"> <file baseinstalldir="/" md5sum="41766020ff8f63f695c9bf7e86040e70" name="Net/IDNA2.php" role="php" /> <file baseinstalldir="/" md5sum="72f605f2f6d9d56e07bb6bcec099d03a" name="Net/IDNA2/Exception.php" role="php" /> <file baseinstalldir="/" md5sum="06c4217024082f0f3b6c5a7e61ac7130" name="Net/IDNA2/Exception/Nameprep.php" role="php" /> <file baseinstalldir="/" md5sum="999210e6bd489aba06e5121a2788956f" name="tests/Net_IDNA2Test.php" role="test" /> <file baseinstalldir="/" md5sum="2996ea57df9e5e3153da8a94fbb3c603" name="tests/draft-josefsson-idn-test-vectors.php" role="test" /> </dir> </contents> <dependencies> <required> <php> <min>5.4.0</min> </php> <pearinstaller> <min>1.10.1</min> </pearinstaller> </required> </dependencies> <phprelease /> <changelog> <release> <version> <release>0.1.0</release> <api>0.1.0</api> </version> <stability> <release>beta</release> <api>beta</api> </stability> <date>2010-06-03</date> <license uri="https://www.gnu.org/copyleft/lesser.html">LGPL</license> <notes> QA Release Bug #17430 Multiple Net_IDNA class declarations Warning: This package is now split between Net_IDNA (php4) and Net_IDNA2 (php5) </notes> </release> <release> <version> <release>0.2.0</release> <api>0.2.0</api> </version> <stability> <release>beta</release> <api>beta</api> </stability> <date>2017-03-06</date> <license uri="https://www.gnu.org/copyleft/lesser.html">LGPL</license> <notes> * Set minimum PHP version to 5.4.0 * Set minimum PEAR version to 1.10.1 * Bug #19375: Add static to the fuction getInstance * Bug #21123: Signing the source package </notes> </release> </changelog> </package> PK�����u]Z2iH��H����.pkgxml/Pear_Mail-1.4.1.xmlnu�[��������<?xml version="1.0" encoding="UTF-8"?> <package packagerversion="1.10.3" version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd"> <name>Mail</name> <channel>pear.php.net</channel> <summary>Class that provides multiple interfaces for sending emails</summary> <description>PEAR's Mail package defines an interface for implementing mailers under the PEAR hierarchy. It also provides supporting functions useful to multiple mailer backends. Currently supported backends include: PHP's native mail() function, sendmail, and SMTP. This package also provides a RFC822 email address list validation utility class.</description> <lead> <name>Chuck Hagenbuch</name> <user>chagenbu</user> <email>chuck@horde.org</email> <active>no</active> </lead> <developer> <name>Richard Heyes</name> <user>richard</user> <email>richard@phpguru.org</email> <active>no</active> </developer> <developer> <name>Aleksander Machniak</name> <user>alec</user> <email>alec@alec.pl</email> <active>yes</active> </developer> <date>2017-04-11</date> <time>17:26:44</time> <version> <release>1.4.1</release> <api>1.3.0</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <license uri="https://opensource.org/licenses/BSD-3-Clause">New BSD License</license> <notes> * Loosen recognition of "queued as" server response (PR #10) * Bug #20463: domain-literal parsing error * Bug #20513: Mail_smtp::send() doesn't close socket for smtp connection </notes> <contents> <dir baseinstalldir="/" name="/"> <file baseinstalldir="/" md5sum="8210c33901d415a2692944291632bf34" name="LICENSE" role="doc" /> <file baseinstalldir="/" md5sum="4e86cd3b980f73ef320988a1b299ee07" name="Mail/mail.php" role="php" /> <file baseinstalldir="/" md5sum="360b7b613c98c7703151c50a6e74c367" name="Mail/mock.php" role="php" /> <file baseinstalldir="/" md5sum="30ce63a4a2c4558b3752b1c302e6e508" name="Mail/null.php" role="php" /> <file baseinstalldir="/" md5sum="7199f4e7b07919082a804edb8680c811" name="Mail/RFC822.php" role="php" /> <file baseinstalldir="/" md5sum="5dd0b6ff126608818f44f5866b61b3d0" name="Mail/sendmail.php" role="php" /> <file baseinstalldir="/" md5sum="1d236356d52f3dfa13b740a48a821586" name="Mail/smtp.php" role="php" /> <file baseinstalldir="/" md5sum="853b55cf4803df8caaaa0dca363971ff" name="Mail/smtpmx.php" role="php" /> <file baseinstalldir="/" md5sum="3077f0c01f72cc29a6f8f0175e7fc8a7" name="Mail.php" role="php" /> <file baseinstalldir="/" md5sum="d66aa2a2f0bfe33f8a67d749a1a4d345" name="tests/9137.phpt" role="test" /> <file baseinstalldir="/" md5sum="75d10361f686f1cc16637a9364e3eab7" name="tests/9137_2.phpt" role="test" /> <file baseinstalldir="/" md5sum="63715aad2b5b3ae35c6b05acf04d9ad7" name="tests/13659.phpt" role="test" /> <file baseinstalldir="/" md5sum="e99f00d8f07232e0f129dd77ae9699c7" name="tests/bug17178.phpt" role="test" /> <file baseinstalldir="/" md5sum="c2036980390981cd6b89c1e5c903913e" name="tests/bug17317.phpt" role="test" /> <file baseinstalldir="/" md5sum="7b0eae971fe7595e7c1a563fbfcfee90" name="tests/rfc822.phpt" role="test" /> <file baseinstalldir="/" md5sum="67becdb1027cefcb8dff1b691da630ab" name="tests/smtp_error.phpt" role="test" /> </dir> </contents> <dependencies> <required> <php> <min>5.2.1</min> </php> <pearinstaller> <min>1.5.6</min> </pearinstaller> </required> <optional> <package> <name>Net_SMTP</name> <channel>pear.php.net</channel> <min>1.4.1</min> </package> </optional> </dependencies> <phprelease /> </package> PK�����u]c���� ��.pkgxml/Pear_Auth_SASL-1.1.0.xmlnu�[��������<?xml version="1.0" encoding="UTF-8"?> <package packagerversion="1.10.3" version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd"> <name>Auth_SASL</name> <channel>pear.php.net</channel> <summary>Abstraction of various SASL mechanism responses</summary> <description>Provides code to generate responses to common SASL mechanisms, including: - Digest-MD5 - Cram-MD5 - Plain - Anonymous - Login (Pseudo mechanism) - SCRAM</description> <lead> <name>Anish Mistry</name> <user>amistry</user> <email>amistry@am-productions.biz</email> <active>no</active> </lead> <lead> <name>Richard Heyes</name> <user>richard</user> <email>richard@php.net</email> <active>no</active> </lead> <lead> <name>Michael Bretterklieber</name> <user>mbretter</user> <email>michael@bretterklieber.com</email> <active>no</active> </lead> <date>2017-03-07</date> <time>14:04:34</time> <version> <release>1.1.0</release> <api>1.1.0</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD</license> <notes> * Set minimum PHP version to 5.4.0 * Set minimum PEAR version to 1.10.1 * Request #21033: PHP warning depreciated </notes> <contents> <dir name="/"> <file md5sum="60f7b5ba4d05fe0e518292963b14bddb" name="Auth/SASL/Anonymous.php" role="php" /> <file md5sum="c2c817e4775b6f63f07ddb0c9cbd88b5" name="Auth/SASL/Common.php" role="php" /> <file md5sum="c6b3b3a4e0aec6a4e0728732ef6babc9" name="Auth/SASL/CramMD5.php" role="php" /> <file md5sum="509e431141489a77a991401d64f15e9e" name="Auth/SASL/DigestMD5.php" role="php" /> <file md5sum="1d7478dd9dc5734ec9e16c158dcb6f76" name="Auth/SASL/External.php" role="php" /> <file md5sum="3a0abcf277374b24262807150451b55e" name="Auth/SASL/Login.php" role="php" /> <file md5sum="bde1dcf2780d042c1de12e20a696e945" name="Auth/SASL/Plain.php" role="php" /> <file md5sum="e99f9f71abc36d64ca8e17ad6e5e7631" name="Auth/SASL/SCRAM.php" role="php" /> <file md5sum="b93e37947e1dd90e5fb639a1734f7a71" name="Auth/SASL.php" role="php" /> </dir> </contents> <dependencies> <required> <php> <min>5.4.0</min> </php> <pearinstaller> <min>1.10.1</min> </pearinstaller> </required> </dependencies> <phprelease /> <changelog> <release> <version> <release>1.1.0</release> <api>1.1.0</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <date>2017-03-07</date> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD</license> <notes> * Set minimum PHP version to 5.4.0 * Set minimum PEAR version to 1.10.1 * Request #21033: PHP warning depreciated </notes> </release> <release> <version> <release>1.0.6</release> <api>1.0.3</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <date>2011-09-27</date> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD</license> <notes> QA release * Bug #18856: Authentication warnings because of wrong Auth_SASL::factory argument [kguest] </notes> </release> <release> <version> <release>1.0.5</release> <api>1.0.3</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <date>2011-09-04</date> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD</license> <notes> QA release * Added support for any mechanism of the SCRAM family; with thanks to Jehan Pagès. [kguest] * crammd5 and digestmd5 mechanisms name deprecated in favour of IANA registered names 'cram-md5' and 'digest-md5'; with thanks to Jehan Pagès. [kguest] </notes> </release> <release> <version> <release>1.0.4</release> <api>1.0.3</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <date>2010-02-07</date> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD</license> <notes> QA release * Fix bug #16624: open_basedir restriction warning in DigestMD5.php [till] </notes> </release> <release> <version> <release>1.0.3</release> <api>1.0.3</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <date>2009-08-05</date> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD</license> <notes> QA release * Move SVN to proper directory structure [cweiske] * Fix Bug #8775: Error in package.xml * Fix Bug #14671: Security issue due to seeding random number generator [cweiske] </notes> </release> <release> <version> <release>1.0.2</release> <api>1.0.2</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <date>2006-05-21</date> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD</license> <notes> * Fixed Bug #2143 Auth_SASL_DigestMD5::getResponse() generates invalid response * Fixed Bug #6611 Suppress PHP 5 Notice Errors * Fixed Bug #2154 realm isn't contained in challange </notes> </release> <release> <version> <release>1.0.1</release> <api>1.0.1</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <date>2003-09-11</date> <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD</license> <notes> * Added authcid/authzid separation in PLAIN and DIGEST-MD5. </notes> </release> </changelog> </package> PK�����u]#r �� �� ��.pkgxml/Pear_Net_SMTP-1.10.0.xmlnu�[��������<?xml version="1.0" encoding="UTF-8"?> <package packagerversion="1.10.12" version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd"> <name>Net_SMTP</name> <channel>pear.php.net</channel> <summary>An implementation of the SMTP protocol</summary> <description>Provides an implementation of the SMTP protocol using PEAR's Net_Socket class.</description> <lead> <name>Jon Parise</name> <user>jon</user> <email>jon@php.net</email> <active>yes</active> </lead> <lead> <name>Chuck Hagenbuch</name> <user>chagenbu</user> <email>chuck@horde.org</email> <active>yes</active> </lead> <date>2021-03-19</date> <time>18:39:33</time> <version> <release>1.10.0</release> <api>1.4.0</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <license uri="https://opensource.org/licenses/bsd-license.php">BSD-2-Clause</license> <notes> * Add the starttls() method </notes> <contents> <dir baseinstalldir="/" name="/"> <file baseinstalldir="/" md5sum="5ef820d1bc73898b55a153576953fe70" name="examples/basic.php" role="doc" /> <file baseinstalldir="/" md5sum="0cd9a0c35d1ea17d46de9b5a39fb771d" name="tests/auth.phpt" role="test" /> <file baseinstalldir="/" md5sum="89135826a107455d336071f3570ccd13" name="tests/basic.phpt" role="test" /> <file baseinstalldir="/" md5sum="8517c458ae5094ee3c31a545d51c69c8" name="tests/config.php.dist" role="test" /> <file baseinstalldir="/" md5sum="15c9cb4ef93e0aee232b503e12fc21ee" name="tests/quotedata.phpt" role="test" /> <file baseinstalldir="/" md5sum="00f931f5dd61430e6057f895decdb6af" name="LICENSE" role="doc" /> <file baseinstalldir="/" md5sum="9ddd7d9135cfe6e573cd757edf6855f2" name="README.rst" role="doc" /> <file baseinstalldir="/" md5sum="a157897ae2efc43eabd961597557243a" name="Net/SMTP.php" role="php" /> </dir> </contents> <dependencies> <required> <php> <min>5.4.0</min> </php> <pearinstaller> <min>1.10.1</min> </pearinstaller> <package> <name>Net_Socket</name> <channel>pear.php.net</channel> <min>1.0.7</min> </package> </required> <optional> <package> <name>Auth_SASL</name> <channel>pear.php.net</channel> <min>1.0.5</min> </package> </optional> </dependencies> <phprelease /> </package> PK�����u]��������.pkgxml/Pear.listnu�[��������pear.php.net/Auth_SASL pear.php.net/File_MARC pear.php.net/Mail pear.php.net/Mail_Mime pear.php.net/Mail_mimeDecode pear.php.net/Net_IDNA2 pear.php.net/Net_SMTP pear.php.net/Net_Sieve pear.php.net/Net_Socket pear.php.net/Structures_LinkedList PK�������[t]d ��d ������������������pkgxml/alt-php74-vld.xmlnu�[��������PK�������u] {+��+�������������� ��.channels/pecl.php.net.regnu�[��������PK�������u]ui< ��� ���������������!��.channels/.alias/pecl.txtnu�[��������PK�������u] ��� ���������������v��.channels/.alias/pear.txtnu�[��������PK�������u]o/ ��� �����������������.channels/.alias/phpdocs.txtnu�[��������PK�������u]5j����������������"��.channels/doc.php.net.regnu�[��������PK�������u] �� ����������������.channels/__uri.regnu�[��������PK�������u]W(��(����������������.channels/pear.php.net.regnu�[��������PK�������u]&#r���r��� ������������@��Net/IDNA2/Exception/Nameprep.phpnu�[��������PK�������u]S6���6�����������������Net/IDNA2/Exception.phpnu�[��������PK�������u]z|���� ��������������Net/SMTP.phpnu�[��������PK�������u] �� ������������;��Net/IDNA2.phpnu�[��������PK�������u]NFU��FU��������������%k�Net/Socket.phpnu�[��������PK�������u]Z��Z�� �������������Net/Sieve.phpnu�[��������PK�������u]D:��:�� ������������@x�pearcmd.phpnu�[��������PK�������u]ioK�����������������XML/RPC/Dump.phpnu�[��������PK�������u]GJW��W�������������� �XML/RPC/Server.phpnu�[��������PK�������u]c}��}�� ������������ �XML/Util.phpnu�[��������PK�������u]/=���� ��������������XML/RPC.phpnu�[��������PK�������u]P'hB&��&�������������� �Mail.phpnu�[��������PK�������u]U �� ��������������خ�PEAR/Packager.phpnu�[��������PK�������u]OWH ��H ��������������9�PEAR/PackageFile/Parser/v2.phpnu�[��������PK�������u]_=@��@���������������PEAR/PackageFile/Parser/v1.phpnu�[��������PK�������u]wv@�@��������������PEAR/PackageFile/v2.phpnu�[��������PK�������u]Ɂ��Ɂ��!������������+,�PEAR/PackageFile/Generator/v2.phpnu�[��������PK�������u]`=����!������������E�PEAR/PackageFile/Generator/v1.phpnu�[��������PK�������u]5����������������Gs�PEAR/PackageFile/v1.phpnu�[��������PK�������u]C8L�L�!������������A9 �PEAR/PackageFile/v2/Validator.phpnu�[��������PK�������u]=_��_�������������� �PEAR/PackageFile/v2/rw.phpnu�[��������PK�������u],#y+��+��������������| �PEAR/REST/11.phpnu�[��������PK�������u]Y;��;�������������� �PEAR/REST/13.phpnu�[��������PK�������u]Wf����������������; �PEAR/REST/10.phpnu�[��������PK�������u]'���������������� d �PEAR/RunTest.phpnu�[��������PK�������u]ٲ=��=�������������� �PEAR/PackageFile.phpnu�[��������PK�������u]@P����������������0 �PEAR/ChannelFile/Parser.phpnu�[��������PK�������u]`eEA��EA�� ������������7 �PEAR/REST.phpnu�[��������PK�������u]{ )�)�������������x �PEAR/Downloader/Package.phpnu�[��������PK�������u]_0��0���������������PEAR/Command.phpnu�[��������PK�������u]^D{ �� ��������������N�PEAR/Installer/Role/Www.phpnu�[��������PK�������u]Y�����������������PEAR/Installer/Role/Test.phpnu�[��������PK�������u]0c�����������������PEAR/Installer/Role/Man.xmlnu�[��������PK�������u]/�����������������PEAR/Installer/Role/Cfg.xmlnu�[��������PK�������u]B��B���������������PEAR/Installer/Role/Ext.xmlnu�[��������PK�������u]?m �� ��������������j�PEAR/Installer/Role/Php.phpnu�[��������PK�������u]@vа�����������������PEAR/Installer/Role/Script.xmlnu�[��������PK�������u][�����������������PEAR/Installer/Role/Script.phpnu�[��������PK�������u]h&P*����������������!�PEAR/Installer/Role/Doc.xmlnu�[��������PK�������u]>1H�����������������PEAR/Installer/Role/Www.xmlnu�[��������PK�������u]K �� ���������������PEAR/Installer/Role/Ext.phpnu�[��������PK�������u]B] ����������������D�PEAR/Installer/Role/Test.xmlnu�[��������PK�������u]*Y| %��%��������������"�PEAR/Installer/Role/Man.phpnu�[��������PK�������u]fsz�����������������PEAR/Installer/Role/Data.xmlnu�[��������PK�������u]zq����������������p�PEAR/Installer/Role/Php.xmlnu�[��������PK�������u]p"��"��������������h�PEAR/Installer/Role/Src.xmlnu�[��������PK�������u] �� ���������������PEAR/Installer/Role/Doc.phpnu�[��������PK�������u]?G��G��������������-�PEAR/Installer/Role/Common.phpnu�[��������PK�������u]Ƥ�����������������PEAR/Installer/Role/Cfg.phpnu�[��������PK�������u]sr��r��������������%�PEAR/Installer/Role/Src.phpnu�[��������PK�������u] ����������������I)�PEAR/Installer/Role/Data.phpnu�[��������PK�������u]VZ����������������,�PEAR/Installer/Role.phpnu�[��������PK�������u]،w��������������K�PEAR/Installer.phpnu�[��������PK�������u]l(e��������������]�PEAR/Downloader.phpnu�[��������PK�������u]r"����������������_�PEAR/ChannelFile.phpnu�[��������PK�������u]$(�(�������������&�PEAR/Registry.phpnu�[��������PK�������u].4����������������O�PEAR/Frontend.phpnu�[��������PK�������u]c_��_��������������i�PEAR/DependencyDB.phpnu�[��������PK�������u]TI��I��������������(�PEAR/Builder.phpnu�[��������PK�������u](Pz����������������c�PEAR/Proxy.phpnu�[��������PK�������u]p����������������)�PEAR/Dependency2.phpnu�[��������PK�������u]ym6��m6���������������PEAR/Exception.phpnu�[��������PK�������u]b �� ��������������%�PEAR/ErrorStack.phpnu�[��������PK�������u][ W����������������۩�PEAR/XMLParser.phpnu�[��������PK�������u]���������������PEAR/Config.phpnu�[��������PK�������u]jy9��9��������������x�PEAR/Validator/PECL.phpnu�[��������PK�������u]Zbg��bg���������������PEAR/Common.phpnu�[��������PK�������u]s6 ��6 ��������������C�PEAR/Command/Config.xmlnu�[��������PK�������u]j!��!��������������Q�PEAR/Command/Install.xmlnu�[��������PK�������u],_h/��h/��������������Qs�PEAR/Command/Test.phpnu�[��������PK�������u] #S ��S ���������������PEAR/Command/Build.phpnu�[��������PK�������u] \ �� ���������������PEAR/Command/Remote.xmlnu�[��������PK�������u]u����������������ͺ�PEAR/Command/Registry.xmlnu�[��������PK�������u]������������������PEAR/Command/Mirror.phpnu�[��������PK�������u],t"u��"u���������������PEAR/Command/Remote.phpnu�[��������PK�������u]d֣S����������������bI�PEAR/Command/Pickle.xmlnu�[��������PK�������u] u����������������DN�PEAR/Command/Build.xmlnu�[��������PK�������u]P>��>��������������P�PEAR/Command/Pickle.phpnu�[��������PK�������u]0(;rʹ��ʹ��������������l�PEAR/Command/Registry.phpnu�[��������PK�������u]݄<i��i��������������C�PEAR/Command/Mirror.xmlnu�[��������PK�������u]�%q����������������2F�PEAR/Command/Channels.phpnu�[��������PK�������u]Z h6��6�������������� �PEAR/Command/Package.xmlnu�[��������PK�������u]%Fi��i���������������PEAR/Command/Test.xmlnu�[��������PK�������u]+9 Ҝ��Ҝ��������������L�PEAR/Command/Package.phpnu�[��������PK�������u]4{����������������f�PEAR/Command/Auth.xmlnu�[��������PK�������u]zk<��k<��������������w�PEAR/Command/Config.phpnu�[��������PK�������u]%sp �� ��������������)�PEAR/Command/Common.phpnu�[��������PK�������u]nmi?;��;���������������PEAR/Command/Install.phpnu�[��������PK�������u]wz��z�������������� �PEAR/Command/Channels.xmlnu�[��������PK�������u]X �� ���������������PEAR/Command/Auth.phpnu�[��������PK�������u] Md��Md���������������PEAR/Frontend/CLI.phpnu�[��������PK�������u] ����������������2�PEAR/Task/Unixeol.phpnu�[��������PK�������u]\k����������������;�PEAR/Task/Unixeol/rw.phpnu�[��������PK�������u]ZEx9��x9��������������VA�PEAR/Task/Postinstallscript.phpnu�[��������PK�������u]&%75)��)��������������{�PEAR/Task/Windowseol/rw.phpnu�[��������PK�������u]D$�����������������PEAR/Task/Windowseol.phpnu�[��������PK�������u]3}����������������̉�PEAR/Task/Replace/rw.phpnu�[��������PK�������u]& i.����"������������+�PEAR/Task/Postinstallscript/rw.phpnu�[��������PK�������u]-!�����������������PEAR/Task/Common.phpnu�[��������PK�������u]JD�����������������PEAR/Task/Replace.phpnu�[��������PK�������u]gkU��U��������������:�PEAR/Validate.phpnu�[��������PK�������u]J} ��} ��������������p2�Auth/SASL/Anonymous.phpnu�[��������PK�������u]%ׅtg!��g!��������������4@�Auth/SASL/DigestMD5.phpnu�[��������PK�������u]vRr, ��, ��������������a�Auth/SASL/External.phpnu�[��������PK�������u]< O ��O ��������������Tn�Auth/SASL/Login.phpnu�[��������PK�������u]ќ0��0��������������z�Auth/SASL/SCRAM.phpnu�[��������PK�������u]= ��= ��������������$�Auth/SASL/Plain.phpnu�[��������PK�������u]T�����������������Auth/SASL/Common.phpnu�[��������PK�������u]P(~T ��T ���������������Auth/SASL/CramMD5.phpnu�[��������PK�������u]2r���� �������������Auth/SASL.phpnu�[��������PK�������u]T,��,�� �������������OS/Guess.phpnu�[��������PK�������u]ҵ3����>�������������test/Mail_mimeDecode/tests/semicolon_content_type_bug1724.phptnu�[��������PK�������u]s%����2�������������test/Mail_mimeDecode/tests/parse_header_value.phptnu�[��������PK�������u]Zx����5������������%�test/Structures_LinkedList/tests/single_link_002.phptnu�[��������PK�������u]骗����.������������(�test/Structures_LinkedList/tests/link_006.phptnu�[��������PK�������u]o����.������������2-�test/Structures_LinkedList/tests/link_003.phptnu�[��������PK�������u])����.������������x1�test/Structures_LinkedList/tests/link_002.phptnu�[��������PK�������u]1����5������������y4�test/Structures_LinkedList/tests/single_link_007.phptnu�[��������PK�������u]4����5������������9�test/Structures_LinkedList/tests/single_link_001.phptnu�[��������PK�������u] ����.������������=�test/Structures_LinkedList/tests/link_001.phptnu�[��������PK�������u]K����5������������&B�test/Structures_LinkedList/tests/single_link_003.phptnu�[��������PK�������u])y-��-��5������������F�test/Structures_LinkedList/tests/single_link_004.phptnu�[��������PK�������u]|����5������������I�test/Structures_LinkedList/tests/SingleLinkTester.phpnu�[��������PK�������u]sDH��H��.������������EK�test/Structures_LinkedList/tests/link_007.phptnu�[��������PK�������u]髂[����5������������P�test/Structures_LinkedList/tests/single_link_006.phptnu�[��������PK�������u]����.������������<U�test/Structures_LinkedList/tests/link_005.phptnu�[��������PK�������u]#,E����5������������uZ�test/Structures_LinkedList/tests/single_link_005.phptnu�[��������PK�������u]( �� ��.������������_�test/Structures_LinkedList/tests/link_004.phptnu�[��������PK�������u]����/������������:b�test/Structures_LinkedList/tests/LinkTester.phpnu�[��������PK�������u]E m��m��&������������d�test/Net_IDNA2/tests/Net_IDNA2Test.phpnu�[��������PK�������u]?7E��E��9������������Hm�test/Net_IDNA2/tests/draft-josefsson-idn-test-vectors.phpnu�[��������PK�������u]�X��X�� ������������Ȳ�test/XML_RPC/tests/test_Dump.phpnu�[��������PK�������u]3l*��*�� ������������p�test/XML_RPC/tests/protoport.phpnu�[��������PK�������u]|E �� ��)�������������test/XML_RPC/tests/empty-value-struct.phpnu�[��������PK�������u]̢ �� ��������������+�test/XML_RPC/tests/types.phpnu�[��������PK�������u]J����������������n�test/XML_RPC/tests/encode.phpnu�[��������PK�������u]. ����"��������������test/XML_RPC/tests/extra-lines.phpnu�[��������PK�������u]$]����"������������ �test/XML_RPC/tests/empty-value.phpnu�[��������PK�������u]B�������������������test/XML_RPC/tests/allgot.incnu�[��������PK�������u]b))��)��%������������?�test/XML_RPC/tests/actual-request.phpnu�[��������PK�������u]��$�������������test/Net_Sieve/tests/largescript.sivnu�[��������PK�������u]Ynp���p���$������������;"�test/Net_Sieve/tests/config.php.distnu�[��������PK�������u]�g-��-��"������������<"�test/Net_Sieve/tests/SieveTest.phpnu�[��������PK�������u]g+����(������������j"�test/Mail_Mime/tests/test_Bug_13444.phptnu�[��������PK�������u]UiE!��E!��2������������m"�test/Mail_Mime/tests/headers_without_mbstring.phptnu�[��������PK�������u]����(������������]"�test/Mail_Mime/tests/test_Bug_15320.phptnu�[��������PK�������u]ܶgh��h��)������������"�test/Mail_Mime/tests/test_Bug_9722_1.phptnu�[��������PK�������u]29r������'������������D"�test/Mail_Mime/tests/encoding_case.phptnu�[��������PK�������u](V,����(������������"�test/Mail_Mime/tests/test_Bug_12411.phptnu�[��������PK�������u]-b2����(������������p"�test/Mail_Mime/tests/test_Bug_13032.phptnu�[��������PK�������u]Iz��z��(������������"�test/Mail_Mime/tests/test_Bug_20563.phptnu�[��������PK�������u]Cz2}��}��(������������"�test/Mail_Mime/tests/test_Bug_12165.phptnu�[��������PK�������u]%+2P��P��(������������"�test/Mail_Mime/tests/test_Bug_18083.phptnu�[��������PK�������u]e@Q_��_��(������������2"�test/Mail_Mime/tests/test_Bug_14780.phptnu�[��������PK�������u]5����(������������"�test/Mail_Mime/tests/test_Bug_21098.phptnu�[��������PK�������u] Ǟ �� ��2������������ǣ"�test/Mail_Mime/tests/test_linebreak_larger_76.phptnu�[��������PK�������u]1d����(������������,"�test/Mail_Mime/tests/test_Bug_17025.phptnu�[��������PK�������u]`~@����*������������ "�test/Mail_Mime/tests/test_Bug_12385_1.phptnu�[��������PK�������u]o �� ��(������������"�test/Mail_Mime/tests/test_Bug_14529.phptnu�[��������PK�������u]MU.��.��(������������"�test/Mail_Mime/tests/test_Bug_20273.phptnu�[��������PK�������u]Xb����(������������|"�test/Mail_Mime/tests/test_Bug_14779.phptnu�[��������PK�������u]9:��:��*������������"�test/Mail_Mime/tests/test_Bug_10816_1.phptnu�[��������PK�������u]Eo��o��(������������Q"�test/Mail_Mime/tests/test_Bug_13962.phptnu�[��������PK�������u]@/N��N��(������������"�test/Mail_Mime/tests/test_Bug_21206.phptnu�[��������PK�������u]zŬ����(������������"�test/Mail_Mime/tests/test_Bug_11731.phptnu�[��������PK�������u]X#��#��(������������"�test/Mail_Mime/tests/test_Bug_19497.phptnu�[��������PK�������u]8����)������������="�test/Mail_Mime/tests/test_Bug_3513_1.phptnu�[��������PK�������u]2!B����,������������q"�test/Mail_Mime/tests/test_linebreak_dot.phptnu�[��������PK�������u]%B��B��'������������e"�test/Mail_Mime/tests/test_Bug_GH16.phptnu�[��������PK�������u])#p��p��(������������"�test/Mail_Mime/tests/test_Bug_18772.phptnu�[��������PK�������u]a[������(������������"�test/Mail_Mime/tests/class-filename.phptnu�[��������PK�������u]ZXHw��w��)������������"�test/Mail_Mime/tests/test_Bug_3513_3.phptnu�[��������PK�������u]Y����'������������"�test/Mail_Mime/tests/test_Bug_GH26.phptnu�[��������PK�������u] (��(��*������������*"�test/Mail_Mime/tests/test_Bug_10596_1.phptnu�[��������PK�������u]Qi"-��-��(������������"�test/Mail_Mime/tests/test_Bug_11381.phptnu�[��������PK�������u]v����)������������1"�test/Mail_Mime/tests/test_Bug_8541_1.phptnu�[��������PK�������u]k0����(������������}"�test/Mail_Mime/tests/test_Bug_20564.phptnu�[��������PK�������u]e;I����(������������"�test/Mail_Mime/tests/test_Bug_21205.phptnu�[��������PK�������u]M-\����(������������Y"�test/Mail_Mime/tests/test_Bug_17175.phptnu�[��������PK�������u]qS����*������������h"�test/Mail_Mime/tests/test_Bug_10999_1.phptnu�[��������PK�������u]RoU��U��(������������"�test/Mail_Mime/tests/test_Bug_20226.phptnu�[��������PK�������u]|J��J��8������������Z"�test/Mail_Mime/tests/sleep_wakeup_EOL-bug3488-part2.phptnu�[��������PK�������u]Ԣ`��`��(������������ "�test/Mail_Mime/tests/test_Bug_21255.phptnu�[��������PK�������u]-7c7��7��)������������"�test/Mail_Mime/tests/test_Bug_3513_2.phptnu�[��������PK�������u]''��'��)������������T"�test/Mail_Mime/tests/test_Bug_8386_1.phptnu�[��������PK�������u]i;����)������������"�test/Mail_Mime/tests/test_Bug_7561_1.phptnu�[��������PK�������u];{����'������������"�test/Mail_Mime/tests/test_Bug_GH19.phptnu�[��������PK�������u]YcLY��Y��(������������#�test/Mail_Mime/tests/test_Bug_16539.phptnu�[��������PK�������u]����(������������!#�test/Mail_Mime/tests/test_Bug_21027.phptnu�[��������PK�������u]Yak!��!��8������������v>#�test/Mail_Mime/tests/sleep_wakeup_EOL-bug3488-part1.phptnu�[��������PK�������u]ّ�B �� ��*������������@#�test/Mail_Mime/tests/qp_encoding_test.phptnu�[��������PK�������u]B&����(������������>O#�test/Mail_Mime/tests/test_Bug_12466.phptnu�[��������PK�������u][b����3������������SQ#�test/Mail_Mime/tests/content_transfer_encoding.phptnu�[��������PK�������u]᠗"��"��/������������RU#�test/Mail_Mime/tests/headers_with_mbstring.phptnu�[��������PK�������u]����)������������Hx#�test/Console_Getopt/tests/001-getopt.phptnu�[��������PK�������u]|E��E��'������������o}#�test/Console_Getopt/tests/bug13140.phptnu�[��������PK�������u]����'������������ #�test/Console_Getopt/tests/bug11068.phptnu�[��������PK�������u]����'������������{#�test/Console_Getopt/tests/bug10557.phptnu�[��������PK�������u]*W����������������#�test/Net_SMTP/tests/basic.phptnu�[��������PK�������u]6����#������������#�test/Net_SMTP/tests/config.php.distnu�[��������PK�������u]߁Q����"������������#�test/Net_SMTP/tests/quotedata.phptnu�[��������PK�������u]<ȸB!��!��������������ޖ#�test/Net_SMTP/tests/auth.phptnu�[��������PK�������u]T��T��*������������L#�test/XML_Util/tests/CreateCommentTests.phpnu�[��������PK�������u]>M����$������������#�test/XML_Util/tests/Bug4950Tests.phpnu�[��������PK�������u]zt����,������������'#�test/XML_Util/tests/ReverseEntitiesTests.phpnu�[��������PK�������u]C����,������������Y#�test/XML_Util/tests/ReplaceEntitiesTests.phpnu�[��������PK�������u]Yq����%������������#�test/XML_Util/tests/Bug21184Tests.phpnu�[��������PK�������u]یu������'������������#�test/XML_Util/tests/ApiVersionTests.phpnu�[��������PK�������u]e>4��4��/������������#�test/XML_Util/tests/CreateTagFromArrayTests.phpnu�[��������PK�������u]rv����'������������#�test/XML_Util/tests/RaiseErrorTests.phpnu�[��������PK�������u]|\5����.������������ #�test/XML_Util/tests/CollapseEmptyTagsTests.phpnu�[��������PK�������u]ܬ$����2������������j $�test/XML_Util/tests/GetDocTypeDeclarationTests.phpnu�[��������PK�������u]G��G��/������������$�test/XML_Util/tests/SplitQualifiedNameTests.phpnu�[��������PK�������u]~$[e��e��-������������e$�test/XML_Util/tests/CreateEndElementTests.phpnu�[��������PK�������u]Gs����$������������'$�test/XML_Util/tests/Bug5392Tests.phpnu�[��������PK�������u]G����%������������z$�test/XML_Util/tests/Bug21177Tests.phpnu�[��������PK�������u]4ej��j��/������������!$�test/XML_Util/tests/CreateCDataSectionTests.phpnu�[��������PK�������u]ݑh����(������������#$�test/XML_Util/tests/IsValidNameTests.phpnu�[��������PK�������u]!����)������������+$�test/XML_Util/tests/AbstractUnitTests.phpnu�[��������PK�������u]YR"��"��/������������-$�test/XML_Util/tests/CreateStartElementTests.phpnu�[��������PK�������u]m4*��*��&������������OC$�test/XML_Util/tests/CreateTagTests.phpnu�[��������PK�������u]Df:����.������������b$�test/XML_Util/tests/GetXmlDeclarationTests.phpnu�[��������PK�������u]۩����%������������g$�test/XML_Util/tests/Bug18343Tests.phpnu�[��������PK�������u]Zt����/������������n$�test/XML_Util/tests/AttributesToStringTests.phpnu�[��������PK�������u]�����&������������Q$�test/File_MARC/tests/marc_xml_005.phptnu�[��������PK�������u]#" )�� )��"������������$�test/File_MARC/tests/marc_022.phptnu�[��������PK�������u]\.iv��v��!������������$�test/File_MARC/tests/sandburg.mrcnu�[��������PK�������u]E4kL �� ��"������������$�test/File_MARC/tests/marc_001.phptnu�[��������PK�������u]#c �� ��"������������$�test/File_MARC/tests/onerecord.xmlnu�[��������PK�������u]F-/��/��(������������$�test/File_MARC/tests/marc_field_002.phptnu�[��������PK�������u]rP �� ��&������������$�test/File_MARC/tests/marc_xml_004.phptnu�[��������PK�������u]0S����+������������$�test/File_MARC/tests/marc_subfield_001.phptnu�[��������PK�������u].%`��`��"������������3$�test/File_MARC/tests/marc_010.phptnu�[��������PK�������u]_X����(������������$�test/File_MARC/tests/marc_field_004.phptnu�[��������PK�������u]2.i ��i ��"�������������%�test/File_MARC/tests/marc_018.phptnu�[��������PK�������u]!Ņ\����&������������ %�test/File_MARC/tests/marc_xml_001.phptnu�[��������PK�������u]<-��-��+������������+%�test/File_MARC/tests/marc_subfield_002.phptnu�[��������PK�������u]_|6 ��6 ��'������������\0%�test/File_MARC/tests/marc_lint_002.phptnu�[��������PK�������u]y �� ��'������������9%�test/File_MARC/tests/marc_lint_003.phptnu�[��������PK�������u](Y����"������������+E%�test/File_MARC/tests/xmlescape.mrcnu�[��������PK�������u]~N0:��:�� ������������UH%�test/File_MARC/tests/example.mrcnu�[��������PK�������u]泮����������������O%�test/File_MARC/tests/music.mrcnu�[��������PK�������u]jS �� ��"������������`%�test/File_MARC/tests/marc_015.phptnu�[��������PK�������u]a!����"������������9t%�test/File_MARC/tests/namespace.xmlnu�[��������PK�������u]}& G��G��'������������$%�test/File_MARC/tests/marc_lint_004.phptnu�[��������PK�������u]2������������������¨%�test/File_MARC/tests/skipif.incnu�[��������PK�������u]9D��D��"������������©%�test/File_MARC/tests/marc_017.phptnu�[��������PK�������u]����,������������X%�test/File_MARC/tests/marc_xml_namespace.phptnu�[��������PK�������u]`����"������������%�test/File_MARC/tests/marc_012.phptnu�[��������PK�������u]cܯ����&������������%�test/File_MARC/tests/marc_xml_006.phptnu�[��������PK�������u]c����(������������%�test/File_MARC/tests/marc_xml_16642.phptnu�[��������PK�������u]{ �� ��*������������%�test/File_MARC/tests/marc_xml_rsinger.phptnu�[��������PK�������u]F;Re%��e%��"������������%�test/File_MARC/tests/marc_004.phptnu�[��������PK�������u]B1 �� ��'������������%�test/File_MARC/tests/marc_lint_005.phptnu�[��������PK�������u]s}����3������������ &�test/File_MARC/tests/marc_xml_namespace_prefix.phptnu�[��������PK�������u]}۶\p��p��$������������ &�test/File_MARC/tests/bad_example.xmlnu�[��������PK�������u] ����(������������n)&�test/File_MARC/tests/marc_field_005.phptnu�[��������PK�������u]p̎u1��u1��"������������-&�test/File_MARC/tests/marc_016.phptnu�[��������PK�������u](N��N��������������_&�test/File_MARC/tests/camel.mrcnu�[��������PK�������u])] �� ��"������������ {&�test/File_MARC/tests/marc_005.phptnu�[��������PK�������u]W)��)��"������������!&�test/File_MARC/tests/marc_019.phptnu�[��������PK�������u]=O �� ��!������������&�test/File_MARC/tests/sandburg.xmlnu�[��������PK�������u] VU,��,��*������������&�test/File_MARC/tests/marc_field_21246.phptnu�[��������PK�������u]O~iK!��K!��"������������|&�test/File_MARC/tests/marc_013.phptnu�[��������PK�������u]ye@����&������������&�test/File_MARC/tests/marc_xml_007.phptnu�[��������PK�������u]44-����(������������I&�test/File_MARC/tests/marc_field_003.phptnu�[��������PK�������u]1��1��&������������?&�test/File_MARC/tests/marc_xml_008.phptnu�[��������PK�������u] \����'������������ '�test/File_MARC/tests/marc_lint_001.phptnu�[��������PK�������u]Y��Y��&������������'�test/File_MARC/tests/marc_xml_009.phptnu�[��������PK�������u]����"������������'�test/File_MARC/tests/marc_008.phptnu�[��������PK�������u]+W �� ��#������������!'�test/File_MARC/tests/bigarchive.xmlnu�[��������PK�������u]x;#��#��"������������/'�test/File_MARC/tests/marc_006.phptnu�[��������PK�������u]kP����"������������t5'�test/File_MARC/tests/marc_023.phptnu�[��������PK�������u]f~����(������������7'�test/File_MARC/tests/marc_field_001.phptnu�[��������PK�������u]%Hh��h��"������������;'�test/File_MARC/tests/marc_003.phptnu�[��������PK�������u]S3 �� ��"������������sA'�test/File_MARC/tests/marc_021.phptnu�[��������PK�������u]p޸����"������������T'�test/File_MARC/tests/marc_007.phptnu�[��������PK�������u]N&��&��&������������Y'�test/File_MARC/tests/marc_xml_002.phptnu�[��������PK�������u]5;-��-��������������Wh'�test/File_MARC/tests/music.xmlnu�[��������PK�������u]ԛ �� ��"������������*'�test/File_MARC/tests/marc_014.phptnu�[��������PK�������u]f=��=��$������������o'�test/File_MARC/tests/bad_example.mrcnu�[��������PK�������u]e �� ��"�������������'�test/File_MARC/tests/marc_011.phptnu�[��������PK�������u]Ҕ �� ��$������������'�test/File_MARC/tests/marc_16783.phptnu�[��������PK�������u]7����"������������#'�test/File_MARC/tests/marc_009.phptnu�[��������PK�������u]81��1��)������������{'�test/File_MARC/tests/marc_record_001.phptnu�[��������PK�������u]è{��{��"������������'�test/File_MARC/tests/marc_020.phptnu�[��������PK�������u]&c��c��"������������'�test/File_MARC/tests/marc_002.phptnu�[��������PK�������u]>����&������������'�test/File_MARC/tests/marc_xml_003.phptnu�[��������PK�������u]*����������������'�test/Mail/tests/9137.phptnu�[��������PK�������u]w����������������'�test/Mail/tests/smtp_error.phptnu�[��������PK�������u]q/����������������*'�test/Mail/tests/13659.phptnu�[��������PK�������u]ó����������������'�test/Mail/tests/9137_2.phptnu�[��������PK�������u])f$! ��! ��������������(�test/Mail/tests/rfc822.phptnu�[��������PK�������u]x`(����������������~ (�test/Mail/tests/bug17317.phptnu�[��������PK�������u]8x������������������p(�test/Mail/tests/bug17178.phptnu�[��������PK�������u]V����(������������(�test/Structures_Graph/tests/AllTests.phpnu�[��������PK�������u]W8j#��j#��.������������(�test/Structures_Graph/tests/BasicGraphTest.phpnu�[��������PK�������u]����/������������}6(�test/Structures_Graph/tests/AcyclicTestTest.phpnu�[��������PK�������u]lp=i��i��&������������;(�test/Structures_Graph/tests/helper.incnu�[��������PK�������u]6:U��U��5������������=(�test/Structures_Graph/tests/TopologicalSorterTest.phpnu�[��������PK�������u]Za��a��������������qE(�.filemapnu�[��������PK�������u]Sh��h�������������� c(�File/MARC/List.phpnu�[��������PK�������u]+����������������~(�File/MARC/Field.phpnu�[��������PK�������u]Ɍ59�9�������������Ø(�File/MARC/Lint.phpnu�[��������PK�������u]RA;��A;��������������*�File/MARC/Data_Field.phpnu�[��������PK�������u]7*c����������������Y+�File/MARC/Subfield.phpnu�[��������PK�������u]IC(A��(A��������������a%+�File/MARC/Lint/CodeData.phpnu�[��������PK�������u]9g4xU��xU��������������f+�File/MARC/Record.phpnu�[��������PK�������u](#~����������������+�File/MARC/Exception.phpnu�[��������PK�������u]lz`����������������]+�File/MARC/Control_Field.phpnu�[��������PK�������u]5F '"��"��������������+�File/MARCXML.phpnu�[��������PK�������u]/f����������������,�File/MARCBASE.phpnu�[��������PK�������u]Sbw{7��{7�� ������������c#,�File/MARC.phpnu�[��������PK�������u]6EW��W��������������[,�data/Mail_mimeDecode/xmail.xslnu�[��������PK�������u] $v6��6��������������c,�data/Mail_mimeDecode/xmail.dtdnu�[��������PK�������u]����������������Df,�data/PEAR/template.specnu�[��������PK�������u]ũ �� ��������������`n,�data/PEAR/package.dtdnu�[��������PK�������u]%)c��c�� ������������{,�peclcmd.phpnu�[��������PK�������u]Pi����������������G,�.depdbnu�[��������PK�������u]؛J��J��������������6,�Mail/mimePart.phpnu�[��������PK�������u]E@%>��>��������������H-�Mail/sendmail.phpnu�[��������PK�������u]B_Ǭ=��=�� ������������@f-�Mail/smtp.phpnu�[��������PK�������u]Bsh��h�� ������������)-�Mail/mock.phpnu�[��������PK�������u]x ع����������������η-�Mail/mimeDecode.phpnu�[��������PK�������u]{ �� �� ������������Q.�Mail/null.phpnu�[��������PK�������u]A~{��{��������������^.�Mail/RFC822.phpnu�[��������PK�������u]wԐE;��E;��������������.�Mail/smtpmx.phpnu�[��������PK�������u]@iE\��\�� ������������;/�Mail/mail.phpnu�[��������PK�������u]+V���� ������������./�Mail/mime.phpnu�[��������PK�������u]oP��P�� ������������0�System.phpnu�[��������PK�������u]=Y�Y�������������V0�Archive/Tar.phpnu�[��������PK�������u]p0 �� ��������������1�.registry/net_idna2.regnu�[��������PK�������u]Jv~����������������f1�.registry/net_socket.regnu�[��������PK�������u]rXS)��S)��������������w1�.registry/mail.regnu�[��������PK�������u]i:+��:+�������������� 2�.registry/mail_mimedecode.regnu�[��������PK�������u]n`I��I��������������/2�.registry/net_smtp.regnu�[��������PK�������u]-P)��)��������������"J2�.registry/console_getopt.regnu�[��������PK�������u]8m|&��|&��������������=t2�.registry/auth_sasl.regnu�[��������PK�������u]r}.��.���������������2�.registry/mail_mime.regnu�[��������PK�������u]uzuv��uv��������������u3�.registry/xml_util.regnu�[��������PK�������u]I(��(��������������03�.registry/file_marc.regnu�[��������PK�������u];VX+��+��������������4�.registry/structures_graph.regnu�[��������PK�������u]SGW��W�������������� 4�.registry/archive_tar.regnu�[��������PK�������u]0R1{��1{��������������5�.registry/xml_rpc.regnu�[��������PK�������u]->,6��,6��#������������i5�.registry/structures_linkedlist.regnu�[��������PK�������u]-EN��EN��������������5�.registry/net_sieve.regnu�[��������PK�������u]b@D�D�������������t6�.registry/pear.regnu�[��������PK�������u]'7,����������������7�PEAR.phpnu�[��������PK�������u]0AC5��C5��������������18�Console/Getopt.phpnu�[��������PK�������u]������������������������Kg8�.locknu�[��������PK�������u]������������ ������������g8�.depdblocknu�[��������PK�������u]C +�� +��������������g8�Structures/Graph/Node.phpnu�[��������PK�������u]~(ht��t��2������������#8�Structures/Graph/Manipulator/TopologicalSorter.phpnu�[��������PK�������u]9����,������������8�Structures/Graph/Manipulator/AcyclicTest.phpnu�[��������PK�������u]Uyv����������������8�Structures/Graph.phpnu�[��������PK�������u]*z%-��%-�� ������������98�Structures/LinkedList/Double.phpnu�[��������PK�������u]p:��p:�� ������������ 9�Structures/LinkedList/Single.phpnu�[��������PK�������u]3-��-��,������������nF9�.pkgxml/Pear_Structures_LinkedList-0.2.2.xmlnu�[��������PK�������u]7pK��K��������������W9�.pkgxml/XML_Util.xmlnu�[��������PK�������u]Q?��?�� ������������̣9�.pkgxml/Pear_Net_Sieve-1.4.5.xmlnu�[��������PK�������u]/h����"������������9�.pkgxml/Pear_Mail_Mime-1.10.11.xmlnu�[��������PK�������u]%ONO����&������������v:�.pkgxml/Pear_Mail_mimeDecode-1.5.6.xmlnu�[��������PK�������u]ȗ����!�������������:�.pkgxml/Pear_Net_Socket-1.2.2.xmlnu�[��������PK�������u]0$-��-�� ������������Y:�.pkgxml/Pear_File_MARC-1.4.1.xmlnu�[��������PK�������u]zWzD ��D �� ������������:�.pkgxml/Pear_Net_IDNA2-0.2.0.xmlnu�[��������PK�������u]Z2iH��H��������������A:�.pkgxml/Pear_Mail-1.4.1.xmlnu�[��������PK�������u]c���� ������������:�.pkgxml/Pear_Auth_SASL-1.1.0.xmlnu�[��������PK�������u]#r �� �� ������������ :�.pkgxml/Pear_Net_SMTP-1.10.0.xmlnu�[��������PK�������u]������������������`;�.pkgxml/Pear.listnu�[��������PK����yy��;���