WordPress.org

Make WordPress Core

Ticket #21074: 21074-phpmailer-5.2.2-rc2-r22509.patch​

File 21074-phpmailer-5.2.2-rc2-r22509.patch​, 66.4 KB (added by bpetty, 2 years ago)

Refreshed patch based on PHPMailer 5.2.2-rc2 release.

Line 
1diff --git wp-includes/class-phpmailer.php wp-includes/class-phpmailer.php
2index df533c2..bb66770 100644
3--- wp-includes/class-phpmailer.php
4+++ wp-includes/class-phpmailer.php
5@@ -2,7 +2,7 @@
6 /*~ class.phpmailer.php
7 .---------------------------------------------------------------------------.
8 |  Software: PHPMailer - PHP email class                                    |
9-|   Version: 5.2.1                                                          |
10+|   Version: 5.2.2                                                          |
11 |      Site: https://code.google.com/a/apache-extras.org/p/phpmailer/       |
12 | ------------------------------------------------------------------------- |
13 |     Admin: Jim Jagielski (project admininistrator)                        |
14@@ -31,12 +31,15 @@
15  * @author Jim Jagielski
16  * @copyright 2010 - 2012 Jim Jagielski
17  * @copyright 2004 - 2009 Andy Prevost
18- * @version $Id: class.phpmailer.php 450 2010-06-23 16:46:33Z coolbru $
19  * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
20  */
21 
22+
23 if (version_compare(PHP_VERSION, '5.0.0', '<') ) exit("Sorry, this version of PHPMailer will only run on PHP version 5 or greater!\n");
24 
25+/**
26+ * Main PHPMailer class definition
27+ */
28 class PHPMailer {
29 
30   /////////////////////////////////////////////////
31@@ -87,13 +90,22 @@ class PHPMailer {
32   public $FromName          = 'Root User';
33 
34   /**
35-   * Sets the Sender email (Return-Path) of the message.  If not empty,
36+   * Sets the Sender email of the message.  If not empty,
37    * will be sent via -f to sendmail or as 'MAIL FROM' in smtp mode.
38+   * If not empty, and ReturnPath is empty, will also be the
39+   * Return-Path header.
40    * @var string
41    */
42   public $Sender            = '';
43 
44   /**
45+   * Sets the Return-Path of the message.  If empty, it will
46+   * be set to either From or Sender.
47+   * @var string
48+   */
49+  public $ReturnPath        = '';
50+
51+  /**
52    * Sets the Subject of the message.
53    * @var string
54    */
55@@ -130,11 +142,11 @@ class PHPMailer {
56   protected $MIMEHeader     = '';
57 
58   /**
59-   * Stores the complete sent MIME message (Body and Headers)
60+   * Stores the extra header list which CreateHeader() doesn't fold in
61    * @var string
62    * @access protected
63   */
64-  protected $SentMIMEMessage     = '';
65+  protected $mailHeader     = '';
66 
67   /**
68    * Sets word wrapping on the body of the message to a given number of
69@@ -156,6 +168,13 @@ class PHPMailer {
70   public $Sendmail          = '/usr/sbin/sendmail';
71 
72   /**
73+   * Determine if mail() uses a fully sendmail compatible MTA that
74+   * supports sendmail's "-oi -f" options
75+   * @var boolean
76+   */
77+  public $UseSendmailOptions   = true;
78
79+  /**
80    * Path to PHPMailer plugins.  Useful if the SMTP class
81    * is in a different directory than the PHP include path.
82    * @var string
83@@ -183,12 +202,21 @@ class PHPMailer {
84    */
85   public $MessageID         = '';
86 
87+  /**
88+   * Sets the message Date to be used in the Date header.
89+   * If empty, the current date will be added.
90+   * @var string
91+   */
92+  public $MessageDate       = '';
93+
94   /////////////////////////////////////////////////
95   // PROPERTIES FOR SMTP
96   /////////////////////////////////////////////////
97 
98   /**
99-   * Sets the SMTP hosts.  All hosts must be separated by a
100+   * Sets the SMTP hosts.
101+   *
102+   * All hosts must be separated by a
103    * semicolon.  You can also specify a different port
104    * for each host by using this format: [hostname:port]
105    * (e.g. "smtp1.example.com:25;smtp2.example.com").
106@@ -210,8 +238,7 @@ class PHPMailer {
107   public $Helo          = '';
108 
109   /**
110-   * Sets connection prefix.
111-   * Options are "", "ssl" or "tls"
112+   * Sets connection prefix. Options are "", "ssl" or "tls"
113    * @var string
114    */
115   public $SMTPSecure    = '';
116@@ -235,7 +262,25 @@ class PHPMailer {
117   public $Password      = '';
118 
119   /**
120-   * Sets the SMTP server timeout in seconds.
121+   *  Sets SMTP auth type. Options are LOGIN | PLAIN | NTLM  (default LOGIN)
122+   *  @var string
123+   */
124+  public $AuthType      = '';
125
126+  /**
127+   *  Sets SMTP realm.
128+   *  @var string
129+   */
130+  public $Realm         = '';
131+
132+  /**
133+   *  Sets SMTP workstation.
134+   *  @var string
135+   */
136+  public $Workstation   = '';
137+
138+  /**
139+   * Sets the SMTP server   in seconds.
140    * This function will not work with the win32 version.
141    * @var int
142    */
143@@ -248,6 +293,13 @@ class PHPMailer {
144   public $SMTPDebug     = false;
145 
146   /**
147+   * Sets the function/method to use for debugging output.
148+   * Right now we only honor "echo" or "error_log"
149+   * @var string
150+   */
151+  public $Debugoutput     = "echo";
152+
153+  /**
154    * Prevents the SMTP connection from being closed after each mail
155    * sending.  If this is set to true then to close the connection
156    * requires an explicit call to SmtpClose().
157@@ -269,53 +321,69 @@ class PHPMailer {
158   public $SingleToArray = array();
159 
160  /**
161-   * Provides the ability to change the line ending
162+   * Provides the ability to change the generic line ending
163+   * NOTE: The default remains '\n'. We force CRLF where we KNOW
164+   *        it must be used via self::CRLF
165    * @var string
166    */
167   public $LE              = "\n";
168 
169-  /**
170-   * Used with DKIM DNS Resource Record
171+   /**
172+   * Used with DKIM Signing
173+   * required parameter if DKIM is enabled
174+   *
175+   * domain selector example domainkey
176    * @var string
177    */
178-  public $DKIM_selector   = 'phpmailer';
179+  public $DKIM_selector   = '';
180 
181   /**
182-   * Used with DKIM DNS Resource Record
183-   * optional, in format of email address 'you@yourdomain.com'
184+   * Used with DKIM Signing
185+   * required if DKIM is enabled, in format of email address 'you@yourdomain.com' typically used as the source of the email
186    * @var string
187    */
188   public $DKIM_identity   = '';
189 
190   /**
191-   * Used with DKIM DNS Resource Record
192+   * Used with DKIM Signing
193+   * optional parameter if your private key requires a passphras
194    * @var string
195    */
196   public $DKIM_passphrase   = '';
197 
198   /**
199-   * Used with DKIM DNS Resource Record
200-   * optional, in format of email address 'you@yourdomain.com'
201+   * Used with DKIM Singing
202+   * required if DKIM is enabled, in format of email address 'domain.com'
203    * @var string
204    */
205   public $DKIM_domain     = '';
206 
207   /**
208-   * Used with DKIM DNS Resource Record
209-   * optional, in format of email address 'you@yourdomain.com'
210+   * Used with DKIM Signing
211+   * required if DKIM is enabled, path to private key file
212    * @var string
213    */
214   public $DKIM_private    = '';
215 
216   /**
217-   * Callback Action function name
218-   * the function that handles the result of the send email action. Parameters:
219+   * Callback Action function name.
220+   * The function that handles the result of the send email action.
221+   * It is called out by Send() for each email sent.
222+   *
223+   * Value can be:
224+   * - 'function_name' for function names
225+   * - 'Class::Method' for static method calls
226+   * - array($object, 'Method') for calling methods on $object
227+   * See http://php.net/is_callable manual page for more details.
228+   *
229+   * Parameters:
230    *   bool    $result        result of the send action
231    *   string  $to            email address of the recipient
232    *   string  $cc            cc email addresses
233    *   string  $bcc           bcc email addresses
234    *   string  $subject       the subject
235    *   string  $body          the email body
236+   *   string  $from          email address of sender
237    * @var string
238    */
239   public $action_function = ''; //'callbackAction';
240@@ -324,11 +392,11 @@ class PHPMailer {
241    * Sets the PHPMailer Version number
242    * @var string
243    */
244-  public $Version         = '5.2.1';
245+  public $Version         = '5.2.2-rc2';
246 
247   /**
248    * What to use in the X-Mailer header
249-   * @var string
250+   * @var string NULL for default, whitespace for None, or actual string to use
251    */
252   public $XMailer         = '';
253 
254@@ -360,12 +428,47 @@ class PHPMailer {
255   const STOP_MESSAGE  = 0; // message only, continue processing
256   const STOP_CONTINUE = 1; // message?, likely ok to continue processing
257   const STOP_CRITICAL = 2; // message, plus full stop, critical error reached
258-
259+  const CRLF = "\r\n";     // SMTP RFC specified EOL
260
261   /////////////////////////////////////////////////
262   // METHODS, VARIABLES
263   /////////////////////////////////////////////////
264 
265   /**
266+   * Calls actual mail() function, but in a safe_mode aware fashion
267+   * Also, unless sendmail_path points to sendmail (or something that
268+   * claims to be sendmail), don't pass params (not a perfect fix,
269+   * but it will do)
270+   * @param string $to To
271+   * @param string $subject Subject
272+   * @param string $body Message Body
273+   * @param string $header Additional Header(s)
274+   * @param string $params Params
275+   * @access private
276+   * @return bool
277+   */
278+  private function mail_passthru($to, $subject, $body, $header, $params) {
279+    if ( ini_get('safe_mode') || !($this->UseSendmailOptions) ) {
280+        $rt = @mail($to, $this->EncodeHeader($this->SecureHeader($subject)), $body, $header);
281+    } else {
282+        $rt = @mail($to, $this->EncodeHeader($this->SecureHeader($subject)), $body, $header, $params);
283+    }
284+    return $rt;
285+  }
286+
287+  /**
288+   * Outputs debugging info via user-defined method
289+   * @param string $str
290+   */
291+  private function edebug($str) {
292+    if ($this->Debugoutput == "error_log") {
293+        error_log($str);
294+    } else {
295+        echo $str;
296+    }
297+  }
298+
299+  /**
300    * Constructor
301    * @param boolean $exceptions Should we throw external exceptions?
302    */
303@@ -389,6 +492,7 @@ class PHPMailer {
304   /**
305    * Sets Mailer to send message using SMTP.
306    * @return void
307+   * @deprecated
308    */
309   public function IsSMTP() {
310     $this->Mailer = 'smtp';
311@@ -397,6 +501,7 @@ class PHPMailer {
312   /**
313    * Sets Mailer to send message using PHP mail() function.
314    * @return void
315+   * @deprecated
316    */
317   public function IsMail() {
318     $this->Mailer = 'mail';
319@@ -405,6 +510,7 @@ class PHPMailer {
320   /**
321    * Sets Mailer to send message using the $Sendmail program.
322    * @return void
323+   * @deprecated
324    */
325   public function IsSendmail() {
326     if (!stristr(ini_get('sendmail_path'), 'sendmail')) {
327@@ -416,6 +522,7 @@ class PHPMailer {
328   /**
329    * Sets Mailer to send message using the qmail MTA.
330    * @return void
331+   * @deprecated
332    */
333   public function IsQmail() {
334     if (stristr(ini_get('sendmail_path'), 'qmail')) {
335@@ -485,20 +592,20 @@ class PHPMailer {
336       if ($this->exceptions) {
337         throw new phpmailerException('Invalid recipient array: ' . $kind);
338       }
339-         if ($this->SMTPDebug) {
340-        echo $this->Lang('Invalid recipient array').': '.$kind;
341+      if ($this->SMTPDebug) {
342+        $this->edebug($this->Lang('Invalid recipient array').': '.$kind);
343       }
344       return false;
345     }
346     $address = trim($address);
347     $name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim
348-    if (!self::ValidateAddress($address)) {
349+    if (!$this->ValidateAddress($address)) {
350       $this->SetError($this->Lang('invalid_address').': '. $address);
351       if ($this->exceptions) {
352         throw new phpmailerException($this->Lang('invalid_address').': '.$address);
353       }
354-         if ($this->SMTPDebug) {
355-        echo $this->Lang('invalid_address').': '.$address;
356+      if ($this->SMTPDebug) {
357+        $this->edebug($this->Lang('invalid_address').': '.$address);
358       }
359       return false;
360     }
361@@ -521,18 +628,19 @@ class PHPMailer {
362  * Set the From and FromName properties
363  * @param string $address
364  * @param string $name
365+ * @param int $auto Also set Reply-To and Sender
366  * @return boolean
367  */
368   public function SetFrom($address, $name = '', $auto = 1) {
369     $address = trim($address);
370     $name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim
371-    if (!self::ValidateAddress($address)) {
372+    if (!$this->ValidateAddress($address)) {
373       $this->SetError($this->Lang('invalid_address').': '. $address);
374       if ($this->exceptions) {
375         throw new phpmailerException($this->Lang('invalid_address').': '.$address);
376       }
377-         if ($this->SMTPDebug) {
378-        echo $this->Lang('invalid_address').': '.$address;
379+      if ($this->SMTPDebug) {
380+        $this->edebug($this->Lang('invalid_address').': '.$address);
381       }
382       return false;
383     }
384@@ -551,25 +659,19 @@ class PHPMailer {
385 
386   /**
387    * Check that a string looks roughly like an email address should
388-   * Static so it can be used without instantiation
389-   * Tries to use PHP built-in validator in the filter extension (from PHP 5.2), falls back to a reasonably competent regex validator
390-   * Conforms approximately to RFC2822
391-   * @link http://www.hexillion.com/samples/#Regex Original pattern found here
392+   * Static so it can be used without instantiation, public so people can overload
393+   * Conforms to RFC5322: Uses *correct* regex on which FILTER_VALIDATE_EMAIL is
394+   * based; So why not use FILTER_VALIDATE_EMAIL? Because it was broken to
395+   * not allow a@b type valid addresses :(
396+   * @link http://squiloople.com/2009/12/20/email-address-validation/
397+   * @copyright regex Copyright Michael Rushton 2009-10 | http://squiloople.com/ | Feel free to use and redistribute this code. But please keep this copyright notice.
398    * @param string $address The email address to check
399    * @return boolean
400    * @static
401    * @access public
402    */
403   public static function ValidateAddress($address) {
404-    if (function_exists('filter_var')) { //Introduced in PHP 5.2
405-      if(filter_var($address, FILTER_VALIDATE_EMAIL) === FALSE) {
406-        return false;
407-      } else {
408-        return true;
409-      }
410-    } else {
411-      return preg_match('/^(?:[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+\.)*[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+@(?:(?:(?:[a-zA-Z0-9_](?:[a-zA-Z0-9_\-](?!\.)){0,61}[a-zA-Z0-9_-]?\.)+[a-zA-Z0-9_](?:[a-zA-Z0-9_\-](?!$)){0,61}[a-zA-Z0-9_]?)|(?:\[(?:(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\.){3}(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\]))$/', $address);
412-    }
413+       return preg_match('/^(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){255,})(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){65,}@)((?>(?>(?>((?>(?>(?>\x0D\x0A)?[       ])+|(?>[        ]*\x0D\x0A)?[   ]+)?)(\((?>(?2)(?>[\x01-\x08\x0B\x0C\x0E-\'*-\[\]-\x7F]|\\\[\x00-\x7F]|(?3)))*(?2)\)))+(?2))|(?2))?)([!#-\'*+\/-9=?^-~-]+|"(?>(?2)(?>[\x01-\x08\x0B\x0C\x0E-!#-\[\]-\x7F]|\\\[\x00-\x7F]))*(?2)")(?>(?1)\.(?1)(?4))*(?1)@(?!(?1)[a-z0-9-]{64,})(?1)(?>([a-z0-9](?>[a-z0-9-]*[a-z0-9])?)(?>(?1)\.(?!(?1)[a-z0-9-]{64,})(?1)(?5)){0,126}|\[(?:(?>IPv6:(?>([a-f0-9]{1,4})(?>:(?6)){7}|(?!(?:.*[a-f0-9][:\]]){7,})((?6)(?>:(?6)){0,5})?::(?7)?))|(?>(?>IPv6:(?>(?6)(?>:(?6)){5}:|(?!(?:.*[a-f0-9]:){5,})(?8)?::(?>((?6)(?>:(?6)){0,3}):)?))?(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(?>\.(?9)){3}))\])(?1)$/isD', $address);
414   }
415 
416   /////////////////////////////////////////////////
417@@ -587,7 +689,7 @@ class PHPMailer {
418       if(!$this->PreSend()) return false;
419       return $this->PostSend();
420     } catch (phpmailerException $e) {
421-         $this->SentMIMEMessage = '';
422+      $this->mailHeader = '';
423       $this->SetError($e->getMessage());
424       if ($this->exceptions) {
425         throw $e;
426@@ -596,9 +698,13 @@ class PHPMailer {
427     }
428   }
429 
430-  protected function PreSend() {
431+  /**
432+   * Prep mail by constructing all message entities
433+   * @return bool
434+   */
435+  public function PreSend() {
436     try {
437-         $mailHeader = "";
438+      $this->mailHeader = "";
439       if ((count($this->to) + count($this->cc) + count($this->bcc)) < 1) {
440         throw new phpmailerException($this->Lang('provide_address'), self::STOP_CRITICAL);
441       }
442@@ -619,26 +725,25 @@ class PHPMailer {
443       $this->MIMEBody = $this->CreateBody();
444 
445       // To capture the complete message when using mail(), create
446-         // an extra header list which CreateHeader() doesn't fold in
447+      // an extra header list which CreateHeader() doesn't fold in
448       if ($this->Mailer == 'mail') {
449         if (count($this->to) > 0) {
450-          $mailHeader .= $this->AddrAppend("To", $this->to);
451+          $this->mailHeader .= $this->AddrAppend("To", $this->to);
452         } else {
453-          $mailHeader .= $this->HeaderLine("To", "undisclosed-recipients:;");
454+          $this->mailHeader .= $this->HeaderLine("To", "undisclosed-recipients:;");
455         }
456-        $mailHeader .= $this->HeaderLine('Subject', $this->EncodeHeader($this->SecureHeader(trim($this->Subject))));
457+        $this->mailHeader .= $this->HeaderLine('Subject', $this->EncodeHeader($this->SecureHeader(trim($this->Subject))));
458         // if(count($this->cc) > 0) {
459-            // $mailHeader .= $this->AddrAppend("Cc", $this->cc);
460+            // $this->mailHeader .= $this->AddrAppend("Cc", $this->cc);
461         // }
462       }
463 
464       // digitally sign with DKIM if enabled
465-      if ($this->DKIM_domain && $this->DKIM_private) {
466+      if (!empty($this->DKIM_domain) && !empty($this->DKIM_private) && !empty($this->DKIM_selector) && !empty($this->DKIM_domain) && file_exists($this->DKIM_private)) {
467         $header_dkim = $this->DKIM_Add($this->MIMEHeader, $this->EncodeHeader($this->SecureHeader($this->Subject)), $this->MIMEBody);
468         $this->MIMEHeader = str_replace("\r\n", "\n", $header_dkim) . $this->MIMEHeader;
469       }
470 
471-      $this->SentMIMEMessage = sprintf("%s%s\r\n\r\n%s",$this->MIMEHeader,$mailHeader,$this->MIMEBody);
472       return true;
473 
474     } catch (phpmailerException $e) {
475@@ -650,18 +755,28 @@ class PHPMailer {
476     }
477   }
478 
479-  protected function PostSend() {
480+  /**
481+   * Actual Email transport function
482+   * Send the email via the selected mechanism
483+   * @return bool
484+   */
485+  public function PostSend() {
486+    $rtn = false;
487     try {
488       // Choose the mailer and send through it
489       switch($this->Mailer) {
490         case 'sendmail':
491-          return $this->SendmailSend($this->MIMEHeader, $this->MIMEBody);
492+          $rtn = $this->SendmailSend($this->MIMEHeader, $this->MIMEBody);
493+          break;
494         case 'smtp':
495-          return $this->SmtpSend($this->MIMEHeader, $this->MIMEBody);
496+          $rtn = $this->SmtpSend($this->MIMEHeader, $this->MIMEBody);
497+          break;
498         case 'mail':
499-          return $this->MailSend($this->MIMEHeader, $this->MIMEBody);
500+          $rtn = $this->MailSend($this->MIMEHeader, $this->MIMEBody);
501+          break;
502         default:
503-          return $this->MailSend($this->MIMEHeader, $this->MIMEBody);
504+          $rtn = $this->MailSend($this->MIMEHeader, $this->MIMEBody);
505+          break;
506       }
507 
508     } catch (phpmailerException $e) {
509@@ -669,11 +784,12 @@ class PHPMailer {
510       if ($this->exceptions) {
511         throw $e;
512       }
513-         if ($this->SMTPDebug) {
514-        echo $e->getMessage()."\n";
515+      if ($this->SMTPDebug) {
516+        $this->edebug($e->getMessage()."\n");
517       }
518       return false;
519     }
520+    return $rtn;
521   }
522 
523   /**
524@@ -685,7 +801,7 @@ class PHPMailer {
525    */
526   protected function SendmailSend($header, $body) {
527     if ($this->Sender != '') {
528-      $sendmail = sprintf("%s -oi -f %s -t", escapeshellcmd($this->Sendmail), escapeshellarg($this->Sender));
529+      $sendmail = sprintf("%s -oi -f%s -t", escapeshellcmd($this->Sendmail), escapeshellarg($this->Sender));
530     } else {
531       $sendmail = sprintf("%s -oi -t", escapeshellcmd($this->Sendmail));
532     }
533@@ -739,38 +855,24 @@ class PHPMailer {
534     if (empty($this->Sender)) {
535       $params = "-oi ";
536     } else {
537-      $params = sprintf("-oi -f %s", $this->Sender);
538+      $params = sprintf("-oi -f%s", $this->Sender);
539     }
540     if ($this->Sender != '' and !ini_get('safe_mode')) {
541       $old_from = ini_get('sendmail_from');
542       ini_set('sendmail_from', $this->Sender);
543-      if ($this->SingleTo === true && count($toArr) > 1) {
544-        foreach ($toArr as $key => $val) {
545-          $rt = @mail($val, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params);
546-          // implement call back function if it exists
547-          $isSent = ($rt == 1) ? 1 : 0;
548-          $this->doCallback($isSent, $val, $this->cc, $this->bcc, $this->Subject, $body);
549-        }
550-      } else {
551-        $rt = @mail($to, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params);
552+    }
553+    if ($this->SingleTo === true && count($toArr) > 1) {
554+      foreach ($toArr as $key => $val) {
555+        $rt = $this->mail_passthru($val, $this->Subject, $body, $header, $params);
556         // implement call back function if it exists
557         $isSent = ($rt == 1) ? 1 : 0;
558-        $this->doCallback($isSent, $to, $this->cc, $this->bcc, $this->Subject, $body);
559+        $this->doCallback($isSent, $val, $this->cc, $this->bcc, $this->Subject, $body);
560       }
561     } else {
562-      if ($this->SingleTo === true && count($toArr) > 1) {
563-        foreach ($toArr as $key => $val) {
564-          $rt = @mail($val, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header);
565-          // implement call back function if it exists
566-          $isSent = ($rt == 1) ? 1 : 0;
567-          $this->doCallback($isSent, $val, $this->cc, $this->bcc, $this->Subject, $body);
568-        }
569-      } else {
570-        $rt = @mail($to, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header);
571-        // implement call back function if it exists
572-        $isSent = ($rt == 1) ? 1 : 0;
573-        $this->doCallback($isSent, $to, $this->cc, $this->bcc, $this->Subject, $body);
574-      }
575+      $rt = $this->mail_passthru($to, $this->Subject, $body, $header, $params);
576+      // implement call back function if it exists
577+      $isSent = ($rt == 1) ? 1 : 0;
578+      $this->doCallback($isSent, $to, $this->cc, $this->bcc, $this->Subject, $body);
579     }
580     if (isset($old_from)) {
581       ini_set('sendmail_from', $old_from);
582@@ -862,14 +964,16 @@ class PHPMailer {
583    * @return bool
584    */
585   public function SmtpConnect() {
586-    if(is_null($this->smtp)) {
587+    if ($this->smtp === null) {
588       $this->smtp = new SMTP();
589     }
590 
591+    $this->smtp->Timeout = $this->Timeout;
592     $this->smtp->do_debug = $this->SMTPDebug;
593     $hosts = explode(';', $this->Host);
594     $index = 0;
595     $connection = $this->smtp->Connected();
596+    $rtn = true;
597 
598     // Retry while there is no connection
599     try {
600@@ -893,6 +997,7 @@ class PHPMailer {
601 
602           if ($tls) {
603             if (!$this->smtp->StartTLS()) {
604+              $rtn = false;
605               throw new phpmailerException($this->Lang('tls'));
606             }
607 
608@@ -902,23 +1007,27 @@ class PHPMailer {
609 
610           $connection = true;
611           if ($this->SMTPAuth) {
612-            if (!$this->smtp->Authenticate($this->Username, $this->Password)) {
613+            if (!$this->smtp->Authenticate($this->Username, $this->Password, $this->AuthType,
614+                                           $this->Realm, $this->Workstation)) {
615+              $rtn = false;
616               throw new phpmailerException($this->Lang('authenticate'));
617             }
618           }
619         }
620         $index++;
621-        if (!$connection) {
622-          throw new phpmailerException($this->Lang('connect_host'));
623-        }
624+      }
625+      if (!$connection) {
626+        $rtn = false;
627+        throw new phpmailerException($this->Lang('connect_host'));
628       }
629     } catch (phpmailerException $e) {
630       $this->smtp->Reset();
631-         if ($this->exceptions) {
632+      if ($this->exceptions) {
633         throw $e;
634       }
635+      $rtn = false;
636     }
637-    return true;
638+    return $rtn;
639   }
640 
641   /**
642@@ -926,7 +1035,7 @@ class PHPMailer {
643    * @return void
644    */
645   public function SmtpClose() {
646-    if(!is_null($this->smtp)) {
647+    if ($this->smtp !== null) {
648       if($this->smtp->Connected()) {
649         $this->smtp->Quit();
650         $this->smtp->Close();
651@@ -944,23 +1053,24 @@ class PHPMailer {
652   function SetLanguage($langcode = 'en', $lang_path = 'language/') {
653     //Define full set of translatable strings
654     $PHPMAILER_LANG = array(
655-      'provide_address' => 'You must provide at least one recipient email address.',
656+      'authenticate'         => 'SMTP Error: Could not authenticate.',
657+      'connect_host'         => 'SMTP Error: Could not connect to SMTP host.',
658+      'data_not_accepted'    => 'SMTP Error: Data not accepted.',
659+      'empty_message'        => 'Message body empty',
660+      'encoding'             => 'Unknown encoding: ',
661+      'execute'              => 'Could not execute: ',
662+      'file_access'          => 'Could not access file: ',
663+      'file_open'            => 'File Error: Could not open file: ',
664+      'from_failed'          => 'The following From address failed: ',
665+      'instantiate'          => 'Could not instantiate mail function.',
666+      'invalid_address'      => 'Invalid address',
667       'mailer_not_supported' => ' mailer is not supported.',
668-      'execute' => 'Could not execute: ',
669-      'instantiate' => 'Could not instantiate mail function.',
670-      'authenticate' => 'SMTP Error: Could not authenticate.',
671-      'from_failed' => 'The following From address failed: ',
672-      'recipients_failed' => 'SMTP Error: The following recipients failed: ',
673-      'data_not_accepted' => 'SMTP Error: Data not accepted.',
674-      'connect_host' => 'SMTP Error: Could not connect to SMTP host.',
675-      'file_access' => 'Could not access file: ',
676-      'file_open' => 'File Error: Could not open file: ',
677-      'encoding' => 'Unknown encoding: ',
678-      'signing' => 'Signing Error: ',
679-      'smtp_error' => 'SMTP server error: ',
680-      'empty_message' => 'Message body empty',
681-      'invalid_address' => 'Invalid address',
682-      'variable_set' => 'Cannot set or reset variable: '
683+      'provide_address'      => 'You must provide at least one recipient email address.',
684+      'recipients_failed'    => 'SMTP Error: The following recipients failed: ',
685+      'signing'              => 'Signing Error: ',
686+      'smtp_connect_failed'  => 'SMTP Connect() failed.',
687+      'smtp_error'           => 'SMTP server error: ',
688+      'variable_set'         => 'Cannot set or reset variable: '
689     );
690     //Overwrite language-specific strings. This way we'll never have missing translations - no more "language string failed to load"!
691     $l = true;
692@@ -1028,13 +1138,15 @@ class PHPMailer {
693     // If utf-8 encoding is used, we will need to make sure we don't
694     // split multibyte characters when we wrap
695     $is_utf8 = (strtolower($this->CharSet) == "utf-8");
696+    $lelen = strlen($this->LE);
697+    $crlflen = strlen(self::CRLF);
698 
699     $message = $this->FixEOL($message);
700-    if (substr($message, -1) == $this->LE) {
701-      $message = substr($message, 0, -1);
702+    if (substr($message, -$lelen) == $this->LE) {
703+      $message = substr($message, 0, -$lelen);
704     }
705 
706-    $line = explode($this->LE, $message);
707+    $line = explode($this->LE, $message);   // Magic. We know FixEOL uses $LE
708     $message = '';
709     for ($i = 0 ;$i < count($line); $i++) {
710       $line_part = explode(' ', $line[$i]);
711@@ -1042,7 +1154,7 @@ class PHPMailer {
712       for ($e = 0; $e<count($line_part); $e++) {
713         $word = $line_part[$e];
714         if ($qp_mode and (strlen($word) > $length)) {
715-          $space_left = $length - strlen($buf) - 1;
716+          $space_left = $length - strlen($buf) - $crlflen;
717           if ($e != 0) {
718             if ($space_left > 20) {
719               $len = $space_left;
720@@ -1056,7 +1168,7 @@ class PHPMailer {
721               $part = substr($word, 0, $len);
722               $word = substr($word, $len);
723               $buf .= ' ' . $part;
724-              $message .= $buf . sprintf("=%s", $this->LE);
725+              $message .= $buf . sprintf("=%s", self::CRLF);
726             } else {
727               $message .= $buf . $soft_break;
728             }
729@@ -1075,7 +1187,7 @@ class PHPMailer {
730             $word = substr($word, $len);
731 
732             if (strlen($word) > 0) {
733-              $message .= $part . sprintf("=%s", $this->LE);
734+              $message .= $part . sprintf("=%s", self::CRLF);
735             } else {
736               $buf = $part;
737             }
738@@ -1090,7 +1202,7 @@ class PHPMailer {
739           }
740         }
741       }
742-      $message .= $buf . $this->LE;
743+      $message .= $buf . self::CRLF;
744     }
745 
746     return $message;
747@@ -1175,8 +1287,15 @@ class PHPMailer {
748     $this->boundary[2] = 'b2_' . $uniq_id;
749     $this->boundary[3] = 'b3_' . $uniq_id;
750 
751-    $result .= $this->HeaderLine('Date', self::RFCDate());
752-    if($this->Sender == '') {
753+    if ($this->MessageDate == '') {
754+      $result .= $this->HeaderLine('Date', self::RFCDate());
755+    } else {
756+      $result .= $this->HeaderLine('Date', $this->MessageDate);
757+    }
758+
759+    if ($this->ReturnPath) {
760+      $result .= $this->HeaderLine('Return-Path', trim($this->ReturnPath));
761+    } elseif ($this->Sender == '') {
762       $result .= $this->HeaderLine('Return-Path', trim($this->From));
763     } else {
764       $result .= $this->HeaderLine('Return-Path', trim($this->Sender));
765@@ -1195,7 +1314,7 @@ class PHPMailer {
766           $result .= $this->HeaderLine('To', 'undisclosed-recipients:;');
767         }
768       }
769-       }
770+    }
771 
772     $from = array();
773     $from[0][0] = trim($this->From);
774@@ -1227,10 +1346,13 @@ class PHPMailer {
775       $result .= sprintf("Message-ID: <%s@%s>%s", $uniq_id, $this->ServerHostname(), $this->LE);
776     }
777     $result .= $this->HeaderLine('X-Priority', $this->Priority);
778-    if($this->XMailer) {
779-      $result .= $this->HeaderLine('X-Mailer', $this->XMailer);
780+    if ($this->XMailer == '') {
781+        $result .= $this->HeaderLine('X-Mailer', 'PHPMailer '.$this->Version.' (http://code.google.com/a/apache-extras.org/p/phpmailer/)');
782     } else {
783-      $result .= $this->HeaderLine('X-Mailer', 'PHPMailer '.$this->Version.' (http://code.google.com/a/apache-extras.org/p/phpmailer/)');
784+      $myXmailer = trim($this->XMailer);
785+      if ($myXmailer) {
786+        $result .= $this->HeaderLine('X-Mailer', $myXmailer);
787+      }
788     }
789 
790     if($this->ConfirmReadingTo != '') {
791@@ -1257,10 +1379,6 @@ class PHPMailer {
792   public function GetMailMIME() {
793     $result = '';
794     switch($this->message_type) {
795-      case 'plain':
796-        $result .= $this->HeaderLine('Content-Transfer-Encoding', $this->Encoding);
797-        $result .= $this->TextLine('Content-Type: '.$this->ContentType.'; charset="'.$this->CharSet.'"');
798-        break;
799       case 'inline':
800         $result .= $this->HeaderLine('Content-Type', 'multipart/related;');
801         $result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . '"');
802@@ -1277,10 +1395,15 @@ class PHPMailer {
803         $result .= $this->HeaderLine('Content-Type', 'multipart/alternative;');
804         $result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . '"');
805         break;
806+      default:
807+        // Catches case 'plain': and case '':
808+        $result .= $this->HeaderLine('Content-Transfer-Encoding', $this->Encoding);
809+        $result .= $this->TextLine('Content-Type: '.$this->ContentType.'; charset='.$this->CharSet);
810+        break;
811     }
812 
813     if($this->Mailer != 'mail') {
814-      $result .= $this->LE.$this->LE;
815+      $result .= $this->LE;
816     }
817 
818     return $result;
819@@ -1292,7 +1415,7 @@ class PHPMailer {
820    * @return string
821    */
822   public function GetSentMIMEMessage() {
823-    return $this->SentMIMEMessage;
824+    return $this->MIMEHeader . $this->mailHeader . self::CRLF . $this->MIMEBody;
825   }
826 
827 
828@@ -1305,15 +1428,12 @@ class PHPMailer {
829     $body = '';
830 
831     if ($this->sign_key_file) {
832-      $body .= $this->GetMailMIME();
833+      $body .= $this->GetMailMIME().$this->LE;
834     }
835 
836     $this->SetWordWrap();
837 
838     switch($this->message_type) {
839-      case 'plain':
840-        $body .= $this->EncodeString($this->Body, $this->Encoding);
841-        break;
842       case 'inline':
843         $body .= $this->GetBoundary($this->boundary[1], '', '', '');
844         $body .= $this->EncodeString($this->Body, $this->Encoding);
845@@ -1398,6 +1518,10 @@ class PHPMailer {
846         $body .= $this->LE;
847         $body .= $this->AttachAll("attachment", $this->boundary[1]);
848         break;
849+      default:
850+        // catch case 'plain' and case ''
851+        $body .= $this->EncodeString($this->Body, $this->Encoding);
852+        break;
853     }
854 
855     if ($this->IsError()) {
856@@ -1444,7 +1568,7 @@ class PHPMailer {
857       $encoding = $this->Encoding;
858     }
859     $result .= $this->TextLine('--' . $boundary);
860-    $result .= sprintf("Content-Type: %s; charset=\"%s\"", $contentType, $charSet);
861+    $result .= sprintf("Content-Type: %s; charset=%s", $contentType, $charSet);
862     $result .= $this->LE;
863     $result .= $this->HeaderLine('Content-Transfer-Encoding', $encoding);
864     $result .= $this->LE;
865@@ -1533,8 +1657,8 @@ class PHPMailer {
866       if ($this->exceptions) {
867         throw $e;
868       }
869-         if ($this->SMTPDebug) {
870-        echo $e->getMessage()."\n";
871+      if ($this->SMTPDebug) {
872+        $this->edebug($e->getMessage()."\n");
873       }
874       if ( $e->getCode() == self::STOP_CRITICAL ) {
875         return false;
876@@ -1633,28 +1757,28 @@ class PHPMailer {
877       if (!is_readable($path)) {
878         throw new phpmailerException($this->Lang('file_open') . $path, self::STOP_CONTINUE);
879       }
880-      if (function_exists('get_magic_quotes')) {
881-        function get_magic_quotes() {
882-          return false;
883-        }
884-      }
885-         $magic_quotes = get_magic_quotes_runtime();
886-         if ($magic_quotes) {
887+      //  if (!function_exists('get_magic_quotes')) {
888+      //    function get_magic_quotes() {
889+      //      return false;
890+      //    }
891+      //  }
892+      $magic_quotes = get_magic_quotes_runtime();
893+      if ($magic_quotes) {
894         if (version_compare(PHP_VERSION, '5.3.0', '<')) {
895           set_magic_quotes_runtime(0);
896         } else {
897-                 ini_set('magic_quotes_runtime', 0);
898-               }
899-         }
900+          ini_set('magic_quotes_runtime', 0);
901+        }
902+      }
903       $file_buffer  = file_get_contents($path);
904       $file_buffer  = $this->EncodeString($file_buffer, $encoding);
905-         if ($magic_quotes) {
906+      if ($magic_quotes) {
907         if (version_compare(PHP_VERSION, '5.3.0', '<')) {
908           set_magic_quotes_runtime($magic_quotes);
909         } else {
910-                 ini_set('magic_quotes_runtime', $magic_quotes);
911-           }
912-         }
913+          ini_set('magic_quotes_runtime', $magic_quotes);
914+        }
915+      }
916       return $file_buffer;
917     } catch (Exception $e) {
918       $this->SetError($e->getMessage());
919@@ -1737,7 +1861,7 @@ class PHPMailer {
920       if (function_exists('mb_strlen') && $this->HasMultiBytes($str)) {
921         // Use a custom function which correctly encodes and wraps long
922         // multibyte strings without breaking lines within a character
923-        $encoded = $this->Base64EncodeWrapMB($str);
924+        $encoded = $this->Base64EncodeWrapMB($str, "\n");
925       } else {
926         $encoded = base64_encode($str);
927         $maxlen -= $maxlen % 4;
928@@ -1747,7 +1871,7 @@ class PHPMailer {
929       $encoding = 'Q';
930       $encoded = $this->EncodeQ($str, $position);
931       $encoded = $this->WrapText($encoded, $maxlen, true);
932-      $encoded = str_replace('='.$this->LE, "\n", trim($encoded));
933+      $encoded = str_replace('='.self::CRLF, "\n", trim($encoded));
934     }
935 
936     $encoded = preg_replace('/^(.*)$/m', " =?".$this->CharSet."?$encoding?\\1?=", $encoded);
937@@ -1776,12 +1900,16 @@ class PHPMailer {
938    * Adapted from a function by paravoid at http://uk.php.net/manual/en/function.mb-encode-mimeheader.php
939    * @access public
940    * @param string $str multi-byte text to wrap encode
941+   * @param string $lf string to use as linefeed/end-of-line
942    * @return string
943    */
944-  public function Base64EncodeWrapMB($str) {
945+  public function Base64EncodeWrapMB($str, $lf=null) {
946     $start = "=?".$this->CharSet."?B?";
947     $end = "?=";
948     $encoded = "";
949+    if ($lf === null) {
950+      $lf = $this->LE;
951+    }
952 
953     $mb_length = mb_strlen($str, $this->CharSet);
954     // Each line must have length <= 75, including $start and $end
955@@ -1802,11 +1930,11 @@ class PHPMailer {
956       }
957       while (strlen($chunk) > $length);
958 
959-      $encoded .= $chunk . $this->LE;
960+      $encoded .= $chunk . $lf;
961     }
962 
963     // Chomp the last linefeed
964-    $encoded = substr($encoded, 0, -strlen($this->LE));
965+    $encoded = substr($encoded, 0, -strlen($lf));
966     return $encoded;
967   }
968 
969@@ -1901,29 +2029,37 @@ class PHPMailer {
970    * @return string
971    */
972   public function EncodeQ($str, $position = 'text') {
973-    // There should not be any EOL in the string
974-    $encoded = preg_replace('/[\r\n]*/', '', $str);
975-
976+    //There should not be any EOL in the string
977+       $pattern="";
978+    $encoded = str_replace(array("\r", "\n"), '', $str);
979     switch (strtolower($position)) {
980       case 'phrase':
981-        $encoded = preg_replace("/([^A-Za-z0-9!*+\/ -])/e", "'='.sprintf('%02X', ord('\\1'))", $encoded);
982+        $pattern = '^A-Za-z0-9!*+\/ -';
983         break;
984+
985       case 'comment':
986-        $encoded = preg_replace("/([\(\)\"])/e", "'='.sprintf('%02X', ord('\\1'))", $encoded);
987+        $pattern = '\(\)"';
988+        //note that we dont break here!
989+        //for this reason we build the $pattern withoud including delimiters and []
990+
991       case 'text':
992       default:
993-        // Replace every high ascii, control =, ? and _ characters
994-        //TODO using /e (equivalent to eval()) is probably not a good idea
995-        $encoded = preg_replace('/([\000-\011\013\014\016-\037\075\077\137\177-\377])/e',
996-                                "'='.sprintf('%02X', ord(stripslashes('\\1')))", $encoded);
997+        //Replace every high ascii, control =, ? and _ characters
998+        //We put \075 (=) as first value to make sure it's the first one in being converted, preventing double encode
999+        $pattern = '\075\000-\011\013\014\016-\037\077\137\177-\377' . $pattern;
1000         break;
1001     }
1002+   
1003+    if (preg_match_all("/[{$pattern}]/", $encoded, $matches)) {
1004+      foreach (array_unique($matches[0]) as $char) {
1005+        $encoded = str_replace($char, '=' . sprintf('%02X', ord($char)), $encoded);
1006+      }
1007+    }
1008+   
1009+    //Replace every spaces to _ (more readable than =20)
1010+    return str_replace(' ', '_', $encoded);
1011+}
1012 
1013-    // Replace every spaces to _ (more readable than =20)
1014-    $encoded = str_replace(' ', '_', $encoded);
1015-
1016-    return $encoded;
1017-  }
1018 
1019   /**
1020    * Adds a string or binary attachment (non-filesystem) to the list.
1021@@ -2027,7 +2163,7 @@ class PHPMailer {
1022   }
1023 
1024   public function AlternativeExists() {
1025-    return strlen($this->AltBody)>0;
1026+    return !empty($this->AltBody);
1027   }
1028 
1029   /////////////////////////////////////////////////
1030@@ -2115,7 +2251,7 @@ class PHPMailer {
1031    */
1032   protected function SetError($msg) {
1033     $this->error_count++;
1034-    if ($this->Mailer == 'smtp' and !is_null($this->smtp)) {
1035+    if (($this->Mailer == 'smtp') and ($this->smtp !== null)) {
1036       $lasterror = $this->smtp->getError();
1037       if (!empty($lasterror) and array_key_exists('smtp_msg', $lasterror)) {
1038         $msg .= '<p>' . $this->Lang('smtp_error') . $lasterror['smtp_msg'] . "</p>\n";
1039@@ -2184,29 +2320,43 @@ class PHPMailer {
1040   }
1041 
1042   /**
1043-   * Changes every end of line from CR or LF to CRLF.
1044+   * Changes every end of line from CRLF, CR or LF to $this->LE.
1045    * @access public
1046+   * @param string $str String to FixEOL
1047    * @return string
1048    */
1049   public function FixEOL($str) {
1050-    $str = str_replace("\r\n", "\n", $str);
1051-    $str = str_replace("\r", "\n", $str);
1052-    $str = str_replace("\n", $this->LE, $str);
1053-    return $str;
1054+       // condense down to \n
1055+       $nstr = str_replace(array("\r\n", "\r"), "\n", $str);
1056+       // Now convert LE as needed
1057+       if ($this->LE !== "\n") {
1058+               $nstr = str_replace("\n", $this->LE, $nstr);
1059+       }
1060+    return  $nstr;
1061   }
1062 
1063   /**
1064-   * Adds a custom header.
1065+   * Adds a custom header. $name value can be overloaded to contain
1066+   * both header name and value (name:value)
1067    * @access public
1068+   * @param string $name custom header name
1069+   * @param string $value header value
1070    * @return void
1071    */
1072-  public function AddCustomHeader($custom_header) {
1073-    $this->CustomHeader[] = explode(':', $custom_header, 2);
1074+  public function AddCustomHeader($name, $value=null) {
1075+       if ($value === null) {
1076+               // Value passed in as name:value
1077+               $this->CustomHeader[] = explode(':', $name, 2);
1078+       } else {
1079+               $this->CustomHeader[] = array($name, $value);
1080+       }
1081   }
1082 
1083   /**
1084    * Evaluates the message and returns modifications for inline images and backgrounds
1085    * @access public
1086+   * @param string $message Text to be HTML modified
1087+   * @param string $basedir baseline directory for path
1088    * @return $message
1089    */
1090   public function MsgHTML($message, $basedir = '') {
1091@@ -2231,40 +2381,43 @@ class PHPMailer {
1092     }
1093     $this->IsHTML(true);
1094     $this->Body = $message;
1095-       if (empty($this->AltBody)) {
1096-               $textMsg = trim(strip_tags(preg_replace('/<(head|title|style|script)[^>]*>.*?<\/\\1>/s', '', $message)));
1097-               if (!empty($textMsg)) {
1098-                       $this->AltBody = html_entity_decode($textMsg, ENT_QUOTES, $this->CharSet);
1099-               }
1100-       }
1101+    if (empty($this->AltBody)) {
1102+        $textMsg = trim(strip_tags(preg_replace('/<(head|title|style|script)[^>]*>.*?<\/\\1>/s', '', $message)));
1103+        if (!empty($textMsg)) {
1104+            $this->AltBody = html_entity_decode($textMsg, ENT_QUOTES, $this->CharSet);
1105+        }
1106+    }
1107     if (empty($this->AltBody)) {
1108       $this->AltBody = 'To view this email message, open it in a program that understands HTML!' . "\n\n";
1109     }
1110-       return $message;
1111+    return $message;
1112   }
1113 
1114   /**
1115    * Gets the MIME type of the embedded or inline image
1116-   * @param string File extension
1117+   * @param string $ext File extension
1118    * @access public
1119    * @return string MIME type of ext
1120    * @static
1121    */
1122   public static function _mime_types($ext = '') {
1123     $mimes = array(
1124+      'xl'    =>  'application/excel',
1125       'hqx'   =>  'application/mac-binhex40',
1126       'cpt'   =>  'application/mac-compactpro',
1127-      'doc'   =>  'application/msword',
1128       'bin'   =>  'application/macbinary',
1129+      'doc'   =>  'application/msword',
1130+      'doc'   =>  'application/msword',
1131+      'word'  =>  'application/msword',
1132+      'class' =>  'application/octet-stream',
1133+      'dll'   =>  'application/octet-stream',
1134       'dms'   =>  'application/octet-stream',
1135+      'exe'   =>  'application/octet-stream',
1136       'lha'   =>  'application/octet-stream',
1137       'lzh'   =>  'application/octet-stream',
1138-      'exe'   =>  'application/octet-stream',
1139-      'class' =>  'application/octet-stream',
1140       'psd'   =>  'application/octet-stream',
1141-      'so'    =>  'application/octet-stream',
1142       'sea'   =>  'application/octet-stream',
1143-      'dll'   =>  'application/octet-stream',
1144+      'so'    =>  'application/octet-stream',
1145       'oda'   =>  'application/oda',
1146       'pdf'   =>  'application/pdf',
1147       'ai'    =>  'application/postscript',
1148@@ -2282,9 +2435,9 @@ class PHPMailer {
1149       'dxr'   =>  'application/x-director',
1150       'dvi'   =>  'application/x-dvi',
1151       'gtar'  =>  'application/x-gtar',
1152-      'php'   =>  'application/x-httpd-php',
1153-      'php4'  =>  'application/x-httpd-php',
1154       'php3'  =>  'application/x-httpd-php',
1155+      'php4'  =>  'application/x-httpd-php',
1156+      'php'   =>  'application/x-httpd-php',
1157       'phtml' =>  'application/x-httpd-php',
1158       'phps'  =>  'application/x-httpd-php-source',
1159       'js'    =>  'application/x-javascript',
1160@@ -2292,53 +2445,50 @@ class PHPMailer {
1161       'sit'   =>  'application/x-stuffit',
1162       'tar'   =>  'application/x-tar',
1163       'tgz'   =>  'application/x-tar',
1164-      'xhtml' =>  'application/xhtml+xml',
1165       'xht'   =>  'application/xhtml+xml',
1166+      'xhtml' =>  'application/xhtml+xml',
1167       'zip'   =>  'application/zip',
1168       'mid'   =>  'audio/midi',
1169       'midi'  =>  'audio/midi',
1170-      'mpga'  =>  'audio/mpeg',
1171       'mp2'   =>  'audio/mpeg',
1172       'mp3'   =>  'audio/mpeg',
1173+      'mpga'  =>  'audio/mpeg',
1174       'aif'   =>  'audio/x-aiff',
1175-      'aiff'  =>  'audio/x-aiff',
1176       'aifc'  =>  'audio/x-aiff',
1177+      'aiff'  =>  'audio/x-aiff',
1178       'ram'   =>  'audio/x-pn-realaudio',
1179       'rm'    =>  'audio/x-pn-realaudio',
1180       'rpm'   =>  'audio/x-pn-realaudio-plugin',
1181       'ra'    =>  'audio/x-realaudio',
1182-      'rv'    =>  'video/vnd.rn-realvideo',
1183       'wav'   =>  'audio/x-wav',
1184       'bmp'   =>  'image/bmp',
1185       'gif'   =>  'image/gif',
1186       'jpeg'  =>  'image/jpeg',
1187-      'jpg'   =>  'image/jpeg',
1188       'jpe'   =>  'image/jpeg',
1189+      'jpg'   =>  'image/jpeg',
1190       'png'   =>  'image/png',
1191       'tiff'  =>  'image/tiff',
1192       'tif'   =>  'image/tiff',
1193+      'eml'   =>  'message/rfc822',
1194       'css'   =>  'text/css',
1195       'html'  =>  'text/html',
1196       'htm'   =>  'text/html',
1197       'shtml' =>  'text/html',
1198-      'txt'   =>  'text/plain',
1199-      'text'  =>  'text/plain',
1200       'log'   =>  'text/plain',
1201+      'text'  =>  'text/plain',
1202+      'txt'   =>  'text/plain',
1203       'rtx'   =>  'text/richtext',
1204       'rtf'   =>  'text/rtf',
1205       'xml'   =>  'text/xml',
1206       'xsl'   =>  'text/xml',
1207       'mpeg'  =>  'video/mpeg',
1208-      'mpg'   =>  'video/mpeg',
1209       'mpe'   =>  'video/mpeg',
1210-      'qt'    =>  'video/quicktime',
1211+      'mpg'   =>  'video/mpeg',
1212       'mov'   =>  'video/quicktime',
1213+      'qt'    =>  'video/quicktime',
1214+      'rv'    =>  'video/vnd.rn-realvideo',
1215       'avi'   =>  'video/x-msvideo',
1216-      'movie' =>  'video/x-sgi-movie',
1217-      'doc'   =>  'application/msword',
1218-      'word'  =>  'application/msword',
1219-      'xl'    =>  'application/excel',
1220-      'eml'   =>  'message/rfc822'
1221+      'movie' =>  'video/x-sgi-movie'
1222     );
1223     return (!isset($mimes[strtolower($ext)])) ? 'application/octet-stream' : $mimes[strtolower($ext)];
1224   }
1225@@ -2378,9 +2528,7 @@ class PHPMailer {
1226    * @return string
1227    */
1228   public function SecureHeader($str) {
1229-    $str = str_replace("\r", '', $str);
1230-    $str = str_replace("\n", '', $str);
1231-    return trim($str);
1232+    return trim(str_replace(array("\r", "\n"), '', $str));
1233   }
1234 
1235   /**
1236@@ -2487,6 +2635,8 @@ class PHPMailer {
1237     $DKIMtime             = time() ; // Signature Timestamp = seconds since 00:00:00 - Jan 1, 1970 (UTC time zone)
1238     $subject_header       = "Subject: $subject";
1239     $headers              = explode($this->LE, $headers_line);
1240+       $from_header          = "";
1241+       $to_header            = "";
1242     foreach($headers as $header) {
1243       if (strpos($header, 'From:') === 0) {
1244         $from_header = $header;
1245@@ -2512,17 +2662,23 @@ class PHPMailer {
1246                 "\tb=";
1247     $toSign   = $this->DKIM_HeaderC($from_header . "\r\n" . $to_header . "\r\n" . $subject_header . "\r\n" . $dkimhdrs);
1248     $signed   = $this->DKIM_Sign($toSign);
1249-    return "X-PHPMAILER-DKIM: phpmailer.worxware.com\r\n".$dkimhdrs.$signed."\r\n";
1250+    return "X-PHPMAILER-DKIM: code.google.com/a/apache-extras.org/p/phpmailer/\r\n".$dkimhdrs.$signed."\r\n";
1251   }
1252 
1253-  protected function doCallback($isSent, $to, $cc, $bcc, $subject, $body) {
1254-    if (!empty($this->action_function) && function_exists($this->action_function)) {
1255-      $params = array($isSent, $to, $cc, $bcc, $subject, $body);
1256+  /**
1257+   * Perform callback
1258+   */
1259+  protected function doCallback($isSent, $to, $cc, $bcc, $subject, $body, $from=null) {
1260+    if (!empty($this->action_function) && is_callable($this->action_function)) {
1261+      $params = array($isSent, $to, $cc, $bcc, $subject, $body, $from);
1262       call_user_func_array($this->action_function, $params);
1263     }
1264   }
1265 }
1266 
1267+/**
1268+ * Exception handling
1269+ */
1270 class phpmailerException extends Exception {
1271   public function errorMessage() {
1272     $errorMsg = '<strong>' . $this->getMessage() . "</strong><br />\n";
1273diff --git wp-includes/class-smtp.php wp-includes/class-smtp.php
1274index 6977bff..cccaeae 100644
1275--- wp-includes/class-smtp.php
1276+++ wp-includes/class-smtp.php
1277@@ -2,7 +2,7 @@
1278 /*~ class.smtp.php
1279 .---------------------------------------------------------------------------.
1280 |  Software: PHPMailer - PHP email class                                    |
1281-|   Version: 5.2.1                                                          |
1282+|   Version: 5.2.2                                                          |
1283 |      Site: https://code.google.com/a/apache-extras.org/p/phpmailer/       |
1284 | ------------------------------------------------------------------------- |
1285 |     Admin: Jim Jagielski (project admininistrator)                        |
1286@@ -32,7 +32,6 @@
1287  * @author Jim Jagielski
1288  * @copyright 2010 - 2012 Jim Jagielski
1289  * @license http://www.gnu.org/copyleft/lesser.html Distributed under the Lesser General Public License (LGPL)
1290- * @version $Id: class.smtp.php 450 2010-06-23 16:46:33Z coolbru $
1291  */
1292 
1293 /**
1294@@ -51,7 +50,7 @@ class SMTP {
1295   public $SMTP_PORT = 25;
1296 
1297   /**
1298-   *  SMTP reply line ending
1299+   *  SMTP reply line ending (don't change)
1300    *  @var string
1301    */
1302   public $CRLF = "\r\n";
1303@@ -63,16 +62,35 @@ class SMTP {
1304   public $do_debug;       // the level of debug to perform
1305 
1306   /**
1307+   * Sets the function/method to use for debugging output.
1308+   * Right now we only honor "echo" or "error_log"
1309+   * @var string
1310+   */
1311+  public $Debugoutput     = "echo";
1312+
1313+  /**
1314    *  Sets VERP use on/off (default is off)
1315    *  @var bool
1316    */
1317   public $do_verp = false;
1318 
1319   /**
1320+   * Sets the SMTP timeout value for reads, in seconds
1321+   * @var int
1322+   */
1323+  public $Timeout         = 15;
1324+
1325+  /**
1326+   * Sets the SMTP timelimit value for reads, in seconds
1327+   * @var int
1328+   */
1329+  public $Timelimit       = 30;
1330+
1331+  /**
1332    * Sets the SMTP PHPMailer Version number
1333    * @var string
1334    */
1335-  public $Version         = '5.2.1';
1336+  public $Version         = '5.2.2-rc2';
1337 
1338   /////////////////////////////////////////////////
1339   // PROPERTIES, PRIVATE AND PROTECTED
1340@@ -83,6 +101,18 @@ class SMTP {
1341   private $helo_rply; // the reply the server sent to us for HELO
1342 
1343   /**
1344+   * Outputs debugging info via user-defined method
1345+   * @param string $str
1346+   */
1347+  private function edebug($str) {
1348+    if ($this->Debugoutput == "error_log") {
1349+        error_log($str);
1350+    } else {
1351+        echo $str;
1352+    }
1353+  }
1354+
1355+  /**
1356    * Initialize the class so that the data is in a known state.
1357    * @access public
1358    * @return void
1359@@ -139,21 +169,26 @@ class SMTP {
1360                            "errno" => $errno,
1361                            "errstr" => $errstr);
1362       if($this->do_debug >= 1) {
1363-        echo "SMTP -> ERROR: " . $this->error["error"] . ": $errstr ($errno)" . $this->CRLF . '<br />';
1364+        $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": $errstr ($errno)" . $this->CRLF . '<br />');
1365       }
1366       return false;
1367     }
1368 
1369     // SMTP server can take longer to respond, give longer timeout for first read
1370     // Windows does not have support for this timeout function
1371-    if(substr(PHP_OS, 0, 3) != "WIN")
1372-     socket_set_timeout($this->smtp_conn, $tval, 0);
1373+    if(substr(PHP_OS, 0, 3) != "WIN") {
1374+     $max = ini_get('max_execution_time');
1375+     if ($max != 0 && $tval > $max) { // don't bother if unlimited
1376+      @set_time_limit($tval);
1377+     }
1378+     stream_set_timeout($this->smtp_conn, $tval, 0);
1379+    }
1380 
1381     // get any announcement
1382     $announce = $this->get_lines();
1383 
1384     if($this->do_debug >= 2) {
1385-      echo "SMTP -> FROM SERVER:" . $announce . $this->CRLF . '<br />';
1386+      $this->edebug("SMTP -> FROM SERVER:" . $announce . $this->CRLF . '<br />');
1387     }
1388 
1389     return true;
1390@@ -182,7 +217,7 @@ class SMTP {
1391     $code = substr($rply,0,3);
1392 
1393     if($this->do_debug >= 2) {
1394-      echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />';
1395+      $this->edebug("SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />');
1396     }
1397 
1398     if($code != 220) {
1399@@ -191,7 +226,7 @@ class SMTP {
1400                "smtp_code" => $code,
1401                "smtp_msg"  => substr($rply,4));
1402       if($this->do_debug >= 1) {
1403-        echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
1404+        $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />');
1405       }
1406       return false;
1407     }
1408@@ -210,58 +245,158 @@ class SMTP {
1409    * @access public
1410    * @return bool
1411    */
1412-  public function Authenticate($username, $password) {
1413-    // Start authentication
1414-    fputs($this->smtp_conn,"AUTH LOGIN" . $this->CRLF);
1415-
1416-    $rply = $this->get_lines();
1417-    $code = substr($rply,0,3);
1418-
1419-    if($code != 334) {
1420-      $this->error =
1421-        array("error" => "AUTH not accepted from server",
1422-              "smtp_code" => $code,
1423-              "smtp_msg" => substr($rply,4));
1424-      if($this->do_debug >= 1) {
1425-        echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
1426-      }
1427-      return false;
1428-    }
1429-
1430-    // Send encoded username
1431-    fputs($this->smtp_conn, base64_encode($username) . $this->CRLF);
1432-
1433-    $rply = $this->get_lines();
1434-    $code = substr($rply,0,3);
1435-
1436-    if($code != 334) {
1437-      $this->error =
1438-        array("error" => "Username not accepted from server",
1439-              "smtp_code" => $code,
1440-              "smtp_msg" => substr($rply,4));
1441-      if($this->do_debug >= 1) {
1442-        echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
1443-      }
1444-      return false;
1445-    }
1446-
1447-    // Send encoded password
1448-    fputs($this->smtp_conn, base64_encode($password) . $this->CRLF);
1449-
1450-    $rply = $this->get_lines();
1451-    $code = substr($rply,0,3);
1452-
1453-    if($code != 235) {
1454-      $this->error =
1455-        array("error" => "Password not accepted from server",
1456-              "smtp_code" => $code,
1457-              "smtp_msg" => substr($rply,4));
1458-      if($this->do_debug >= 1) {
1459-        echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
1460-      }
1461-      return false;
1462+  public function Authenticate($username, $password, $authtype='LOGIN', $realm='',
1463+                               $workstation='') {
1464+    if (empty($authtype)) {
1465+      $authtype = 'LOGIN';
1466+    }
1467+
1468+    switch ($authtype) {
1469+      case 'PLAIN':
1470+        // Start authentication
1471+        fputs($this->smtp_conn,"AUTH PLAIN" . $this->CRLF);
1472+   
1473+        $rply = $this->get_lines();
1474+        $code = substr($rply,0,3);
1475+   
1476+        if($code != 334) {
1477+          $this->error =
1478+            array("error" => "AUTH not accepted from server",
1479+                  "smtp_code" => $code,
1480+                  "smtp_msg" => substr($rply,4));
1481+          if($this->do_debug >= 1) {
1482+            $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />');
1483+          }
1484+          return false;
1485+        }
1486+        // Send encoded username and password
1487+        fputs($this->smtp_conn, base64_encode("\0".$username."\0".$password) . $this->CRLF);
1488+
1489+        $rply = $this->get_lines();
1490+        $code = substr($rply,0,3);
1491+   
1492+        if($code != 235) {
1493+          $this->error =
1494+            array("error" => "Authentication not accepted from server",
1495+                  "smtp_code" => $code,
1496+                  "smtp_msg" => substr($rply,4));
1497+          if($this->do_debug >= 1) {
1498+            $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />');
1499+          }
1500+          return false;
1501+        }
1502+        break;
1503+      case 'LOGIN':
1504+        // Start authentication
1505+        fputs($this->smtp_conn,"AUTH LOGIN" . $this->CRLF);
1506+   
1507+        $rply = $this->get_lines();
1508+        $code = substr($rply,0,3);
1509+   
1510+        if($code != 334) {
1511+          $this->error =
1512+            array("error" => "AUTH not accepted from server",
1513+                  "smtp_code" => $code,
1514+                  "smtp_msg" => substr($rply,4));
1515+          if($this->do_debug >= 1) {
1516+            $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />');
1517+          }
1518+          return false;
1519+        }
1520+   
1521+        // Send encoded username
1522+        fputs($this->smtp_conn, base64_encode($username) . $this->CRLF);
1523+   
1524+        $rply = $this->get_lines();
1525+        $code = substr($rply,0,3);
1526+   
1527+        if($code != 334) {
1528+          $this->error =
1529+            array("error" => "Username not accepted from server",
1530+                  "smtp_code" => $code,
1531+                  "smtp_msg" => substr($rply,4));
1532+          if($this->do_debug >= 1) {
1533+            $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />');
1534+          }
1535+          return false;
1536+        }
1537+   
1538+        // Send encoded password
1539+        fputs($this->smtp_conn, base64_encode($password) . $this->CRLF);
1540+   
1541+        $rply = $this->get_lines();
1542+        $code = substr($rply,0,3);
1543+   
1544+        if($code != 235) {
1545+          $this->error =
1546+            array("error" => "Password not accepted from server",
1547+                  "smtp_code" => $code,
1548+                  "smtp_msg" => substr($rply,4));
1549+          if($this->do_debug >= 1) {
1550+            $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />');
1551+          }
1552+          return false;
1553+        }
1554+        break;
1555+      case 'NTLM':
1556+        /*
1557+         * ntlm_sasl_client.php
1558+         ** Bundled with Permission
1559+         **
1560+         ** How to telnet in windows: http://technet.microsoft.com/en-us/library/aa995718%28EXCHG.65%29.aspx
1561+         ** PROTOCOL Documentation http://curl.haxx.se/rfc/ntlm.html#ntlmSmtpAuthentication
1562+         */
1563+        require_once('ntlm_sasl_client.php');
1564+        $temp = new stdClass();
1565+        $ntlm_client = new ntlm_sasl_client_class;
1566+        if(! $ntlm_client->Initialize($temp)){//let's test if every function its available
1567+            $this->error = array("error" => $temp->error);
1568+            if($this->do_debug >= 1) {
1569+                $this->edebug("You need to enable some modules in your php.ini file: " . $this->error["error"] . $this->CRLF);
1570+            }
1571+            return false;
1572+        }
1573+        $msg1 = $ntlm_client->TypeMsg1($realm, $workstation);//msg1
1574+       
1575+        fputs($this->smtp_conn,"AUTH NTLM " . base64_encode($msg1) . $this->CRLF);
1576+
1577+        $rply = $this->get_lines();
1578+        $code = substr($rply,0,3);
1579+       
1580+
1581+        if($code != 334) {
1582+            $this->error =
1583+                array("error" => "AUTH not accepted from server",
1584+                      "smtp_code" => $code,
1585+                      "smtp_msg" => substr($rply,4));
1586+            if($this->do_debug >= 1) {
1587+                $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF);
1588+            }
1589+            return false;
1590+        }
1591+       
1592+        $challange = substr($rply,3);//though 0 based, there is a white space after the 3 digit number....//msg2
1593+        $challange = base64_decode($challange);
1594+        $ntlm_res = $ntlm_client->NTLMResponse(substr($challange,24,8),$password);
1595+        $msg3 = $ntlm_client->TypeMsg3($ntlm_res,$username,$realm,$workstation);//msg3
1596+        // Send encoded username
1597+        fputs($this->smtp_conn, base64_encode($msg3) . $this->CRLF);
1598+
1599+        $rply = $this->get_lines();
1600+        $code = substr($rply,0,3);
1601+
1602+        if($code != 235) {
1603+            $this->error =
1604+                array("error" => "Could not authenticate",
1605+                      "smtp_code" => $code,
1606+                      "smtp_msg" => substr($rply,4));
1607+            if($this->do_debug >= 1) {
1608+                $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF);
1609+            }
1610+            return false;
1611+        }
1612+        break;
1613     }
1614-
1615     return true;
1616   }
1617 
1618@@ -276,7 +411,7 @@ class SMTP {
1619       if($sock_status["eof"]) {
1620         // the socket is valid but we are not connected
1621         if($this->do_debug >= 1) {
1622-            echo "SMTP -> NOTICE:" . $this->CRLF . "EOF caught while checking if connected";
1623+            $this->edebug("SMTP -> NOTICE:" . $this->CRLF . "EOF caught while checking if connected");
1624         }
1625         $this->Close();
1626         return false;
1627@@ -341,7 +476,7 @@ class SMTP {
1628     $code = substr($rply,0,3);
1629 
1630     if($this->do_debug >= 2) {
1631-      echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />';
1632+      $this->edebug("SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />');
1633     }
1634 
1635     if($code != 354) {
1636@@ -350,7 +485,7 @@ class SMTP {
1637               "smtp_code" => $code,
1638               "smtp_msg" => substr($rply,4));
1639       if($this->do_debug >= 1) {
1640-        echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
1641+        $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />');
1642       }
1643       return false;
1644     }
1645@@ -435,7 +570,7 @@ class SMTP {
1646     $code = substr($rply,0,3);
1647 
1648     if($this->do_debug >= 2) {
1649-      echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />';
1650+      $this->edebug("SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />');
1651     }
1652 
1653     if($code != 250) {
1654@@ -444,7 +579,7 @@ class SMTP {
1655               "smtp_code" => $code,
1656               "smtp_msg" => substr($rply,4));
1657       if($this->do_debug >= 1) {
1658-        echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
1659+        $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />');
1660       }
1661       return false;
1662     }
1663@@ -500,7 +635,7 @@ class SMTP {
1664     $code = substr($rply,0,3);
1665 
1666     if($this->do_debug >= 2) {
1667-      echo "SMTP -> FROM SERVER: " . $rply . $this->CRLF . '<br />';
1668+      $this->edebug("SMTP -> FROM SERVER: " . $rply . $this->CRLF . '<br />');
1669     }
1670 
1671     if($code != 250) {
1672@@ -509,7 +644,7 @@ class SMTP {
1673               "smtp_code" => $code,
1674               "smtp_msg" => substr($rply,4));
1675       if($this->do_debug >= 1) {
1676-        echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
1677+        $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />');
1678       }
1679       return false;
1680     }
1681@@ -542,14 +677,14 @@ class SMTP {
1682       return false;
1683     }
1684 
1685-    $useVerp = ($this->do_verp ? "XVERP" : "");
1686+    $useVerp = ($this->do_verp ? " XVERP" : "");
1687     fputs($this->smtp_conn,"MAIL FROM:<" . $from . ">" . $useVerp . $this->CRLF);
1688 
1689     $rply = $this->get_lines();
1690     $code = substr($rply,0,3);
1691 
1692     if($this->do_debug >= 2) {
1693-      echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />';
1694+      $this->edebug("SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />');
1695     }
1696 
1697     if($code != 250) {
1698@@ -558,7 +693,7 @@ class SMTP {
1699               "smtp_code" => $code,
1700               "smtp_msg" => substr($rply,4));
1701       if($this->do_debug >= 1) {
1702-        echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
1703+        $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />');
1704       }
1705       return false;
1706     }
1707@@ -592,7 +727,7 @@ class SMTP {
1708     $byemsg = $this->get_lines();
1709 
1710     if($this->do_debug >= 2) {
1711-      echo "SMTP -> FROM SERVER:" . $byemsg . $this->CRLF . '<br />';
1712+      $this->edebug("SMTP -> FROM SERVER:" . $byemsg . $this->CRLF . '<br />');
1713     }
1714 
1715     $rval = true;
1716@@ -606,7 +741,7 @@ class SMTP {
1717                  "smtp_rply" => substr($byemsg,4));
1718       $rval = false;
1719       if($this->do_debug >= 1) {
1720-        echo "SMTP -> ERROR: " . $e["error"] . ": " . $byemsg . $this->CRLF . '<br />';
1721+        $this->edebug("SMTP -> ERROR: " . $e["error"] . ": " . $byemsg . $this->CRLF . '<br />');
1722       }
1723     }
1724 
1725@@ -644,7 +779,7 @@ class SMTP {
1726     $code = substr($rply,0,3);
1727 
1728     if($this->do_debug >= 2) {
1729-      echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />';
1730+      $this->edebug("SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />');
1731     }
1732 
1733     if($code != 250 && $code != 251) {
1734@@ -653,7 +788,7 @@ class SMTP {
1735               "smtp_code" => $code,
1736               "smtp_msg" => substr($rply,4));
1737       if($this->do_debug >= 1) {
1738-        echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
1739+        $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />');
1740       }
1741       return false;
1742     }
1743@@ -687,7 +822,7 @@ class SMTP {
1744     $code = substr($rply,0,3);
1745 
1746     if($this->do_debug >= 2) {
1747-      echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />';
1748+      $this->edebug("SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />');
1749     }
1750 
1751     if($code != 250) {
1752@@ -696,7 +831,7 @@ class SMTP {
1753               "smtp_code" => $code,
1754               "smtp_msg" => substr($rply,4));
1755       if($this->do_debug >= 1) {
1756-        echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
1757+        $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />');
1758       }
1759       return false;
1760     }
1761@@ -735,7 +870,7 @@ class SMTP {
1762     $code = substr($rply,0,3);
1763 
1764     if($this->do_debug >= 2) {
1765-      echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />';
1766+      $this->edebug("SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />');
1767     }
1768 
1769     if($code != 250) {
1770@@ -744,7 +879,7 @@ class SMTP {
1771               "smtp_code" => $code,
1772               "smtp_msg" => substr($rply,4));
1773       if($this->do_debug >= 1) {
1774-        echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
1775+        $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />');
1776       }
1777       return false;
1778     }
1779@@ -768,7 +903,7 @@ class SMTP {
1780     $this->error = array("error" => "This method, TURN, of the SMTP ".
1781                                     "is not implemented");
1782     if($this->do_debug >= 1) {
1783-      echo "SMTP -> NOTICE: " . $this->error["error"] . $this->CRLF . '<br />';
1784+      $this->edebug("SMTP -> NOTICE: " . $this->error["error"] . $this->CRLF . '<br />');
1785     }
1786     return false;
1787   }
1788@@ -797,18 +932,44 @@ class SMTP {
1789    */
1790   private function get_lines() {
1791     $data = "";
1792-    while(!feof($this->smtp_conn)) {
1793+    $endtime = 0;
1794+    /* If for some reason the fp is bad, don't inf loop */
1795+    if (!is_resource($this->smtp_conn)) {
1796+      return $data;
1797+    }
1798+    stream_set_timeout($this->smtp_conn, $this->Timeout);
1799+    if ($this->Timelimit > 0) {
1800+      $endtime = time() + $this->Timelimit;
1801+    }
1802+    while(is_resource($this->smtp_conn) && !feof($this->smtp_conn)) {
1803       $str = @fgets($this->smtp_conn,515);
1804       if($this->do_debug >= 4) {
1805-        echo "SMTP -> get_lines(): \$data was \"$data\"" . $this->CRLF . '<br />';
1806-        echo "SMTP -> get_lines(): \$str is \"$str\"" . $this->CRLF . '<br />';
1807+        $this->edebug("SMTP -> get_lines(): \$data was \"$data\"" . $this->CRLF . '<br />');
1808+        $this->edebug("SMTP -> get_lines(): \$str is \"$str\"" . $this->CRLF . '<br />');
1809       }
1810       $data .= $str;
1811       if($this->do_debug >= 4) {
1812-        echo "SMTP -> get_lines(): \$data is \"$data\"" . $this->CRLF . '<br />';
1813+        $this->edebug("SMTP -> get_lines(): \$data is \"$data\"" . $this->CRLF . '<br />');
1814       }
1815       // if 4th character is a space, we are done reading, break the loop
1816       if(substr($str,3,1) == " ") { break; }
1817+      // Timed-out? Log and break
1818+      $info = stream_get_meta_data($this->smtp_conn);
1819+      if ($info['timed_out']) {
1820+        if($this->do_debug >= 4) {
1821+          $this->edebug("SMTP -> get_lines(): timed-out (" . $this->Timeout . " seconds) <br />");
1822+        }
1823+        break;
1824+      }
1825+      // Now check if reads took too long
1826+      if ($endtime) {
1827+        if (time() > $endtime) {
1828+          if($this->do_debug >= 4) {
1829+            $this->edebug("SMTP -> get_lines(): timelimit reached (" . $this->Timelimit . " seconds) <br />");
1830+          }
1831+          break;
1832+        }
1833+      }
1834     }
1835     return $data;
1836   }