From 2c3d81dddd8d931385022a065515d6ef42d7fb7d Mon Sep 17 00:00:00 2001
From: alecpl <alec@alec.pl>
Date: Tue, 21 Jul 2009 08:31:59 -0400
Subject: [PATCH] - use simple rcube_smtp class - Installer: fix SMTP settings test

---
 program/include/rcube_smtp.php |  394 ++++++++++++++++++++++++++++
 /dev/null                      |  370 --------------------------
 installer/rcube_install.php    |    4 
 installer/utils.php            |   19 -
 program/include/rcmail.php     |   18 +
 program/steps/mail/func.inc    |   10 
 installer/test.php             |   18 
 installer/index.php            |    2 
 8 files changed, 434 insertions(+), 401 deletions(-)

diff --git a/installer/index.php b/installer/index.php
index 9f4c0a3..d1c55e4 100644
--- a/installer/index.php
+++ b/installer/index.php
@@ -13,8 +13,8 @@
 
 set_include_path($include_path);
 
-require_once 'rcube_shared.inc';
 require_once 'utils.php';
+require_once 'main.inc';
 
 session_start();
 
diff --git a/installer/rcube_install.php b/installer/rcube_install.php
index 0504687..1ad1ff2 100644
--- a/installer/rcube_install.php
+++ b/installer/rcube_install.php
@@ -136,10 +136,10 @@
    */
   function create_config($which, $force = false)
   {
-    $out = file_get_contents(RCMAIL_CONFIG_DIR . "/{$which}.inc.php.dist");
+    $out = @file_get_contents(RCMAIL_CONFIG_DIR . "/{$which}.inc.php.dist");
     
     if (!$out)
-      return '[Warning: could not read the template file]';
+      return '[Warning: could not read the config template file]';
 
     foreach ($this->config as $prop => $default) {
       $value = (isset($_POST["_$prop"]) || $this->bool_config_props[$prop]) ? $_POST["_$prop"] : $default;
diff --git a/installer/test.php b/installer/test.php
index 5740a64..90d089f 100644
--- a/installer/test.php
+++ b/installer/test.php
@@ -248,13 +248,11 @@
 
 if (isset($_POST['sendmail']) && !empty($_POST['_from']) && !empty($_POST['_to'])) {
   
-  require_once 'rcube_smtp.inc';
-  
   echo '<p>Trying to send email...<br />';
   
   if (preg_match('/^' . $RCI->email_pattern . '$/i', trim($_POST['_from'])) &&
       preg_match('/^' . $RCI->email_pattern . '$/i', trim($_POST['_to']))) {
-  
+
     $headers = array(
       'From'    => trim($_POST['_from']),
       'To'      => trim($_POST['_to']),
@@ -267,7 +265,7 @@
     // send mail using configured SMTP server
     if ($RCI->getprop('smtp_server')) {
       $CONFIG = $RCI->config;
-      
+
       if (!empty($_POST['_smtp_user'])) {
         $CONFIG['smtp_user'] = $_POST['_smtp_user'];
       }
@@ -277,10 +275,14 @@
 
       $mail_object  = new rcube_mail_mime();
       $send_headers = $mail_object->headers($headers);
-      
-      $status = smtp_mail($headers['From'], $headers['To'],
-          ($foo = $mail_object->txtHeaders($send_headers)),
-          $body, $smtp_response);
+
+      $SMTP = new rcube_smtp();
+      $SMTP->connect();
+
+      $status = $SMTP->send_mail($headers['From'], $headers['To'],
+          ($foo = $mail_object->txtHeaders($send_headers)), $body);
+
+      $smtp_response = $SMTP->get_response();
     }
     else {    // use mail()
       $header_str = 'From: ' . $headers['From'];
diff --git a/installer/utils.php b/installer/utils.php
index 54221dd..1c10105 100644
--- a/installer/utils.php
+++ b/installer/utils.php
@@ -29,28 +29,16 @@
 
 /**
  * Use PHP5 autoload for dynamic class loading
- * (copy from program/incllude/iniset.php)
+ * (copy from program/include/iniset.php)
  */
 function __autoload($classname)
 {
   $filename = preg_replace(
-      array('/MDB2_(.+)/', '/Mail_(.+)/', '/^html_.+/', '/^utf8$/'),
-      array('MDB2/\\1', 'Mail/\\1', 'html', 'utf8.class'),
+      array('/MDB2_(.+)/', '/Mail_(.+)/', '/Net_(.+)/', '/^html_.+/', '/^utf8$/'),
+      array('MDB2/\\1', 'Mail/\\1', 'Net/\\1', 'html', 'utf8.class'),
       $classname
   );
   include_once $filename. '.php';
-}
-
-
-/**
- * Shortcut function for htmlentities()
- *
- * @param string String to quote
- * @return string The html-encoded string
- */
-function Q($string)
-{
-  return htmlentities($string, ENT_COMPAT, 'UTF-8');
 }
 
 
@@ -62,5 +50,4 @@
   $rci = rcube_install::get_instance();
   $rci->raise_error($p);
 }
-
 
diff --git a/program/include/rcmail.php b/program/include/rcmail.php
index 627a8f2..a508e17 100644
--- a/program/include/rcmail.php
+++ b/program/include/rcmail.php
@@ -35,6 +35,7 @@
   public $config;
   public $user;
   public $db;
+  public $smtp;
   public $imap;
   public $output;
   public $plugins;
@@ -337,6 +338,20 @@
       $this->output = new rcube_json_output($this->task);
     
     return $this->output;
+  }
+
+
+  /**
+   * Create SMTP object and connect to server
+   *
+   * @param boolean True if connection should be established
+   */
+  public function smtp_init($connect = false)
+  {
+    $this->smtp = new rcube_smtp();
+  
+    if ($connect)
+      $this->smtp->connect();
   }
   
   
@@ -842,6 +857,9 @@
       $this->imap->write_cache();
     }
 
+    if (is_object($this->smtp))
+      $this->smtp->disconnect();
+
     if (is_object($this->contacts))
       $this->contacts->close();
 
diff --git a/program/include/rcube_smtp.inc b/program/include/rcube_smtp.inc
deleted file mode 100644
index 9e1e664..0000000
--- a/program/include/rcube_smtp.inc
+++ /dev/null
@@ -1,370 +0,0 @@
-<?php
-
-/*
- +-----------------------------------------------------------------------+
- | program/include/rcube_smtp.inc                                        |
- |                                                                       |
- | This file is part of the RoundCube Webmail client                     |
- | Copyright (C) 2005-2007, RoundCube Dev. - Switzerland                 |
- | Licensed under the GNU GPL                                            |
- |                                                                       |
- | PURPOSE:                                                              |
- |   Provide SMTP functionality using socket connections                 |
- |                                                                       |
- +-----------------------------------------------------------------------+
- | Author: Thomas Bruederli <roundcube@gmail.com>                        |
- +-----------------------------------------------------------------------+
-
- $Id$
-
-*/
-
-/**
- * SMTP delivery functions
- *
- * @package Mail
- */
-
-// define headers delimiter
-define('SMTP_MIME_CRLF', "\r\n");
-
-$SMTP_CONN = null;
-
-/**
- * Function for sending mail using SMTP.
- *
- * @param string Sender e-Mail address
- *
- * @param mixed  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 mixed  The message headers to send with the mail
- *               Either as an associative array or a finally
- *               formatted string
- *
- * @param string The full text of the message body, including any Mime parts, etc.
- *
- * @return bool  Returns TRUE on success, or FALSE on error
- */
-function smtp_mail($from, $recipients, &$headers, &$body, &$response, &$error)
-  {
-  global $SMTP_CONN, $RCMAIL;
-  
-  // let plugins alter smtp connection config
-  $CONFIG = $RCMAIL->plugins->exec_hook('smtp_connect', array(
-    'smtp_server' => $RCMAIL->config->get('smtp_server'),
-    'smtp_port'   => $RCMAIL->config->get('smtp_port', 25),
-    'smtp_user'   => $RCMAIL->config->get('smtp_user'),
-    'smtp_pass'   => $RCMAIL->config->get('smtp_pass'),
-    'smtp_auth_type' => $RCMAIL->config->get('smtp_auth_type'),
-    'smtp_helo_host' => $RCMAIL->config->get('smtp_helo_host'),
-  ));
-
-  $smtp_timeout = null;
-  $smtp_host = str_replace('%h', $_SESSION['imap_host'], $CONFIG['smtp_server']);
-  $smtp_port = is_numeric($CONFIG['smtp_port']) ? $CONFIG['smtp_port'] : 25;
-  $smtp_host_url = parse_url($smtp_host);
-
-  // overwrite port
-  if (isset($smtp_host_url['host']) && isset($smtp_host_url['port']))
-    {
-    $smtp_host = $smtp_host_url['host'];
-    $smtp_port = $smtp_host_url['port'];
-    }
-
-  // re-write smtp host
-  if (isset($smtp_host_url['host']) && isset($smtp_host_url['scheme']))
-    $smtp_host = sprintf('%s://%s', $smtp_host_url['scheme'], $smtp_host_url['host']);
-
-
-  // create Net_SMTP object and connect to server
-  if (!is_object($SMTP_CONN))
-    {
-    if (!empty($CONFIG['smtp_helo_host']))
-      $helo_host = $CONFIG['smtp_helo_host'];
-    else if (!empty($_SERVER['SERVER_NAME']))
-      $helo_host = preg_replace('/:\d+$/', '', $_SERVER['SERVER_NAME']);
-    else
-      $helo_host = 'localhost';
-
-    $SMTP_CONN = new Net_SMTP($smtp_host, $smtp_port, $helo_host);
-
-    if($RCMAIL->config->get('smtp_debug'))
-      $SMTP_CONN->setDebug(true, 'smtp_debug_handler');
-
-    // try to connect to server and exit on failure
-    $result = $SMTP_CONN->connect($smtp_timeout);
-    if (PEAR::isError($result))
-      {
-      $response[] = "Connection failed: ".$result->getMessage();
-      $error = array('label' => 'smtpconnerror', 'vars' => array('code' => $SMTP_CONN->_code));
-      $SMTP_CONN = null;
-      return FALSE;
-      }
-      
-    // attempt to authenticate to the SMTP server
-    if ($CONFIG['smtp_user'] && $CONFIG['smtp_pass'])
-      {
-      if (strstr($CONFIG['smtp_user'], '%u'))
-        $smtp_user = str_replace('%u', $_SESSION['username'], $CONFIG['smtp_user']);
-      else
-        $smtp_user = $CONFIG['smtp_user'];
-
-      if (strstr($CONFIG['smtp_pass'], '%p'))
-        $smtp_pass = str_replace('%p', $RCMAIL->decrypt($_SESSION['password']), $CONFIG['smtp_pass']);
-      else
-        $smtp_pass = $CONFIG['smtp_pass'];
-
-      $smtp_auth_type = empty($CONFIG['smtp_auth_type']) ? NULL : $CONFIG['smtp_auth_type'];
-      $result = $SMTP_CONN->auth($smtp_user, $smtp_pass, $smtp_auth_type);
-    
-      if (PEAR::isError($result))
-        {
-        $error = array('label' => 'smtpautherror', 'vars' => array('code' => $SMTP_CONN->_code));
-        $response[] .= 'Authentication failure: ' . $result->getMessage() . ' (Code: ' . $result->getCode() . ')';
-        smtp_reset();
-        return FALSE;
-        }
-      }
-    }
-
-
-  // prepare message headers as string
-  if (is_array($headers))
-    {
-    $headerElements = smtp_prepare_headers($headers);
-    if (!$headerElements)
-      {
-      smtp_reset();
-      return FALSE;
-      }
-
-    list($from, $text_headers) = $headerElements;
-    }
-  else if (is_string($headers))
-    $text_headers = $headers;
-  else
-    {
-    smtp_reset();
-    $response[] .= "Invalid message headers";
-    return FALSE;
-    }
-
-  // exit if no from address is given
-  if (!isset($from))
-    {
-    smtp_reset();
-    $response[] .= "No From address has been provided";
-    return FALSE;
-    }
-
-
-  // set From: address
-  if (PEAR::isError($SMTP_CONN->mailFrom($from)))
-    {
-    $error = array('label' => 'smtpfromerror', 'vars' => array('from' => $from, 'code' => $SMTP_CONN->_code));
-    $response[] .= "Failed to set sender '$from'";
-    smtp_reset();
-    return FALSE;
-    }
-
-
-  // prepare list of recipients
-  $recipients = smtp_parse_rfc822($recipients);
-  if (PEAR::isError($recipients))
-    {
-    $error = array('label' => 'smtprecipientserror');
-    smtp_reset();
-    return FALSE;
-    }
-
-
-  // set mail recipients
-  foreach ($recipients as $recipient)
-    {
-    if (PEAR::isError($SMTP_CONN->rcptTo($recipient)))
-      {
-      $error = array('label' => 'smtptoerror', 'vars' => array('to' => $recipient, 'code' => $SMTP_CONN->_code));
-      $response[] .= "Failed to add recipient '$recipient'";
-      smtp_reset();
-      return FALSE;
-      }
-    }
-
-
-  // Concatenate headers and body so it can be passed by reference to SMTP_CONN->data
-  // so preg_replace in SMTP_CONN->quotedata will store a reference instead of a copy. 
-  // We are still forced to make another copy here for a couple ticks so we don't really 
-  // get to save a copy in the method call.
-  $data = $text_headers . "\r\n" . $body;
-
-  // unset old vars to save data and so we can pass into SMTP_CONN->data by reference.
-  unset($text_headers, $body);
-   
-  // Send the message's headers and the body as SMTP data.
-  if (PEAR::isError($result = $SMTP_CONN->data($data)))
-    {
-    $error = array('label' => 'smtperror', 'vars' => array('msg' => $result->getMessage()));
-    $response[] .= "Failed to send data";
-    smtp_reset();
-    return FALSE;
-    }
-
-  $response[] = join(': ', $SMTP_CONN->getResponse());
-  return TRUE;
-  }
-
-
-
-/**
- * Reset the global SMTP connection
- * @access public
- */
-function smtp_reset()
-  {
-  global $SMTP_CONN;
-
-  if (is_object($SMTP_CONN) && is_resource($SMTP_CONN->_socket->fp))
-    {
-    $SMTP_CONN->rset();
-    smtp_disconnect();
-    }
-  }
-
-
-/**
- * Disconnect the global SMTP connection and destroy object
- * @access public
- */
-function smtp_disconnect()
-  {
-  global $SMTP_CONN;
-
-  if (is_object($SMTP_CONN))
-    {
-    $SMTP_CONN->disconnect();
-    $SMTP_CONN = null;
-    }
-  }
-
-/* this is our own debug handler for the SMTP connection */
-function smtp_debug_handler(&$smtp, $message)
-  {
-  write_log('smtp', preg_replace('/\r\n$/', '', $message));
-  }
-
-
-/**
- * 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.
- * @access private
- */
-function smtp_prepare_headers($headers)
-  {
-  $lines = array();
-  $from = null;
-
-  foreach ($headers as $key => $value)
-    {
-    if (strcasecmp($key, 'From') === 0)
-      {
-      $addresses = smtp_parse_rfc822($value);
-
-      if (is_array($addresses))
-        $from = $addresses[0];
-
-      // Reject envelope From: addresses with spaces.
-      if (strstr($from, ' '))
-        return FALSE;
-
-
-      $lines[] = $key . ': ' . $value;
-      }
-    else if (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(SMTP_MIME_CRLF, $lines) . SMTP_MIME_CRLF);
-  }
-
-
-
-/**
- * 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 array An array of forward paths (bare addresses).
- * @access private
- */
-function smtp_parse_rfc822($recipients)
-  {
-  // if we're passed an array, assume addresses are valid and implode them before parsing.
-  if (is_array($recipients))
-    $recipients = implode(', ', $recipients);
-    
-  $addresses = array();
-  $recipients = rcube_explode_quoted_string(',', $recipients);
-  
-  reset($recipients);
-  while (list($k, $recipient) = each($recipients))
-    {
-  $a = explode(" ", $recipient);
-  while (list($k2, $word) = each($a))
-    {
-      if ((strpos($word, "@") > 0) && (strpos($word, "\"")===false))
-        {
-        $word = preg_replace('/^<|>$/', '', trim($word));
-        if (in_array($word, $addresses)===false)
-          array_push($addresses, $word);
-        }
-      }
-    }
-  return $addresses;
-  }
-
-?>
diff --git a/program/include/rcube_smtp.php b/program/include/rcube_smtp.php
new file mode 100644
index 0000000..d2957e2
--- /dev/null
+++ b/program/include/rcube_smtp.php
@@ -0,0 +1,394 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | program/include/rcube_smtp.php                                        |
+ |                                                                       |
+ | This file is part of the RoundCube Webmail client                     |
+ | Copyright (C) 2005-2007, RoundCube Dev. - Switzerland                 |
+ | Licensed under the GNU GPL                                            |
+ |                                                                       |
+ | PURPOSE:                                                              |
+ |   Provide SMTP functionality using socket connections                 |
+ |                                                                       |
+ +-----------------------------------------------------------------------+
+ | Author: Thomas Bruederli <roundcube@gmail.com>                        |
+ +-----------------------------------------------------------------------+
+
+ $Id: rcube_smtp.inc 2754 2009-07-14 16:34:34Z alec $
+
+*/
+
+// define headers delimiter
+define('SMTP_MIME_CRLF', "\r\n");
+
+class rcube_smtp {
+
+  private $conn = null;
+  private $response;
+  private $error;
+
+
+  /**
+   * Object constructor
+   *
+   * @param 
+   */
+  function __construct()
+  {
+  }
+
+
+  /**
+   * SMTP Connection and authentication
+   *
+   * @return bool  Returns true on success, or false on error
+   */
+  public function connect()
+  {
+    $RCMAIL = rcmail::get_instance();
+  
+    // disconnect/destroy $this->conn
+    $this->disconnect();
+    
+    // reset error/response var
+    $this->error = $this->response = null;
+  
+    // let plugins alter smtp connection config
+    $CONFIG = $RCMAIL->plugins->exec_hook('smtp_connect', array(
+      'smtp_server' => $RCMAIL->config->get('smtp_server'),
+      'smtp_port'   => $RCMAIL->config->get('smtp_port', 25),
+      'smtp_user'   => $RCMAIL->config->get('smtp_user'),
+      'smtp_pass'   => $RCMAIL->config->get('smtp_pass'),
+      'smtp_auth_type' => $RCMAIL->config->get('smtp_auth_type'),
+      'smtp_helo_host' => $RCMAIL->config->get('smtp_helo_host'),
+      'smtp_timeout'   => $RCMAIL->config->get('smtp_timeout'),
+    ));
+
+    $smtp_host = str_replace('%h', $_SESSION['imap_host'], $CONFIG['smtp_server']);
+    // when called from Installer it's possible to have empty $smtp_host here
+    if (!$smtp_host) $smtp_host = 'localhost';
+    $smtp_port = is_numeric($CONFIG['smtp_port']) ? $CONFIG['smtp_port'] : 25;
+    $smtp_host_url = parse_url($smtp_host);
+
+    // overwrite port
+    if (isset($smtp_host_url['host']) && isset($smtp_host_url['port']))
+    {
+      $smtp_host = $smtp_host_url['host'];
+      $smtp_port = $smtp_host_url['port'];
+    }
+
+    // re-write smtp host
+    if (isset($smtp_host_url['host']) && isset($smtp_host_url['scheme']))
+      $smtp_host = sprintf('%s://%s', $smtp_host_url['scheme'], $smtp_host_url['host']);
+
+    if (!empty($CONFIG['smtp_helo_host']))
+      $helo_host = $CONFIG['smtp_helo_host'];
+    else if (!empty($_SERVER['SERVER_NAME']))
+      $helo_host = preg_replace('/:\d+$/', '', $_SERVER['SERVER_NAME']);
+    else
+      $helo_host = 'localhost';
+
+    $this->conn = new Net_SMTP($smtp_host, $smtp_port, $helo_host);
+
+    if($RCMAIL->config->get('smtp_debug'))
+      $this->conn->setDebug(true, array($this, 'debug_handler'));
+    
+    // try to connect to server and exit on failure
+    $result = $this->conn->connect($smtp_timeout);
+    if (PEAR::isError($result))
+    {
+      $this->response[] = "Connection failed: ".$result->getMessage();
+      $this->error = array('label' => 'smtpconnerror', 'vars' => array('code' => $this->conn->_code));
+      $this->conn = null;
+      return false;
+    }
+
+    $smtp_user = str_replace('%u', $_SESSION['username'], $CONFIG['smtp_user']);
+    $smtp_pass = str_replace('%p', $RCMAIL->decrypt($_SESSION['password']), $CONFIG['smtp_pass']);
+    $smtp_auth_type = empty($CONFIG['smtp_auth_type']) ? NULL : $CONFIG['smtp_auth_type'];
+      
+    // attempt to authenticate to the SMTP server
+    if ($smtp_user && $smtp_pass)
+    {
+      $result = $this->conn->auth($smtp_user, $smtp_pass, $smtp_auth_type);
+      if (PEAR::isError($result))
+      {
+        $this->error = array('label' => 'smtpautherror', 'vars' => array('code' => $this->conn->_code));
+        $this->response[] .= 'Authentication failure: ' . $result->getMessage() . ' (Code: ' . $result->getCode() . ')';
+        $this->reset();
+	$this->disconnect();
+        return false;
+      }
+    }
+
+    return true;
+  }
+
+
+  /**
+   * Function for sending mail
+   *
+   * @param string Sender e-Mail address
+   *
+   * @param mixed  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 mixed  The message headers to send with the mail
+   *               Either as an associative array or a finally
+   *               formatted string
+   *
+   * @param string The full text of the message body, including any Mime parts, etc.
+   *
+   * @return bool  Returns true on success, or false on error
+   */
+  public function send_mail($from, $recipients, &$headers, &$body)
+  {
+    if (!is_object($this->conn))
+      return false;
+
+    // prepare message headers as string
+    if (is_array($headers))
+    {
+      if (!($headerElements = $this->_prepare_headers($headers))) {
+        $this->reset();
+        return false;
+      }
+
+      list($from, $text_headers) = $headerElements;
+    }
+    else if (is_string($headers))
+      $text_headers = $headers;
+    else
+    {
+      $this->reset();
+      $this->response[] .= "Invalid message headers";
+      return false;
+    }
+
+    // exit if no from address is given
+    if (!isset($from))
+    {
+      $this->reset();
+      $this->response[] .= "No From address has been provided";
+      return false;
+    }
+
+    // set From: address
+    if (PEAR::isError($this->conn->mailFrom($from)))
+    {
+      $this->error = array('label' => 'smtpfromerror', 'vars' => array('from' => $from, 'code' => $this->conn->_code));
+      $this->response[] .= "Failed to set sender '$from'";
+      $this->reset();
+      return false;
+    }
+
+    // prepare list of recipients
+    $recipients = $this->_parse_rfc822($recipients);
+    if (PEAR::isError($recipients))
+    {
+      $this->error = array('label' => 'smtprecipientserror');
+      $this->reset();
+      return false;
+    }
+
+    // set mail recipients
+    foreach ($recipients as $recipient)
+    {
+      if (PEAR::isError($this->conn->rcptTo($recipient))) {
+        $this->error = array('label' => 'smtptoerror', 'vars' => array('to' => $recipient, 'code' => $this->conn->_code));
+        $this->response[] .= "Failed to add recipient '$recipient'";
+        $this->reset();
+        return false;
+      }
+    }
+
+    // Concatenate headers and body so it can be passed by reference to SMTP_CONN->data
+    // so preg_replace in SMTP_CONN->quotedata will store a reference instead of a copy. 
+    // We are still forced to make another copy here for a couple ticks so we don't really 
+    // get to save a copy in the method call.
+    $data = $text_headers . "\r\n" . $body;
+
+    // unset old vars to save data and so we can pass into SMTP_CONN->data by reference.
+    unset($text_headers, $body);
+   
+    // Send the message's headers and the body as SMTP data.
+    if (PEAR::isError($result = $this->conn->data($data)))
+    {
+      $this->error = array('label' => 'smtperror', 'vars' => array('msg' => $result->getMessage()));
+      $this->response[] .= "Failed to send data";
+      $this->reset();
+      return false;
+    }
+
+    $this->response[] = join(': ', $this->conn->getResponse());
+    return true;
+  }
+
+
+  /**
+   * Reset the global SMTP connection
+   * @access public
+   */
+  public function reset()
+  {
+    if (is_object($this->conn))
+      $this->conn->rset();
+  }
+
+
+  /**
+   * Disconnect the global SMTP connection
+   * @access public
+   */
+  public function disconnect()
+  {
+    if (is_object($this->conn)) {
+      $this->conn->disconnect();
+      $this->conn = null;
+    }
+  }
+
+
+  /**
+   * This is our own debug handler for the SMTP connection
+   * @access public
+   */
+  public function debug_handler(&$smtp, $message)
+  {
+    write_log('smtp', preg_replace('/\r\n$/', '', $message));
+  }
+
+
+  /**
+   * Get error message
+   * @access public
+   */
+  public function get_error()
+  {
+    return $this->error;
+  }
+
+
+  /**
+   * Get server response messages array
+   * @access public
+   */
+  public function get_response()
+  {
+    return $this->response;
+  }
+
+
+  /**
+   * 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.
+   * @access private
+   */
+  private function _prepare_headers($headers)
+  {
+    $lines = array();
+    $from = null;
+
+    foreach ($headers as $key => $value)
+    {
+      if (strcasecmp($key, 'From') === 0)
+      {
+        $addresses = $this->_parse_rfc822($value);
+
+        if (is_array($addresses))
+          $from = $addresses[0];
+
+        // Reject envelope From: addresses with spaces.
+        if (strstr($from, ' '))
+          return false;
+
+        $lines[] = $key . ': ' . $value;
+      }
+      else if (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(SMTP_MIME_CRLF, $lines) . SMTP_MIME_CRLF);
+  }
+
+  /**
+   * 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 array An array of forward paths (bare addresses).
+   * @access private
+   */
+  private function _parse_rfc822($recipients)
+  {
+    // if we're passed an array, assume addresses are valid and implode them before parsing.
+    if (is_array($recipients))
+      $recipients = implode(', ', $recipients);
+    
+    $addresses = array();
+    $recipients = rcube_explode_quoted_string(',', $recipients);
+  
+    reset($recipients);
+    while (list($k, $recipient) = each($recipients))
+    {
+      $a = explode(" ", $recipient);
+      while (list($k2, $word) = each($a))
+      {
+        if ((strpos($word, "@") > 0) && (strpos($word, "\"")===false))
+        {
+          $word = preg_replace('/^<|>$/', '', trim($word));
+          if (in_array($word, $addresses)===false)
+            array_push($addresses, $word);
+        }
+      }
+    }
+    return $addresses;
+  }
+
+}
+
+?>
diff --git a/program/steps/mail/func.inc b/program/steps/mail/func.inc
index 4486635..b969c04 100644
--- a/program/steps/mail/func.inc
+++ b/program/steps/mail/func.inc
@@ -19,8 +19,6 @@
 
 */
 
-require_once('include/rcube_smtp.inc');
-
 $EMAIL_ADDRESS_PATTERN = '([a-z0-9][a-z0-9\-\.\+\_]*@[a-z0-9][a-z0-9\-\.]*\\.[a-z]{2,5})';
 
 // actions that do not require imap connection
@@ -1326,8 +1324,12 @@
     unset($message->_headers['Bcc']);
 
     // send message
-    $smtp_response = array();
-    $sent = smtp_mail($from, $a_recipients, ($foo = $message->txtHeaders($send_headers, true)), $msg_body, $smtp_response, $smtp_error);
+    if (!is_object($RCMAIL->smtp))
+      $RCMAIL->smtp_init(true);
+     
+    $sent = $RCMAIL->smtp->send_mail($from, $a_recipients, ($foo = $message->txtHeaders($send_headers, true)), $msg_body);
+    $smtp_response = $RCMAIL->smtp->get_response();
+    $smtp_error = $RCMAIL->smtp->get_error();
 
     // log error
     if (!$sent)

--
Gitblit v1.9.1