sieve.php
来自「PHP 知识管理系统(基于树结构的知识管理系统), 英文原版的PHP源码。」· PHP 代码 · 共 1,165 行 · 第 1/3 页
PHP
1,165 行
function haveSpace($scriptname,$quota)
{
if (NET_SIEVE_STATE_TRANSACTION != $this->_state) {
$msg='Not currently in TRANSACTION state';
$code=1;
return $this->_raiseError($msg,$code);
}
if (PEAR::isError($res = $this->_doCmd(sprintf('HAVESPACE "%s" %s', $scriptname, $quota) ) ) ) {
//if (PEAR::isError($res = $this->_doCmd(sprintf('HAVESPACE %d "%s"', $quota,$scriptname ) ) ) ) {
return $res;
}
return true;
}
/**
* Parses the response from the capability command. Storesq
* the result in $this->_capability
*
* @access private
*/
function _parseCapability($data)
{
$data = preg_split('/\r?\n/', $data, -1, PREG_SPLIT_NO_EMPTY);
for ($i = 0; $i < count($data); $i++) {
if (preg_match('/^"([a-z]+)" ("(.*)")?$/i', $data[$i], $matches)) {
switch (strtolower($matches[1])) {
case 'implementation':
$this->_capability['implementation'] = $matches[3];
break;
case 'sasl':
$this->_capability['sasl'] = preg_split('/\s+/', $matches[3]);
break;
case 'sieve':
$this->_capability['extensions'] = preg_split('/\s+/', $matches[3]);
break;
case 'starttls':
$this->_capability['starttls'] = true;
}
}
}
}
/**
* Sends a command to the server
*
* @access private
* @param string $cmd The command to send
*/
function _sendCmd($cmd)
{
$status = $this->_sock->getStatus();
if (PEAR::isError($status) || $status['eof']) {
return new PEAR_Error( 'Failed to write to socket: (connection lost!) ' );
}
if ( PEAR::isError( $error = $this->_sock->write( $cmd . "\r\n" ) ) ) {
return new PEAR_Error( 'Failed to write to socket: ' . $error->getMessage() );
}
if( $this->_debug ){
// C: means this data was sent by the client (this class)
echo "C:$cmd\n";
}
return true;
}
/**
* Sends a string response to the server
*
* @access private
* @param string $cmd The command to send
*/
function _sendStringResponse($str)
{
$response='{' . strlen($str) . "+}\r\n" . $str ;
return $this->_sendCmd($response);
}
function _recvLn()
{
$lastline='';
if (PEAR::isError( $lastline = $this->_sock->gets( 8192 ) ) ) {
return new PEAR_Error('Failed to write to socket: ' . $lastline->getMessage() );
}
$lastline=rtrim($lastline);
if($this->_debug){
// S: means this data was sent by the IMAP Server
echo "S:$lastline\n" ;
}
/* if( $lastline === '' ){
return new PEAR_Error('Failed to receive from the socket: ' );
}
*/
return $lastline;
}
/**
* Send a command and retrieves a response from the server.
*
*
* @access private
* @param string $cmd The command to send
* @return mixed Reponse string if an OK response, PEAR_Error if a NO response
*/
function _doCmd($cmd = '' )
{
$referralCount=0;
while($referralCount < $this->_maxReferralCount ){
if($cmd != '' ){
if(PEAR::isError($error = $this->_sendCmd($cmd) )) {
return $error;
}
}
$response = '';
while (true) {
if(PEAR::isError( $line=$this->_recvLn() )){
return $line;
}
if ('ok' === strtolower(substr($line, 0, 2))) {
$response .= $line;
return rtrim($response);
} elseif ('no' === strtolower(substr($line, 0, 2))) {
// Check for string literal error message
if (preg_match('/^no {([0-9]+)\+?}/i', $line, $matches)) {
$line .= str_replace("\r\n", ' ', $this->_sock->read($matches[1] + 2 ));
if($this->_debug){
echo "S:$line\n";
}
}
$msg=trim($response . substr($line, 2));
$code=3;
return $this->_raiseError($msg,$code);
//return PEAR::raiseError(trim($response . substr($line, 2)));
} elseif ('bye' === strtolower(substr($line, 0, 3))) {
if(PEAR::isError($error = $this->disconnect(false) ) ){
$msg="Can't handle bye, The error was= " . $error->getMessage() ;
$code=4;
return $this->_raiseError($msg,$code);
//return PEAR::raiseError("Can't handle bye, The error was= " . $error->getMessage() );
}
//if (preg_match('/^bye \(referral "([^"]+)/i', $line, $matches)) {
if (preg_match('/^bye \(referral "(sieve:\/\/)?([^"]+)/i', $line, $matches)) {
// Check for referral, then follow it. Otherwise, carp an error.
//$this->_data['host'] = $matches[1];
$this->_data['host'] = $matches[2];
if (PEAR::isError($error = $this->_handleConnectAndLogin() ) ){
$msg="Can't follow referral to " . $this->_data['host'] . ", The error was= " . $error->getMessage() ;
$code=5;
return $this->_raiseError($msg,$code);
//return PEAR::raiseError("Can't follow referral to " . $this->_data['host'] . ", The error was= " . $error->getMessage() );
}
break;
// Retry the command
if(PEAR::isError($error = $this->_sendCmd($cmd) )) {
return $error;
}
continue;
}
$msg=trim($response . $line);
$code=6;
return $this->_raiseError($msg,$code);
//return PEAR::raiseError(trim($response . $line));
} elseif (preg_match('/^{([0-9]+)\+?}/i', $line, $matches)) {
// Matches String Responses.
//$line = str_replace("\r\n", ' ', $this->_sock->read($matches[1] + 2 ));
$line = $this->_sock->read($matches[1] + 2 );
if($this->_debug){
echo "S:$line\n";
}
return $line;
}
$response .= $line . "\r\n";
$referralCount++;
}
}
$msg="Max referral count reached ($referralCount times) Cyrus murder loop error?";
$code=7;
return $this->_raiseError($msg,$code);
//return PEAR::raiseError("Max referral count reached ($referralCount times) Cyrus murder loop error?" );
}
/**
* Sets the bebug state
*
* @access public
* @return void
*/
function setDebug($debug=true)
{
$this->_debug=$debug;
}
/**
* Disconnect from the Sieve server
*
* @access public
* @param string $scriptname The name of the script to be set as active
* @return mixed true on success, PEAR_Error on failure
*/
function disconnect($sendLogoutCMD=true)
{
return $this->_cmdLogout($sendLogoutCMD);
}
/**
* Returns the name of the best authentication method that the server
* has advertised.
*
* @param string if !=null,authenticate with this method ($userMethod).
*
* @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.
* @access private
* @since 1.0
*/
function _getBestAuthMethod($userMethod = null)
{
if( isset($this->_capability['sasl']) ){
$serverMethods=$this->_capability['sasl'];
}else{
// if the server don't send an sasl capability fallback to login auth
//return 'LOGIN';
return new PEAR_Error("This server don't support any Auth methods SASL problem?");
}
if($userMethod != null ){
$methods = array();
$methods[] = $userMethod;
}else{
$methods = $this->supportedAuthMethods;
}
if( ($methods != null) && ($serverMethods != null)){
foreach ( $methods as $method ) {
if ( in_array( $method , $serverMethods ) ) {
return $method;
}
}
$serverMethods=implode(',' , $serverMethods );
$myMethods=implode(',' ,$this->supportedAuthMethods);
return new PEAR_Error("$method NOT supported authentication method!. This server " .
"supports these methods= $serverMethods, but I support $myMethods");
}else{
return new PEAR_Error("This server don't support any Auth methods");
}
}
/**
* Return the list of extensions the server supports
*
* @access public
* @return mixed array on success, PEAR_Error on failure
*/
function getExtensions()
{
if (NET_SIEVE_STATE_DISCONNECTED === $this->_state) {
$msg='Not currently connected';
$code=7;
return $this->_raiseError($msg,$code);
//return PEAR::raiseError('Not currently connected');
}
return $this->_capability['extensions'];
}
/**
* Return true if tyhe server has that extension
*
* @access public
* @param string the extension to compare
* @return mixed array on success, PEAR_Error on failure
*/
function hasExtension($extension)
{
if (NET_SIEVE_STATE_DISCONNECTED === $this->_state) {
$msg='Not currently connected';
$code=7;
return $this->_raiseError($msg,$code);
//return PEAR::raiseError('Not currently connected');
}
if(is_array($this->_capability['extensions'] ) ){
foreach( $this->_capability['extensions'] as $ext){
if( trim( strtolower( $ext ) ) === trim( strtolower( $extension ) ) )
return true;
}
}
return false;
}
/**
* Return the list of auth methods the server supports
*
* @access public
* @return mixed array on success, PEAR_Error on failure
*/
function getAuthMechs()
{
if (NET_SIEVE_STATE_DISCONNECTED === $this->_state) {
$msg='Not currently connected';
$code=7;
return $this->_raiseError($msg,$code);
//return PEAR::raiseError('Not currently connected');
}
if(!isset($this->_capability['sasl']) ){
$this->_capability['sasl']=array();
}
return $this->_capability['sasl'];
}
/**
* Return true if tyhe server has that extension
*
* @access public
* @param string the extension to compare
* @return mixed array on success, PEAR_Error on failure
*/
function hasAuthMech($method)
{
if (NET_SIEVE_STATE_DISCONNECTED === $this->_state) {
$msg='Not currently connected';
$code=7;
return $this->_raiseError($msg,$code);
//return PEAR::raiseError('Not currently connected');
}
if(is_array($this->_capability['sasl'] ) ){
foreach( $this->_capability['sasl'] as $ext){
if( trim( strtolower( $ext ) ) === trim( strtolower( $method ) ) )
return true;
}
}
return false;
}
}
?>
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?