| | |
| | | var $auth_methods = array('DIGEST-MD5', 'CRAM-MD5', 'LOGIN', 'PLAIN'); |
| | | |
| | | /** |
| | | * 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 |
| | | * @access public |
| | | */ |
| | | var $pipelining = false; |
| | | |
| | | /** |
| | | * Number of pipelined commands. |
| | | * @var int |
| | | * @access private |
| | | */ |
| | | var $_pipelined_commands = 0; |
| | | |
| | | /** |
| | | * Should debugging output be enabled? |
| | | * @var boolean |
| | | * @access private |
| | |
| | | * @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 $pipeling Use SMTP command pipelining |
| | | * |
| | | * @access public |
| | | * @since 1.0 |
| | | */ |
| | | function Net_SMTP($host = null, $port = null, $localhost = null) |
| | | function Net_SMTP($host = null, $port = null, $localhost = null, $pipelining = false) |
| | | { |
| | | if (isset($host)) $this->host = $host; |
| | | if (isset($port)) $this->port = $port; |
| | | if (isset($localhost)) $this->localhost = $localhost; |
| | | 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(); |
| | | |
| | | /* |
| | | * Include the Auth_SASL package. If the package is not available, |
| | | * we disable the authentication methods that depend upon it. |
| | | */ |
| | | /* 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) { |
| | | $pos = array_search('DIGEST-MD5', $this->auth_methods); |
| | | unset($this->auth_methods[$pos]); |
| | |
| | | * @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. |
| | |
| | | * |
| | | * @see getResponse |
| | | */ |
| | | function _parseResponse($valid) |
| | | 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()) { |
| | | if ($this->_debug) { |
| | | echo "DEBUG: Recv: $line\n"; |
| | |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | |
| | | /* Compare the server's response code with the valid code. */ |
| | | $this->_pipelined_commands = 0; |
| | | |
| | | /* Compare the server's response code with the valid code/codes. */ |
| | | if (is_int($valid) && ($this->_code === $valid)) { |
| | | return true; |
| | | } |
| | | |
| | | /* If we were given an array of valid response codes, check each one. */ |
| | | if (is_array($valid)) { |
| | | foreach ($valid as $valid_code) { |
| | | if ($this->_code === $valid_code) { |
| | | } elseif (is_array($valid) && in_array($this->_code, $valid, true)) { |
| | | return true; |
| | | } |
| | | } |
| | | } |
| | | |
| | | return PEAR::raiseError('Invalid response code received from server', |
| | |
| | | $arguments = substr($argument, strlen($verb) + 1, |
| | | strlen($argument) - strlen($verb) - 1); |
| | | $this->_esmtp[$verb] = $arguments; |
| | | } |
| | | |
| | | if (!isset($this->_esmtp['PIPELINING'])) { |
| | | $this->pipelining = false; |
| | | } |
| | | |
| | | return true; |
| | |
| | | } |
| | | |
| | | /** |
| | | * Return the list of SMTP service extensions advertised by the server. |
| | | * |
| | | * @return array The list of SMTP service extensions. |
| | | * @access public |
| | | * @since 1.3 |
| | | */ |
| | | function getServiceExtensions() |
| | | { |
| | | return $this->_esmtp; |
| | | } |
| | | |
| | | /** |
| | | * Send the MAIL FROM: command. |
| | | * |
| | | * @param string $sender The sender (reverse path) to set. |
| | |
| | | if (PEAR::isError($error = $this->_put('MAIL', $args))) { |
| | | return $error; |
| | | } |
| | | if (PEAR::isError($error = $this->_parseResponse(250))) { |
| | | if (PEAR::isError($error = $this->_parseResponse(250, $this->pipelining))) { |
| | | return $error; |
| | | } |
| | | |
| | |
| | | if (PEAR::isError($error = $this->_put('RCPT', $args))) { |
| | | return $error; |
| | | } |
| | | if (PEAR::isError($error = $this->_parseResponse(array(250, 251)))) { |
| | | if (PEAR::isError($error = $this->_parseResponse(array(250, 251), $this->pipelining))) { |
| | | return $error; |
| | | } |
| | | |
| | |
| | | if (PEAR::isError($result = $this->_send($data . "\r\n.\r\n"))) { |
| | | return $result; |
| | | } |
| | | if (PEAR::isError($error = $this->_parseResponse(250))) { |
| | | if (PEAR::isError($error = $this->_parseResponse(250, $this->pipelining))) { |
| | | return $error; |
| | | } |
| | | |
| | |
| | | if (PEAR::isError($error = $this->_put('SEND', "FROM:<$path>"))) { |
| | | return $error; |
| | | } |
| | | if (PEAR::isError($error = $this->_parseResponse(250))) { |
| | | if (PEAR::isError($error = $this->_parseResponse(250, $this->pipelining))) { |
| | | return $error; |
| | | } |
| | | |
| | |
| | | if (PEAR::isError($error = $this->_put('SOML', "FROM:<$path>"))) { |
| | | return $error; |
| | | } |
| | | if (PEAR::isError($error = $this->_parseResponse(250))) { |
| | | if (PEAR::isError($error = $this->_parseResponse(250, $this->pipelining))) { |
| | | return $error; |
| | | } |
| | | |
| | |
| | | if (PEAR::isError($error = $this->_put('SAML', "FROM:<$path>"))) { |
| | | return $error; |
| | | } |
| | | if (PEAR::isError($error = $this->_parseResponse(250))) { |
| | | if (PEAR::isError($error = $this->_parseResponse(250, $this->pipelining))) { |
| | | return $error; |
| | | } |
| | | |
| | |
| | | if (PEAR::isError($error = $this->_put('RSET'))) { |
| | | return $error; |
| | | } |
| | | if (PEAR::isError($error = $this->_parseResponse(250))) { |
| | | if (PEAR::isError($error = $this->_parseResponse(250, $this->pipelining))) { |
| | | return $error; |
| | | } |
| | | |