WordPress.org

Make WordPress Core

Changeset 8762


Ignore:
Timestamp:
08/28/08 20:26:36 (6 years ago)
Author:
ryan
Message:

Update phpMailer to 2.0.2. Props mattyrob. fixes #7474

Location:
trunk/wp-includes
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/wp-includes/class-phpmailer.php

    r8082 r8762  
    11<?php 
    2 /** 
    3  * PHPMailer - PHP email class 
    4  * 
    5  * Class for sending email using either sendmail, PHP mail(), or SMTP. Methods 
    6  * are based upon the standard AspEmail(tm) classes. 
    7  * 
    8  * @copyright 2001 - 2003 Brent R. Matzelle 
    9  * @license LGPL 
    10  * @package PHPMailer 
    11  */ 
     2/*~ class.phpmailer.php 
     3.---------------------------------------------------------------------------. 
     4|  Software: PHPMailer - PHP email class                                    | 
     5|   Version: 2.0.2                                                          | 
     6|   Contact: via sourceforge.net support pages (also www.codeworxtech.com)  | 
     7|      Info: http://phpmailer.sourceforge.net                               | 
     8|   Support: http://sourceforge.net/projects/phpmailer/                     | 
     9| ------------------------------------------------------------------------- | 
     10|    Author: Andy Prevost (project admininistrator)                         | 
     11|    Author: Brent R. Matzelle (original founder)                           | 
     12| Copyright (c) 2004-2007, Andy Prevost. All Rights Reserved.               | 
     13| Copyright (c) 2001-2003, Brent R. Matzelle                                | 
     14| ------------------------------------------------------------------------- | 
     15|   License: Distributed under the Lesser General Public License (LGPL)     | 
     16|            http://www.gnu.org/copyleft/lesser.html                        | 
     17| This program is distributed in the hope that it will be useful - WITHOUT  | 
     18| ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or     | 
     19| FITNESS FOR A PARTICULAR PURPOSE.                                         | 
     20| ------------------------------------------------------------------------- | 
     21| We offer a number of paid services (www.codeworxtech.com):                | 
     22| - Web Hosting on highly optimized fast and secure servers                 | 
     23| - Technology Consulting                                                   | 
     24| - Oursourcing (highly qualified programmers and graphic designers)        | 
     25'---------------------------------------------------------------------------' 
    1226 
    1327/** 
    1428 * PHPMailer - PHP email transport class 
    1529 * @package PHPMailer 
    16  * @author Brent R. Matzelle 
    17  * @copyright 2001 - 2003 Brent R. Matzelle 
     30 * @author Andy Prevost 
     31 * @copyright 2004 - 2008 Andy Prevost 
    1832 */ 
    19 class PHPMailer 
    20 { 
    21     ///////////////////////////////////////////////// 
    22     // PUBLIC VARIABLES 
    23     ///////////////////////////////////////////////// 
    24  
    25     /** 
    26      * Email priority (1 = High, 3 = Normal, 5 = low). 
    27      * @var int 
    28      */ 
    29     var $Priority          = 3; 
    30  
    31     /** 
    32      * Sets the CharSet of the message. 
    33      * @var string 
    34      */ 
    35     var $CharSet           = "UTF-8"; 
    36  
    37     /** 
    38      * Sets the Content-type of the message. 
    39      * @var string 
    40      */ 
    41     var $ContentType        = "text/plain"; 
    42  
    43     /** 
    44      * Sets the Encoding of the message. Options for this are "8bit", 
    45      * "7bit", "binary", "base64", and "quoted-printable". 
    46      * @var string 
    47      */ 
    48     var $Encoding          = "8bit"; 
    49  
    50     /** 
    51      * Holds the most recent mailer error message. 
    52      * @var string 
    53      */ 
    54     var $ErrorInfo         = ""; 
    55  
    56     /** 
    57      * Sets the From email address for the message. 
    58      * @var string 
    59      */ 
    60     var $From               = "localhost.localdomain"; 
    61  
    62     /** 
    63      * Sets the From name of the message. 
    64      * @var string 
    65      */ 
    66     var $FromName           = "Support"; 
    67  
    68     /** 
    69      * Sets the Sender email (Return-Path) of the message.  If not empty, 
    70      * will be sent via -f to sendmail or as 'MAIL FROM' in smtp mode. 
    71      * @var string 
    72      */ 
    73     var $Sender            = ""; 
    74  
    75     /** 
    76      * Sets the Subject of the message. 
    77      * @var string 
    78      */ 
    79     var $Subject           = ""; 
    80  
    81     /** 
    82      * Sets the Body of the message.  This can be either an HTML or text body. 
    83      * If HTML then run IsHTML(true). 
    84      * @var string 
    85      */ 
    86     var $Body               = ""; 
    87  
    88     /** 
    89      * Sets the text-only body of the message.  This automatically sets the 
    90      * email to multipart/alternative.  This body can be read by mail 
    91      * clients that do not have HTML email capability such as mutt. Clients 
    92      * that can read HTML will view the normal Body. 
    93      * @var string 
    94      */ 
    95     var $AltBody           = ""; 
    96  
    97     /** 
    98      * Sets word wrapping on the body of the message to a given number of 
    99      * characters. 
    100      * @var int 
    101      */ 
    102     var $WordWrap          = 0; 
    103  
    104     /** 
    105      * Method to send mail: ("mail", "sendmail", or "smtp"). 
    106      * @var string 
    107      */ 
    108     var $Mailer            = "mail"; 
    109  
    110     /** 
    111      * Sets the path of the sendmail program. 
    112      * @var string 
    113      */ 
    114     var $Sendmail          = "/usr/sbin/sendmail"; 
    115  
    116     /** 
    117      * Path to PHPMailer plugins.  This is now only useful if the SMTP class 
    118      * is in a different directory than the PHP include path. 
    119      * @var string 
    120      */ 
    121     var $PluginDir         = ""; 
    122  
    123     /** 
    124      *  Holds PHPMailer version. 
    125      *  @var string 
    126      */ 
    127     var $Version           = "1.73"; 
    128  
    129     /** 
    130      * Sets the email address that a reading confirmation will be sent. 
    131      * @var string 
    132      */ 
    133     var $ConfirmReadingTo  = ""; 
    134  
    135     /** 
    136      *  Sets the hostname to use in Message-Id and Received headers 
    137      *  and as default HELO string. If empty, the value returned 
    138      *  by SERVER_NAME is used or 'localhost.localdomain'. 
    139      *  @var string 
    140      */ 
    141     var $Hostname          = ""; 
    142  
    143     ///////////////////////////////////////////////// 
    144     // SMTP VARIABLES 
    145     ///////////////////////////////////////////////// 
    146  
    147     /** 
    148      *  Sets the SMTP hosts.  All hosts must be separated by a 
    149      *  semicolon.  You can also specify a different port 
    150      *  for each host by using this format: [hostname:port] 
    151      *  (e.g. "smtp1.example.com:25;smtp2.example.com"). 
    152      *  Hosts will be tried in order. 
    153      *  @var string 
    154      */ 
    155     var $Host        = "localhost"; 
    156  
    157     /** 
    158      *  Sets the default SMTP server port. 
    159      *  @var int 
    160      */ 
    161     var $Port        = 25; 
    162  
    163     /** 
    164      *  Sets the SMTP HELO of the message (Default is $Hostname). 
    165      *  @var string 
    166      */ 
    167     var $Helo        = ""; 
    168  
    169     /** 
    170      *  Sets SMTP authentication. Utilizes the Username and Password variables. 
    171      *  @var bool 
    172      */ 
    173     var $SMTPAuth     = false; 
    174  
    175     /** 
    176      *  Sets SMTP username. 
    177      *  @var string 
    178      */ 
    179     var $Username     = ""; 
    180  
    181     /** 
    182      *  Sets SMTP password. 
    183      *  @var string 
    184      */ 
    185     var $Password     = ""; 
    186  
    187     /** 
    188      *  Sets the SMTP server timeout in seconds. This function will not 
    189      *  work with the win32 version. 
    190      *  @var int 
    191      */ 
    192     var $Timeout      = 10; 
    193  
    194     /** 
    195      *  Sets SMTP class debugging on or off. 
    196      *  @var bool 
    197      */ 
    198     var $SMTPDebug    = false; 
    199  
    200     /** 
    201      * Prevents the SMTP connection from being closed after each mail 
    202      * sending.  If this is set to true then to close the connection 
    203      * requires an explicit call to SmtpClose(). 
    204      * @var bool 
    205      */ 
    206     var $SMTPKeepAlive = false; 
    207  
    208     /**#@+ 
    209      * @access private 
    210      */ 
    211     var $smtp            = NULL; 
    212     var $to              = array(); 
    213     var $cc              = array(); 
    214     var $bcc             = array(); 
    215     var $ReplyTo         = array(); 
    216     var $attachment      = array(); 
    217     var $CustomHeader    = array(); 
    218     var $message_type    = ""; 
    219     var $boundary        = array(); 
    220     var $language        = array(); 
    221     var $error_count     = 0; 
    222     var $LE              = "\n"; 
    223     /**#@-*/ 
    224  
    225     ///////////////////////////////////////////////// 
    226     // VARIABLE METHODS 
    227     ///////////////////////////////////////////////// 
    228  
    229     /** 
    230      * Sets message type to HTML. 
    231      * @param bool $bool 
    232      * @return void 
    233      */ 
    234     function IsHTML($bool) { 
    235         if($bool == true) 
    236             $this->ContentType = "text/html"; 
    237         else 
    238             $this->ContentType = "text/plain"; 
    239     } 
    240  
    241     /** 
    242      * Sets Mailer to send message using SMTP. 
    243      * @return void 
    244      */ 
    245     function IsSMTP() { 
    246         $this->Mailer = "smtp"; 
    247     } 
    248  
    249     /** 
    250      * Sets Mailer to send message using PHP mail() function. 
    251      * @return void 
    252      */ 
    253     function IsMail() { 
    254         $this->Mailer = "mail"; 
    255     } 
    256  
    257     /** 
    258      * Sets Mailer to send message using the $Sendmail program. 
    259      * @return void 
    260      */ 
    261     function IsSendmail() { 
    262         $this->Mailer = "sendmail"; 
    263     } 
    264  
    265     /** 
    266      * Sets Mailer to send message using the qmail MTA. 
    267      * @return void 
    268      */ 
    269     function IsQmail() { 
    270         $this->Sendmail = "/var/qmail/bin/sendmail"; 
    271         $this->Mailer = "sendmail"; 
    272     } 
    273  
    274  
    275     ///////////////////////////////////////////////// 
    276     // RECIPIENT METHODS 
    277     ///////////////////////////////////////////////// 
    278  
    279     /** 
    280      * Adds a "To" address. 
    281      * @param string $address 
    282      * @param string $name 
    283      * @return void 
    284      */ 
    285     function AddAddress($address, $name = "") { 
    286         $cur = count($this->to); 
    287         $this->to[$cur][0] = trim($address); 
    288         $this->to[$cur][1] = $name; 
    289     } 
    290  
    291     /** 
    292      * Adds a "Cc" address. Note: this function works 
    293      * with the SMTP mailer on win32, not with the "mail" 
    294      * mailer. 
    295      * @param string $address 
    296      * @param string $name 
    297      * @return void 
    298     */ 
    299     function AddCC($address, $name = "") { 
    300         $cur = count($this->cc); 
    301         $this->cc[$cur][0] = trim($address); 
    302         $this->cc[$cur][1] = $name; 
    303     } 
    304  
    305     /** 
    306      * Adds a "Bcc" address. Note: this function works 
    307      * with the SMTP mailer on win32, not with the "mail" 
    308      * mailer. 
    309      * @param string $address 
    310      * @param string $name 
    311      * @return void 
    312      */ 
    313     function AddBCC($address, $name = "") { 
    314         $cur = count($this->bcc); 
    315         $this->bcc[$cur][0] = trim($address); 
    316         $this->bcc[$cur][1] = $name; 
    317     } 
    318  
    319     /** 
    320      * Adds a "Reply-to" address. 
    321      * @param string $address 
    322      * @param string $name 
    323      * @return void 
    324      */ 
    325     function AddReplyTo($address, $name = "") { 
    326         $cur = count($this->ReplyTo); 
    327         $this->ReplyTo[$cur][0] = trim($address); 
    328         $this->ReplyTo[$cur][1] = $name; 
    329     } 
    330  
    331  
    332     ///////////////////////////////////////////////// 
    333     // MAIL SENDING METHODS 
    334     ///////////////////////////////////////////////// 
    335  
    336     /** 
    337      * Creates message and assigns Mailer. If the message is 
    338      * not sent successfully then it returns false.  Use the ErrorInfo 
    339      * variable to view description of the error. 
    340      * @return bool 
    341      */ 
    342     function Send() { 
    343         $header = ""; 
    344         $body = ""; 
    345         $result = true; 
    346  
    347         if((count($this->to) + count($this->cc) + count($this->bcc)) < 1) 
    348         { 
    349             $this->SetError($this->Lang("provide_address")); 
    350             return false; 
     33 
     34class PHPMailer { 
     35 
     36  ///////////////////////////////////////////////// 
     37  // PROPERTIES, PUBLIC 
     38  ///////////////////////////////////////////////// 
     39 
     40  /** 
     41   * Email priority (1 = High, 3 = Normal, 5 = low). 
     42   * @var int 
     43   */ 
     44  var $Priority          = 3; 
     45 
     46  /** 
     47   * Sets the CharSet of the message. 
     48   * @var string 
     49   */ 
     50  var $CharSet           = 'iso-8859-1'; 
     51 
     52  /** 
     53   * Sets the Content-type of the message. 
     54   * @var string 
     55   */ 
     56  var $ContentType        = 'text/plain'; 
     57 
     58  /** 
     59   * Sets the Encoding of the message. Options for this are "8bit", 
     60   * "7bit", "binary", "base64", and "quoted-printable". 
     61   * @var string 
     62   */ 
     63  var $Encoding          = '8bit'; 
     64 
     65  /** 
     66   * Holds the most recent mailer error message. 
     67   * @var string 
     68   */ 
     69  var $ErrorInfo         = ''; 
     70 
     71  /** 
     72   * Sets the From email address for the message. 
     73   * @var string 
     74   */ 
     75  var $From              = 'root@localhost'; 
     76 
     77  /** 
     78   * Sets the From name of the message. 
     79   * @var string 
     80   */ 
     81  var $FromName          = 'Root User'; 
     82 
     83  /** 
     84   * Sets the Sender email (Return-Path) of the message.  If not empty, 
     85   * will be sent via -f to sendmail or as 'MAIL FROM' in smtp mode. 
     86   * @var string 
     87   */ 
     88  var $Sender            = ''; 
     89 
     90  /** 
     91   * Sets the Subject of the message. 
     92   * @var string 
     93   */ 
     94  var $Subject           = ''; 
     95 
     96  /** 
     97   * Sets the Body of the message.  This can be either an HTML or text body. 
     98   * If HTML then run IsHTML(true). 
     99   * @var string 
     100   */ 
     101  var $Body              = ''; 
     102 
     103  /** 
     104   * Sets the text-only body of the message.  This automatically sets the 
     105   * email to multipart/alternative.  This body can be read by mail 
     106   * clients that do not have HTML email capability such as mutt. Clients 
     107   * that can read HTML will view the normal Body. 
     108   * @var string 
     109   */ 
     110  var $AltBody           = ''; 
     111 
     112  /** 
     113   * Sets word wrapping on the body of the message to a given number of 
     114   * characters. 
     115   * @var int 
     116   */ 
     117  var $WordWrap          = 0; 
     118 
     119  /** 
     120   * Method to send mail: ("mail", "sendmail", or "smtp"). 
     121   * @var string 
     122   */ 
     123  var $Mailer            = 'mail'; 
     124 
     125  /** 
     126   * Sets the path of the sendmail program. 
     127   * @var string 
     128   */ 
     129  var $Sendmail          = '/usr/sbin/sendmail'; 
     130 
     131  /** 
     132   * Path to PHPMailer plugins.  This is now only useful if the SMTP class 
     133   * is in a different directory than the PHP include path. 
     134   * @var string 
     135   */ 
     136  var $PluginDir         = ''; 
     137 
     138  /** 
     139   * Holds PHPMailer version. 
     140   * @var string 
     141   */ 
     142  var $Version           = "2.0.2"; 
     143 
     144  /** 
     145   * Sets the email address that a reading confirmation will be sent. 
     146   * @var string 
     147   */ 
     148  var $ConfirmReadingTo  = ''; 
     149 
     150  /** 
     151   * Sets the hostname to use in Message-Id and Received headers 
     152   * and as default HELO string. If empty, the value returned 
     153   * by SERVER_NAME is used or 'localhost.localdomain'. 
     154   * @var string 
     155   */ 
     156  var $Hostname          = ''; 
     157 
     158  /** 
     159   * Sets the message ID to be used in the Message-Id header. 
     160   * If empty, a unique id will be generated. 
     161   * @var string 
     162   */ 
     163  var $MessageID         = ''; 
     164 
     165  ///////////////////////////////////////////////// 
     166  // PROPERTIES FOR SMTP 
     167  ///////////////////////////////////////////////// 
     168 
     169  /** 
     170   * Sets the SMTP hosts.  All hosts must be separated by a 
     171   * semicolon.  You can also specify a different port 
     172   * for each host by using this format: [hostname:port] 
     173   * (e.g. "smtp1.example.com:25;smtp2.example.com"). 
     174   * Hosts will be tried in order. 
     175   * @var string 
     176   */ 
     177  var $Host        = 'localhost'; 
     178 
     179  /** 
     180   * Sets the default SMTP server port. 
     181   * @var int 
     182   */ 
     183  var $Port        = 25; 
     184 
     185  /** 
     186   * Sets the SMTP HELO of the message (Default is $Hostname). 
     187   * @var string 
     188   */ 
     189  var $Helo        = ''; 
     190 
     191  /** 
     192   * Sets connection prefix. 
     193   * Options are "", "ssl" or "tls" 
     194   * @var string 
     195   */ 
     196  var $SMTPSecure = ""; 
     197 
     198  /** 
     199   * Sets SMTP authentication. Utilizes the Username and Password variables. 
     200   * @var bool 
     201   */ 
     202  var $SMTPAuth     = false; 
     203 
     204  /** 
     205   * Sets SMTP username. 
     206   * @var string 
     207   */ 
     208  var $Username     = ''; 
     209 
     210  /** 
     211   * Sets SMTP password. 
     212   * @var string 
     213   */ 
     214  var $Password     = ''; 
     215 
     216  /** 
     217   * Sets the SMTP server timeout in seconds. This function will not 
     218   * work with the win32 version. 
     219   * @var int 
     220   */ 
     221  var $Timeout      = 10; 
     222 
     223  /** 
     224   * Sets SMTP class debugging on or off. 
     225   * @var bool 
     226   */ 
     227  var $SMTPDebug    = false; 
     228 
     229  /** 
     230   * Prevents the SMTP connection from being closed after each mail 
     231   * sending.  If this is set to true then to close the connection 
     232   * requires an explicit call to SmtpClose(). 
     233   * @var bool 
     234   */ 
     235  var $SMTPKeepAlive = false; 
     236 
     237  /** 
     238   * Provides the ability to have the TO field process individual 
     239   * emails, instead of sending to entire TO addresses 
     240   * @var bool 
     241   */ 
     242  var $SingleTo = false; 
     243 
     244  ///////////////////////////////////////////////// 
     245  // PROPERTIES, PRIVATE 
     246  ///////////////////////////////////////////////// 
     247 
     248  var $smtp            = NULL; 
     249  var $to              = array(); 
     250  var $cc              = array(); 
     251  var $bcc             = array(); 
     252  var $ReplyTo         = array(); 
     253  var $attachment      = array(); 
     254  var $CustomHeader    = array(); 
     255  var $message_type    = ''; 
     256  var $boundary        = array(); 
     257  var $language        = array(); 
     258  var $error_count     = 0; 
     259  var $LE              = "\n"; 
     260  var $sign_key_file   = ""; 
     261  var $sign_key_pass   = ""; 
     262 
     263  ///////////////////////////////////////////////// 
     264  // METHODS, VARIABLES 
     265  ///////////////////////////////////////////////// 
     266 
     267  /** 
     268   * Sets message type to HTML. 
     269   * @param bool $bool 
     270   * @return void 
     271   */ 
     272  function IsHTML($bool) { 
     273    if($bool == true) { 
     274      $this->ContentType = 'text/html'; 
     275    } else { 
     276      $this->ContentType = 'text/plain'; 
     277    } 
     278  } 
     279 
     280  /** 
     281   * Sets Mailer to send message using SMTP. 
     282   * @return void 
     283   */ 
     284  function IsSMTP() { 
     285    $this->Mailer = 'smtp'; 
     286  } 
     287 
     288  /** 
     289   * Sets Mailer to send message using PHP mail() function. 
     290   * @return void 
     291   */ 
     292  function IsMail() { 
     293    $this->Mailer = 'mail'; 
     294  } 
     295 
     296  /** 
     297   * Sets Mailer to send message using the $Sendmail program. 
     298   * @return void 
     299   */ 
     300  function IsSendmail() { 
     301    $this->Mailer = 'sendmail'; 
     302  } 
     303 
     304  /** 
     305   * Sets Mailer to send message using the qmail MTA. 
     306   * @return void 
     307   */ 
     308  function IsQmail() { 
     309    $this->Sendmail = '/var/qmail/bin/sendmail'; 
     310    $this->Mailer = 'sendmail'; 
     311  } 
     312 
     313  ///////////////////////////////////////////////// 
     314  // METHODS, RECIPIENTS 
     315  ///////////////////////////////////////////////// 
     316 
     317  /** 
     318   * Adds a "To" address. 
     319   * @param string $address 
     320   * @param string $name 
     321   * @return void 
     322   */ 
     323  function AddAddress($address, $name = '') { 
     324    $cur = count($this->to); 
     325    $this->to[$cur][0] = trim($address); 
     326    $this->to[$cur][1] = $name; 
     327  } 
     328 
     329  /** 
     330   * Adds a "Cc" address. Note: this function works 
     331   * with the SMTP mailer on win32, not with the "mail" 
     332   * mailer. 
     333   * @param string $address 
     334   * @param string $name 
     335   * @return void 
     336   */ 
     337  function AddCC($address, $name = '') { 
     338    $cur = count($this->cc); 
     339    $this->cc[$cur][0] = trim($address); 
     340    $this->cc[$cur][1] = $name; 
     341  } 
     342 
     343  /** 
     344   * Adds a "Bcc" address. Note: this function works 
     345   * with the SMTP mailer on win32, not with the "mail" 
     346   * mailer. 
     347   * @param string $address 
     348   * @param string $name 
     349   * @return void 
     350   */ 
     351  function AddBCC($address, $name = '') { 
     352    $cur = count($this->bcc); 
     353    $this->bcc[$cur][0] = trim($address); 
     354    $this->bcc[$cur][1] = $name; 
     355  } 
     356 
     357  /** 
     358   * Adds a "Reply-To" address. 
     359   * @param string $address 
     360   * @param string $name 
     361   * @return void 
     362   */ 
     363  function AddReplyTo($address, $name = '') { 
     364    $cur = count($this->ReplyTo); 
     365    $this->ReplyTo[$cur][0] = trim($address); 
     366    $this->ReplyTo[$cur][1] = $name; 
     367  } 
     368 
     369  ///////////////////////////////////////////////// 
     370  // METHODS, MAIL SENDING 
     371  ///////////////////////////////////////////////// 
     372 
     373  /** 
     374   * Creates message and assigns Mailer. If the message is 
     375   * not sent successfully then it returns false.  Use the ErrorInfo 
     376   * variable to view description of the error. 
     377   * @return bool 
     378   */ 
     379  function Send() { 
     380    $header = ''; 
     381    $body = ''; 
     382    $result = true; 
     383 
     384    if((count($this->to) + count($this->cc) + count($this->bcc)) < 1) { 
     385      $this->SetError($this->Lang('provide_address')); 
     386      return false; 
     387    } 
     388 
     389    /* Set whether the message is multipart/alternative */ 
     390    if(!empty($this->AltBody)) { 
     391      $this->ContentType = 'multipart/alternative'; 
     392    } 
     393 
     394    $this->error_count = 0; // reset errors 
     395    $this->SetMessageType(); 
     396    $header .= $this->CreateHeader(); 
     397    $body = $this->CreateBody(); 
     398 
     399    if($body == '') { 
     400      return false; 
     401    } 
     402 
     403    /* Choose the mailer */ 
     404    switch($this->Mailer) { 
     405      case 'sendmail': 
     406        $result = $this->SendmailSend($header, $body); 
     407        break; 
     408      case 'smtp': 
     409        $result = $this->SmtpSend($header, $body); 
     410        break; 
     411      case 'mail': 
     412        $result = $this->MailSend($header, $body); 
     413        break; 
     414      default: 
     415        $result = $this->MailSend($header, $body); 
     416        break; 
     417        //$this->SetError($this->Mailer . $this->Lang('mailer_not_supported')); 
     418        //$result = false; 
     419        //break; 
     420    } 
     421 
     422    return $result; 
     423  } 
     424 
     425  /** 
     426   * Sends mail using the $Sendmail program. 
     427   * @access private 
     428   * @return bool 
     429   */ 
     430  function SendmailSend($header, $body) { 
     431    if ($this->Sender != '') { 
     432      $sendmail = sprintf("%s -oi -f %s -t", escapeshellcmd($this->Sendmail), escapeshellarg($this->Sender)); 
     433    } else { 
     434      $sendmail = sprintf("%s -oi -t", escapeshellcmd($this->Sendmail)); 
     435    } 
     436 
     437    if(!@$mail = popen($sendmail, 'w')) { 
     438      $this->SetError($this->Lang('execute') . $this->Sendmail); 
     439      return false; 
     440    } 
     441 
     442    fputs($mail, $header); 
     443    fputs($mail, $body); 
     444 
     445    $result = pclose($mail); 
     446    if (version_compare(phpversion(), '4.2.3') == -1) { 
     447      $result = $result >> 8 & 0xFF; 
     448    } 
     449    if($result != 0) { 
     450      $this->SetError($this->Lang('execute') . $this->Sendmail); 
     451      return false; 
     452    } 
     453    return true; 
     454  } 
     455 
     456  /** 
     457   * Sends mail using the PHP mail() function. 
     458   * @access private 
     459   * @return bool 
     460   */ 
     461  function MailSend($header, $body) { 
     462 
     463    $to = ''; 
     464    for($i = 0; $i < count($this->to); $i++) { 
     465      if($i != 0) { $to .= ', '; } 
     466      $to .= $this->AddrFormat($this->to[$i]); 
     467    } 
     468 
     469    $toArr = split(',', $to); 
     470 
     471    $params = sprintf("-oi -f %s", $this->Sender); 
     472    if ($this->Sender != '' && strlen(ini_get('safe_mode')) < 1) { 
     473      $old_from = ini_get('sendmail_from'); 
     474      ini_set('sendmail_from', $this->Sender); 
     475      if ($this->SingleTo === true && count($toArr) > 1) { 
     476        foreach ($toArr as $key => $val) { 
     477          $rt = @mail($val, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params); 
    351478        } 
    352  
    353         // Set whether the message is multipart/alternative 
    354         if(!empty($this->AltBody)) 
    355             $this->ContentType = "multipart/alternative"; 
    356  
    357         $this->error_count = 0; // reset errors 
    358         $this->SetMessageType(); 
    359         $header .= $this->CreateHeader(); 
    360         $body = $this->CreateBody(); 
    361  
    362         if($body == "") { return false; } 
    363  
    364         // Choose the mailer 
    365         switch($this->Mailer) 
    366         { 
    367             case "sendmail": 
    368                 $result = $this->SendmailSend($header, $body); 
    369                 break; 
    370             case "mail": 
    371                 $result = $this->MailSend($header, $body); 
    372                 break; 
    373             case "smtp": 
    374                 $result = $this->SmtpSend($header, $body); 
    375                 break; 
    376             default: 
    377             $this->SetError($this->Mailer . $this->Lang("mailer_not_supported")); 
    378                 $result = false; 
    379                 break; 
     479      } else { 
     480        $rt = @mail($to, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params); 
     481      } 
     482    } else { 
     483      if ($this->SingleTo === true && count($toArr) > 1) { 
     484        foreach ($toArr as $key => $val) { 
     485          $rt = @mail($val, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params); 
    380486        } 
    381  
    382         return $result; 
    383     } 
    384  
    385     /** 
    386      * Sends mail using the $Sendmail program. 
    387      * @access private 
    388      * @return bool 
    389      */ 
    390     function SendmailSend($header, $body) { 
    391         if ($this->Sender != "") 
    392             $sendmail = sprintf("%s -oi -f %s -t", $this->Sendmail, escapeshellarg($this->Sender)); 
    393         else 
    394             $sendmail = sprintf("%s -oi -t", $this->Sendmail); 
    395  
    396         if(!@$mail = popen($sendmail, "w")) 
    397         { 
    398             $this->SetError($this->Lang("execute") . $this->Sendmail); 
    399             return false; 
     487      } else { 
     488        $rt = @mail($to, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header); 
     489      } 
     490    } 
     491 
     492    if (isset($old_from)) { 
     493      ini_set('sendmail_from', $old_from); 
     494    } 
     495 
     496    if(!$rt) { 
     497      $this->SetError($this->Lang('instantiate')); 
     498      return false; 
     499    } 
     500 
     501    return true; 
     502  } 
     503 
     504  /** 
     505   * Sends mail via SMTP using PhpSMTP (Author: 
     506   * Chris Ryan).  Returns bool.  Returns false if there is a 
     507   * bad MAIL FROM, RCPT, or DATA input. 
     508   * @access private 
     509   * @return bool 
     510   */ 
     511  function SmtpSend($header, $body) { 
     512    include_once($this->PluginDir . 'class-smtp.php'); 
     513    $error = ''; 
     514    $bad_rcpt = array(); 
     515 
     516    if(!$this->SmtpConnect()) { 
     517      return false; 
     518    } 
     519 
     520    $smtp_from = ($this->Sender == '') ? $this->From : $this->Sender; 
     521    if(!$this->smtp->Mail($smtp_from)) { 
     522      $error = $this->Lang('from_failed') . $smtp_from; 
     523      $this->SetError($error); 
     524      $this->smtp->Reset(); 
     525      return false; 
     526    } 
     527 
     528    /* Attempt to send attach all recipients */ 
     529    for($i = 0; $i < count($this->to); $i++) { 
     530      if(!$this->smtp->Recipient($this->to[$i][0])) { 
     531        $bad_rcpt[] = $this->to[$i][0]; 
     532      } 
     533    } 
     534    for($i = 0; $i < count($this->cc); $i++) { 
     535      if(!$this->smtp->Recipient($this->cc[$i][0])) { 
     536        $bad_rcpt[] = $this->cc[$i][0]; 
     537      } 
     538    } 
     539    for($i = 0; $i < count($this->bcc); $i++) { 
     540      if(!$this->smtp->Recipient($this->bcc[$i][0])) { 
     541        $bad_rcpt[] = $this->bcc[$i][0]; 
     542      } 
     543    } 
     544 
     545    if(count($bad_rcpt) > 0) { // Create error message 
     546      for($i = 0; $i < count($bad_rcpt); $i++) { 
     547        if($i != 0) { 
     548          $error .= ', '; 
    400549        } 
    401  
    402         fputs($mail, $header); 
    403         fputs($mail, $body); 
    404  
    405         $result = pclose($mail) >> 8 & 0xFF; 
    406         if($result != 0) 
    407         { 
    408             $this->SetError($this->Lang("execute") . $this->Sendmail); 
    409             return false; 
     550        $error .= $bad_rcpt[$i]; 
     551      } 
     552      $error = $this->Lang('recipients_failed') . $error; 
     553      $this->SetError($error); 
     554      $this->smtp->Reset(); 
     555      return false; 
     556    } 
     557 
     558    if(!$this->smtp->Data($header . $body)) { 
     559      $this->SetError($this->Lang('data_not_accepted')); 
     560      $this->smtp->Reset(); 
     561      return false; 
     562    } 
     563    if($this->SMTPKeepAlive == true) { 
     564      $this->smtp->Reset(); 
     565    } else { 
     566      $this->SmtpClose(); 
     567    } 
     568 
     569    return true; 
     570  } 
     571 
     572  /** 
     573   * Initiates a connection to an SMTP server.  Returns false if the 
     574   * operation failed. 
     575   * @access private 
     576   * @return bool 
     577   */ 
     578  function SmtpConnect() { 
     579    if($this->smtp == NULL) { 
     580      $this->smtp = new SMTP(); 
     581    } 
     582 
     583    $this->smtp->do_debug = $this->SMTPDebug; 
     584    $hosts = explode(';', $this->Host); 
     585    $index = 0; 
     586    $connection = ($this->smtp->Connected()); 
     587 
     588    /* Retry while there is no connection */ 
     589    while($index < count($hosts) && $connection == false) { 
     590      $hostinfo = array(); 
     591      if(eregi('^(.+):([0-9]+)$', $hosts[$index], $hostinfo)) { 
     592        $host = $hostinfo[1]; 
     593        $port = $hostinfo[2]; 
     594      } else { 
     595        $host = $hosts[$index]; 
     596        $port = $this->Port; 
     597      } 
     598 
     599      if($this->smtp->Connect(((!empty($this->SMTPSecure))?$this->SMTPSecure.'://':'').$host, $port, $this->Timeout)) { 
     600        if ($this->Helo != '') { 
     601          $this->smtp->Hello($this->Helo); 
     602        } else { 
     603          $this->smtp->Hello($this->ServerHostname()); 
    410604        } 
    411605 
    412         return true; 
    413     } 
    414  
    415     /** 
    416      * Sends mail using the PHP mail() function. 
    417      * @access private 
    418      * @return bool 
    419      */ 
    420     function MailSend($header, $body) { 
    421         $to = ""; 
    422         for($i = 0; $i < count($this->to); $i++) 
    423         { 
    424             if($i != 0) { $to .= ", "; } 
    425             $to .= $this->to[$i][0]; 
     606        $connection = true; 
     607        if($this->SMTPAuth) { 
     608          if(!$this->smtp->Authenticate($this->Username, $this->Password)) { 
     609            $this->SetError($this->Lang('authenticate')); 
     610            $this->smtp->Reset(); 
     611            $connection = false; 
     612          } 
    426613        } 
    427  
    428         if ($this->Sender != "" && strlen(ini_get("safe_mode"))< 1) 
    429         { 
    430             $old_from = ini_get("sendmail_from"); 
    431             ini_set("sendmail_from", $this->Sender); 
    432             $params = sprintf("-oi -f %s", $this->Sender); 
    433             $rt = @mail($to, $this->EncodeHeader($this->Subject), $body, 
    434                         $header, $params); 
     614      } 
     615      $index++; 
     616    } 
     617    if(!$connection) { 
     618      $this->SetError($this->Lang('connect_host')); 
     619    } 
     620 
     621    return $connection; 
     622  } 
     623 
     624  /** 
     625   * Closes the active SMTP session if one exists. 
     626   * @return void 
     627   */ 
     628  function SmtpClose() { 
     629    if($this->smtp != NULL) { 
     630      if($this->smtp->Connected()) { 
     631        $this->smtp->Quit(); 
     632        $this->smtp->Close(); 
     633      } 
     634    } 
     635  } 
     636 
     637  /** 
     638   * Sets the language for all class error messages.  Returns false 
     639   * if it cannot load the language file.  The default language type 
     640   * is English. 
     641   * @param string $lang_type Type of language (e.g. Portuguese: "br") 
     642   * @param string $lang_path Path to the language file directory 
     643   * @access public 
     644   * @return bool 
     645   */ 
     646  function SetLanguage($lang_type, $lang_path = 'language/') { 
     647    if(file_exists($lang_path.'phpmailer.lang-'.$lang_type.'.php')) { 
     648      include($lang_path.'phpmailer.lang-'.$lang_type.'.php'); 
     649    } elseif (file_exists($lang_path.'phpmailer.lang-en.php')) { 
     650      include($lang_path.'phpmailer.lang-en.php'); 
     651    } else { 
     652      $this->SetError('Could not load language file'); 
     653      return false; 
     654    } 
     655    $this->language = $PHPMAILER_LANG; 
     656 
     657    return true; 
     658  } 
     659 
     660  ///////////////////////////////////////////////// 
     661  // METHODS, MESSAGE CREATION 
     662  ///////////////////////////////////////////////// 
     663 
     664  /** 
     665   * Creates recipient headers. 
     666   * @access private 
     667   * @return string 
     668   */ 
     669  function AddrAppend($type, $addr) { 
     670    $addr_str = $type . ': '; 
     671    $addr_str .= $this->AddrFormat($addr[0]); 
     672    if(count($addr) > 1) { 
     673      for($i = 1; $i < count($addr); $i++) { 
     674        $addr_str .= ', ' . $this->AddrFormat($addr[$i]); 
     675      } 
     676    } 
     677    $addr_str .= $this->LE; 
     678 
     679    return $addr_str; 
     680  } 
     681 
     682  /** 
     683   * Formats an address correctly. 
     684   * @access private 
     685   * @return string 
     686   */ 
     687  function AddrFormat($addr) { 
     688    if(empty($addr[1])) { 
     689      $formatted = $this->SecureHeader($addr[0]); 
     690    } else { 
     691      $formatted = $this->EncodeHeader($this->SecureHeader($addr[1]), 'phrase') . " <" . $this->SecureHeader($addr[0]) . ">"; 
     692    } 
     693 
     694    return $formatted; 
     695  } 
     696 
     697  /** 
     698   * Wraps message for use with mailers that do not 
     699   * automatically perform wrapping and for quoted-printable. 
     700   * Original written by philippe. 
     701   * @access private 
     702   * @return string 
     703   */ 
     704  function WrapText($message, $length, $qp_mode = false) { 
     705    $soft_break = ($qp_mode) ? sprintf(" =%s", $this->LE) : $this->LE; 
     706    // If utf-8 encoding is used, we will need to make sure we don't 
     707    // split multibyte characters when we wrap 
     708    $is_utf8 = (strtolower($this->CharSet) == "utf-8"); 
     709 
     710    $message = $this->FixEOL($message); 
     711    if (substr($message, -1) == $this->LE) { 
     712      $message = substr($message, 0, -1); 
     713    } 
     714 
     715    $line = explode($this->LE, $message); 
     716    $message = ''; 
     717    for ($i=0 ;$i < count($line); $i++) { 
     718      $line_part = explode(' ', $line[$i]); 
     719      $buf = ''; 
     720      for ($e = 0; $e<count($line_part); $e++) { 
     721        $word = $line_part[$e]; 
     722        if ($qp_mode and (strlen($word) > $length)) { 
     723          $space_left = $length - strlen($buf) - 1; 
     724          if ($e != 0) { 
     725            if ($space_left > 20) { 
     726              $len = $space_left; 
     727              if ($is_utf8) { 
     728                $len = $this->UTF8CharBoundary($word, $len); 
     729              } elseif (substr($word, $len - 1, 1) == "=") { 
     730                $len--; 
     731              } elseif (substr($word, $len - 2, 1) == "=") { 
     732                $len -= 2; 
     733              } 
     734              $part = substr($word, 0, $len); 
     735              $word = substr($word, $len); 
     736              $buf .= ' ' . $part; 
     737              $message .= $buf . sprintf("=%s", $this->LE); 
     738            } else { 
     739              $message .= $buf . $soft_break; 
     740            } 
     741            $buf = ''; 
     742          } 
     743          while (strlen($word) > 0) { 
     744            $len = $length; 
     745            if ($is_utf8) { 
     746              $len = $this->UTF8CharBoundary($word, $len); 
     747            } elseif (substr($word, $len - 1, 1) == "=") { 
     748              $len--; 
     749            } elseif (substr($word, $len - 2, 1) == "=") { 
     750              $len -= 2; 
     751            } 
     752            $part = substr($word, 0, $len); 
     753            $word = substr($word, $len); 
     754 
     755            if (strlen($word) > 0) { 
     756              $message .= $part . sprintf("=%s", $this->LE); 
     757            } else { 
     758              $buf = $part; 
     759            } 
     760          } 
     761        } else { 
     762          $buf_o = $buf; 
     763          $buf .= ($e == 0) ? $word : (' ' . $word); 
     764 
     765          if (strlen($buf) > $length and $buf_o != '') { 
     766            $message .= $buf_o . $soft_break; 
     767            $buf = $word; 
     768          } 
    435769        } 
    436         else 
    437             $rt = @mail($to, $this->EncodeHeader($this->Subject), $body, $header); 
    438  
    439         if (isset($old_from)) 
    440             ini_set("sendmail_from", $old_from); 
    441  
    442         if(!$rt) 
    443         { 
    444             $this->SetError($this->Lang("instantiate")); 
    445             return false; 
     770      } 
     771      $message .= $buf . $this->LE; 
     772    } 
     773 
     774    return $message; 
     775  } 
     776 
     777  /** 
     778   * Finds last character boundary prior to maxLength in a utf-8 
     779   * quoted (printable) encoded string. 
     780   * Original written by Colin Brown. 
     781   * @access private 
     782   * @param string $encodedText utf-8 QP text 
     783   * @param int    $maxLength   find last character boundary prior to this length 
     784   * @return int 
     785   */ 
     786  function UTF8CharBoundary($encodedText, $maxLength) { 
     787    $foundSplitPos = false; 
     788    $lookBack = 3; 
     789    while (!$foundSplitPos) { 
     790      $lastChunk = substr($encodedText, $maxLength - $lookBack, $lookBack); 
     791      $encodedCharPos = strpos($lastChunk, "="); 
     792      if ($encodedCharPos !== false) { 
     793        // Found start of encoded character byte within $lookBack block. 
     794        // Check the encoded byte value (the 2 chars after the '=') 
     795        $hex = substr($encodedText, $maxLength - $lookBack + $encodedCharPos + 1, 2); 
     796        $dec = hexdec($hex); 
     797        if ($dec < 128) { // Single byte character. 
     798          // If the encoded char was found at pos 0, it will fit 
     799          // otherwise reduce maxLength to start of the encoded char 
     800          $maxLength = ($encodedCharPos == 0) ? $maxLength : 
     801          $maxLength - ($lookBack - $encodedCharPos); 
     802          $foundSplitPos = true; 
     803        } elseif ($dec >= 192) { // First byte of a multi byte character 
     804          // Reduce maxLength to split at start of character 
     805          $maxLength = $maxLength - ($lookBack - $encodedCharPos); 
     806          $foundSplitPos = true; 
     807        } elseif ($dec < 192) { // Middle byte of a multi byte character, look further back 
     808          $lookBack += 3; 
    446809        } 
    447  
    448         return true; 
    449     } 
    450  
    451     /** 
    452      * Sends mail via SMTP using PhpSMTP (Author: 
    453      * Chris Ryan).  Returns bool.  Returns false if there is a 
    454      * bad MAIL FROM, RCPT, or DATA input. 
    455      * @access private 
    456      * @return bool 
    457      */ 
    458     function SmtpSend($header, $body) { 
    459         include_once($this->PluginDir . "class-smtp.php"); 
    460         $error = ""; 
    461         $bad_rcpt = array(); 
    462  
    463         if(!$this->SmtpConnect()) 
    464             return false; 
    465  
    466         $smtp_from = ($this->Sender == "") ? $this->From : $this->Sender; 
    467         if(!$this->smtp->Mail($smtp_from)) 
    468         { 
    469             $error = $this->Lang("from_failed") . $smtp_from; 
    470             $this->SetError($error); 
    471             $this->smtp->Reset(); 
    472             return false; 
     810      } else { 
     811        // No encoded character found 
     812        $foundSplitPos = true; 
     813      } 
     814    } 
     815    return $maxLength; 
     816  } 
     817 
     818  /** 
     819   * Set the body wrapping. 
     820   * @access private 
     821   * @return void 
     822   */ 
     823  function SetWordWrap() { 
     824    if($this->WordWrap < 1) { 
     825      return; 
     826    } 
     827 
     828    switch($this->message_type) { 
     829      case 'alt': 
     830        /* fall through */ 
     831      case 'alt_attachments': 
     832        $this->AltBody = $this->WrapText($this->AltBody, $this->WordWrap); 
     833        break; 
     834      default: 
     835        $this->Body = $this->WrapText($this->Body, $this->WordWrap); 
     836        break; 
     837    } 
     838  } 
     839 
     840  /** 
     841   * Assembles message header. 
     842   * @access private 
     843   * @return string 
     844   */ 
     845  function CreateHeader() { 
     846    $result = ''; 
     847 
     848    /* Set the boundaries */ 
     849    $uniq_id = md5(uniqid(time())); 
     850    $this->boundary[1] = 'b1_' . $uniq_id; 
     851    $this->boundary[2] = 'b2_' . $uniq_id; 
     852 
     853    $result .= $this->HeaderLine('Date', $this->RFCDate()); 
     854    if($this->Sender == '') { 
     855      $result .= $this->HeaderLine('Return-Path', trim($this->From)); 
     856    } else { 
     857      $result .= $this->HeaderLine('Return-Path', trim($this->Sender)); 
     858    } 
     859 
     860    /* To be created automatically by mail() */ 
     861    if($this->Mailer != 'mail') { 
     862      if(count($this->to) > 0) { 
     863        $result .= $this->AddrAppend('To', $this->to); 
     864      } elseif (count($this->cc) == 0) { 
     865        $result .= $this->HeaderLine('To', 'undisclosed-recipients:;'); 
     866      } 
     867      if(count($this->cc) > 0) { 
     868        $result .= $this->AddrAppend('Cc', $this->cc); 
     869      } 
     870    } 
     871 
     872    $from = array(); 
     873    $from[0][0] = trim($this->From); 
     874    $from[0][1] = $this->FromName; 
     875    $result .= $this->AddrAppend('From', $from); 
     876 
     877    /* sendmail and mail() extract Cc from the header before sending */ 
     878    if((($this->Mailer == 'sendmail') || ($this->Mailer == 'mail')) && (count($this->cc) > 0)) { 
     879      $result .= $this->AddrAppend('Cc', $this->cc); 
     880    } 
     881 
     882    /* sendmail and mail() extract Bcc from the header before sending */ 
     883    if((($this->Mailer == 'sendmail') || ($this->Mailer == 'mail')) && (count($this->bcc) > 0)) { 
     884      $result .= $this->AddrAppend('Bcc', $this->bcc); 
     885    } 
     886 
     887    if(count($this->ReplyTo) > 0) { 
     888      $result .= $this->AddrAppend('Reply-To', $this->ReplyTo); 
     889    } 
     890 
     891    /* mail() sets the subject itself */ 
     892    if($this->Mailer != 'mail') { 
     893      $result .= $this->HeaderLine('Subject', $this->EncodeHeader($this->SecureHeader($this->Subject))); 
     894    } 
     895 
     896    if($this->MessageID != '') { 
     897      $result .= $this->HeaderLine('Message-ID',$this->MessageID); 
     898    } else { 
     899      $result .= sprintf("Message-ID: <%s@%s>%s", $uniq_id, $this->ServerHostname(), $this->LE); 
     900    } 
     901    $result .= $this->HeaderLine('X-Priority', $this->Priority); 
     902    $result .= $this->HeaderLine('X-Mailer', 'PHPMailer (phpmailer.sourceforge.net) [version ' . $this->Version . ']'); 
     903 
     904    if($this->ConfirmReadingTo != '') { 
     905      $result .= $this->HeaderLine('Disposition-Notification-To', '<' . trim($this->ConfirmReadingTo) . '>'); 
     906    } 
     907 
     908    // Add custom headers 
     909    for($index = 0; $index < count($this->CustomHeader); $index++) { 
     910      $result .= $this->HeaderLine(trim($this->CustomHeader[$index][0]), $this->EncodeHeader(trim($this->CustomHeader[$index][1]))); 
     911    } 
     912    if (!$this->sign_key_file) { 
     913      $result .= $this->HeaderLine('MIME-Version', '1.0'); 
     914      $result .= $this->GetMailMIME(); 
     915    } 
     916 
     917    return $result; 
     918  } 
     919 
     920  /** 
     921   * Returns the message MIME. 
     922   * @access private 
     923   * @return string 
     924   */ 
     925  function GetMailMIME() { 
     926    $result = ''; 
     927    switch($this->message_type) { 
     928      case 'plain': 
     929        $result .= $this->HeaderLine('Content-Transfer-Encoding', $this->Encoding); 
     930        $result .= sprintf("Content-Type: %s; charset=\"%s\"", $this->ContentType, $this->CharSet); 
     931        break; 
     932      case 'attachments': 
     933        /* fall through */ 
     934      case 'alt_attachments': 
     935        if($this->InlineImageExists()){ 
     936          $result .= sprintf("Content-Type: %s;%s\ttype=\"text/html\";%s\tboundary=\"%s\"%s", 'multipart/related', $this->LE, $this->LE, $this->boundary[1], $this->LE); 
     937        } else { 
     938          $result .= $this->HeaderLine('Content-Type', 'multipart/mixed;'); 
     939          $result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . '"'); 
    473940        } 
    474  
    475         // Attempt to send attach all recipients 
    476         for($i = 0; $i < count($this->to); $i++) 
    477         { 
    478             if(!$this->smtp->Recipient($this->to[$i][0])) 
    479                 $bad_rcpt[] = $this->to[$i][0]; 
     941        break; 
     942      case 'alt': 
     943        $result .= $this->HeaderLine('Content-Type', 'multipart/alternative;'); 
     944        $result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . '"'); 
     945        break; 
     946    } 
     947 
     948    if($this->Mailer != 'mail') { 
     949      $result .= $this->LE.$this->LE; 
     950    } 
     951 
     952    return $result; 
     953  } 
     954 
     955  /** 
     956   * Assembles the message body.  Returns an empty string on failure. 
     957   * @access private 
     958   * @return string 
     959   */ 
     960  function CreateBody() { 
     961    $result = ''; 
     962    if ($this->sign_key_file) { 
     963      $result .= $this->GetMailMIME(); 
     964    } 
     965 
     966    $this->SetWordWrap(); 
     967 
     968    switch($this->message_type) { 
     969      case 'alt': 
     970        $result .= $this->GetBoundary($this->boundary[1], '', 'text/plain', ''); 
     971        $result .= $this->EncodeString($this->AltBody, $this->Encoding); 
     972        $result .= $this->LE.$this->LE; 
     973        $result .= $this->GetBoundary($this->boundary[1], '', 'text/html', ''); 
     974        $result .= $this->EncodeString($this->Body, $this->Encoding); 
     975        $result .= $this->LE.$this->LE; 
     976        $result .= $this->EndBoundary($this->boundary[1]); 
     977        break; 
     978      case 'plain': 
     979        $result .= $this->EncodeString($this->Body, $this->Encoding); 
     980        break; 
     981      case 'attachments': 
     982        $result .= $this->GetBoundary($this->boundary[1], '', '', ''); 
     983        $result .= $this->EncodeString($this->Body, $this->Encoding); 
     984        $result .= $this->LE; 
     985        $result .= $this->AttachAll(); 
     986        break; 
     987      case 'alt_attachments': 
     988        $result .= sprintf("--%s%s", $this->boundary[1], $this->LE); 
     989        $result .= sprintf("Content-Type: %s;%s" . "\tboundary=\"%s\"%s", 'multipart/alternative', $this->LE, $this->boundary[2], $this->LE.$this->LE); 
     990        $result .= $this->GetBoundary($this->boundary[2], '', 'text/plain', '') . $this->LE; // Create text body 
     991        $result .= $this->EncodeString($this->AltBody, $this->Encoding); 
     992        $result .= $this->LE.$this->LE; 
     993        $result .= $this->GetBoundary($this->boundary[2], '', 'text/html', '') . $this->LE; // Create the HTML body 
     994        $result .= $this->EncodeString($this->Body, $this->Encoding); 
     995        $result .= $this->LE.$this->LE; 
     996        $result .= $this->EndBoundary($this->boundary[2]); 
     997        $result .= $this->AttachAll(); 
     998        break; 
     999    } 
     1000 
     1001    if($this->IsError()) { 
     1002      $result = ''; 
     1003    } else if ($this->sign_key_file) { 
     1004      $file = tempnam("", "mail"); 
     1005      $fp = fopen($file, "w"); 
     1006      fwrite($fp, $result); 
     1007      fclose($fp); 
     1008      $signed = tempnam("", "signed"); 
     1009 
     1010      if (@openssl_pkcs7_sign($file, $signed, "file://".$this->sign_key_file, array("file://".$this->sign_key_file, $this->sign_key_pass), null)) { 
     1011        $fp = fopen($signed, "r"); 
     1012        $result = fread($fp, filesize($this->sign_key_file)); 
     1013        fclose($fp); 
     1014      } else { 
     1015        $this->SetError($this->Lang("signing").openssl_error_string()); 
     1016        $result = ''; 
     1017      } 
     1018 
     1019      unlink($file); 
     1020      unlink($signed); 
     1021    } 
     1022 
     1023    return $result; 
     1024  } 
     1025 
     1026  /** 
     1027   * Returns the start of a message boundary. 
     1028   * @access private 
     1029   */ 
     1030  function GetBoundary($boundary, $charSet, $contentType, $encoding) { 
     1031    $result = ''; 
     1032    if($charSet == '') { 
     1033      $charSet = $this->CharSet; 
     1034    } 
     1035    if($contentType == '') { 
     1036      $contentType = $this->ContentType; 
     1037    } 
     1038    if($encoding == '') { 
     1039      $encoding = $this->Encoding; 
     1040    } 
     1041    $result .= $this->TextLine('--' . $boundary); 
     1042    $result .= sprintf("Content-Type: %s; charset = \"%s\"", $contentType, $charSet); 
     1043    $result .= $this->LE; 
     1044    $result .= $this->HeaderLine('Content-Transfer-Encoding', $encoding); 
     1045    $result .= $this->LE; 
     1046 
     1047    return $result; 
     1048  } 
     1049 
     1050  /** 
     1051   * Returns the end of a message boundary. 
     1052   * @access private 
     1053   */ 
     1054  function EndBoundary($boundary) { 
     1055    return $this->LE . '--' . $boundary . '--' . $this->LE; 
     1056  } 
     1057 
     1058  /** 
     1059   * Sets the message type. 
     1060   * @access private 
     1061   * @return void 
     1062   */ 
     1063  function SetMessageType() { 
     1064    if(count($this->attachment) < 1 && strlen($this->AltBody) < 1) { 
     1065      $this->message_type = 'plain'; 
     1066    } else { 
     1067      if(count($this->attachment) > 0) { 
     1068        $this->message_type = 'attachments'; 
     1069      } 
     1070      if(strlen($this->AltBody) > 0 && count($this->attachment) < 1) { 
     1071        $this->message_type = 'alt'; 
     1072      } 
     1073      if(strlen($this->AltBody) > 0 && count($this->attachment) > 0) { 
     1074        $this->message_type = 'alt_attachments'; 
     1075      } 
     1076    } 
     1077  } 
     1078 
     1079  /* Returns a formatted header line. 
     1080   * @access private 
     1081   * @return string 
     1082   */ 
     1083  function HeaderLine($name, $value) { 
     1084    return $name . ': ' . $value . $this->LE; 
     1085  } 
     1086 
     1087  /** 
     1088   * Returns a formatted mail line. 
     1089   * @access private 
     1090   * @return string 
     1091   */ 
     1092  function TextLine($value) { 
     1093    return $value . $this->LE; 
     1094  } 
     1095 
     1096  ///////////////////////////////////////////////// 
     1097  // CLASS METHODS, ATTACHMENTS 
     1098  ///////////////////////////////////////////////// 
     1099 
     1100  /** 
     1101   * Adds an attachment from a path on the filesystem. 
     1102   * Returns false if the file could not be found 
     1103   * or accessed. 
     1104   * @param string $path Path to the attachment. 
     1105   * @param string $name Overrides the attachment name. 
     1106   * @param string $encoding File encoding (see $Encoding). 
     1107   * @param string $type File extension (MIME) type. 
     1108   * @return bool 
     1109   */ 
     1110  function AddAttachment($path, $name = '', $encoding = 'base64', $type = 'application/octet-stream') { 
     1111    if(!@is_file($path)) { 
     1112      $this->SetError($this->Lang('file_access') . $path); 
     1113      return false; 
     1114    } 
     1115 
     1116    $filename = basename($path); 
     1117    if($name == '') { 
     1118      $name = $filename; 
     1119    } 
     1120 
     1121    $cur = count($this->attachment); 
     1122    $this->attachment[$cur][0] = $path; 
     1123    $this->attachment[$cur][1] = $filename; 
     1124    $this->attachment[$cur][2] = $name; 
     1125    $this->attachment[$cur][3] = $encoding; 
     1126    $this->attachment[$cur][4] = $type; 
     1127    $this->attachment[$cur][5] = false; // isStringAttachment 
     1128    $this->attachment[$cur][6] = 'attachment'; 
     1129    $this->attachment[$cur][7] = 0; 
     1130 
     1131    return true; 
     1132  } 
     1133 
     1134  /** 
     1135   * Attaches all fs, string, and binary attachments to the message. 
     1136   * Returns an empty string on failure. 
     1137   * @access private 
     1138   * @return string 
     1139   */ 
     1140  function AttachAll() { 
     1141    /* Return text of body */ 
     1142    $mime = array(); 
     1143 
     1144    /* Add all attachments */ 
     1145    for($i = 0; $i < count($this->attachment); $i++) { 
     1146      /* Check for string attachment */ 
     1147      $bString = $this->attachment[$i][5]; 
     1148      if ($bString) { 
     1149        $string = $this->attachment[$i][0]; 
     1150      } else { 
     1151        $path = $this->attachment[$i][0]; 
     1152      } 
     1153 
     1154      $filename    = $this->attachment[$i][1]; 
     1155      $name        = $this->attachment[$i][2]; 
     1156      $encoding    = $this->attachment[$i][3]; 
     1157      $type        = $this->attachment[$i][4]; 
     1158      $disposition = $this->attachment[$i][6]; 
     1159      $cid         = $this->attachment[$i][7]; 
     1160 
     1161      $mime[] = sprintf("--%s%s", $this->boundary[1], $this->LE); 
     1162      $mime[] = sprintf("Content-Type: %s; name=\"%s\"%s", $type, $name, $this->LE); 
     1163      $mime[] = sprintf("Content-Transfer-Encoding: %s%s", $encoding, $this->LE); 
     1164 
     1165      if($disposition == 'inline') { 
     1166        $mime[] = sprintf("Content-ID: <%s>%s", $cid, $this->LE); 
     1167      } 
     1168 
     1169      $mime[] = sprintf("Content-Disposition: %s; filename=\"%s\"%s", $disposition, $name, $this->LE.$this->LE); 
     1170 
     1171      /* Encode as string attachment */ 
     1172      if($bString) { 
     1173        $mime[] = $this->EncodeString($string, $encoding); 
     1174        if($this->IsError()) { 
     1175          return ''; 
    4801176        } 
    481         for($i = 0; $i < count($this->cc); $i++) 
    482         { 
    483             if(!$this->smtp->Recipient($this->cc[$i][0])) 
    484                 $bad_rcpt[] = $this->cc[$i][0]; 
     1177        $mime[] = $this->LE.$this->LE; 
     1178      } else { 
     1179        $mime[] = $this->EncodeFile($path, $encoding); 
     1180        if($this->IsError()) { 
     1181          return ''; 
    4851182        } 
    486         for($i = 0; $i < count($this->bcc); $i++) 
    487         { 
    488             if(!$this->smtp->Recipient($this->bcc[$i][0])) 
    489                 $bad_rcpt[] = $this->bcc[$i][0]; 
     1183        $mime[] = $this->LE.$this->LE; 
     1184      } 
     1185    } 
     1186 
     1187    $mime[] = sprintf("--%s--%s", $this->boundary[1], $this->LE); 
     1188 
     1189    return join('', $mime); 
     1190  } 
     1191 
     1192  /** 
     1193   * Encodes attachment in requested format.  Returns an 
     1194   * empty string on failure. 
     1195   * @access private 
     1196   * @return string 
     1197   */ 
     1198  function EncodeFile ($path, $encoding = 'base64') { 
     1199    if(!@$fd = fopen($path, 'rb')) { 
     1200      $this->SetError($this->Lang('file_open') . $path); 
     1201      return ''; 
     1202    } 
     1203    $magic_quotes = get_magic_quotes_runtime(); 
     1204    set_magic_quotes_runtime(0); 
     1205    $file_buffer = fread($fd, filesize($path)); 
     1206    $file_buffer = $this->EncodeString($file_buffer, $encoding); 
     1207    fclose($fd); 
     1208    set_magic_quotes_runtime($magic_quotes); 
     1209 
     1210    return $file_buffer; 
     1211  } 
     1212 
     1213  /** 
     1214   * Encodes string to requested format. Returns an 
     1215   * empty string on failure. 
     1216   * @access private 
     1217   * @return string 
     1218   */ 
     1219  function EncodeString ($str, $encoding = 'base64') { 
     1220    $encoded = ''; 
     1221    switch(strtolower($encoding)) { 
     1222      case 'base64': 
     1223        /* chunk_split is found in PHP >= 3.0.6 */ 
     1224        $encoded = chunk_split(base64_encode($str), 76, $this->LE); 
     1225        break; 
     1226      case '7bit': 
     1227      case '8bit': 
     1228        $encoded = $this->FixEOL($str); 
     1229        if (substr($encoded, -(strlen($this->LE))) != $this->LE) 
     1230          $encoded .= $this->LE; 
     1231        break; 
     1232      case 'binary': 
     1233        $encoded = $str; 
     1234        break; 
     1235      case 'quoted-printable': 
     1236        $encoded = $this->EncodeQP($str); 
     1237        break; 
     1238      default: 
     1239        $this->SetError($this->Lang('encoding') . $encoding); 
     1240        break; 
     1241    } 
     1242    return $encoded; 
     1243  } 
     1244 
     1245  /** 
     1246   * Encode a header string to best of Q, B, quoted or none. 
     1247   * @access private 
     1248   * @return string 
     1249   */ 
     1250  function EncodeHeader ($str, $position = 'text') { 
     1251    $x = 0; 
     1252 
     1253    switch (strtolower($position)) { 
     1254      case 'phrase': 
     1255        if (!preg_match('/[\200-\377]/', $str)) { 
     1256          /* Can't use addslashes as we don't know what value has magic_quotes_sybase. */ 
     1257          $encoded = addcslashes($str, "\0..\37\177\\\""); 
     1258          if (($str == $encoded) && !preg_match('/[^A-Za-z0-9!#$%&\'*+\/=?^_`{|}~ -]/', $str)) { 
     1259            return ($encoded); 
     1260          } else { 
     1261            return ("\"$encoded\""); 
     1262          } 
    4901263        } 
    491  
    492         if(count($bad_rcpt) > 0) // Create error message 
    493         { 
    494             for($i = 0; $i < count($bad_rcpt); $i++) 
    495             { 
    496                 if($i != 0) { $error .= ", "; } 
    497                 $error .= $bad_rcpt[$i]; 
    498             } 
    499             $error = $this->Lang("recipients_failed") . $error; 
    500             $this->SetError($error); 
    501             $this->smtp->Reset(); 
    502             return false; 
    503         } 
    504  
    505         if(!$this->smtp->Data($header . $body)) 
    506         { 
    507             $this->SetError($this->Lang("data_not_accepted")); 
    508             $this->smtp->Reset(); 
    509             return false; 
    510         } 
    511         if($this->SMTPKeepAlive == true) 
    512             $this->smtp->Reset(); 
    513         else 
    514             $this->SmtpClose(); 
    515  
    516         return true; 
    517     } 
    518  
    519     /** 
    520      * Initiates a connection to an SMTP server.  Returns false if the 
    521      * operation failed. 
    522      * @access private 
    523      * @return bool 
    524      */ 
    525     function SmtpConnect() { 
    526         if($this->smtp == NULL) { $this->smtp = new SMTP(); } 
    527  
    528         $this->smtp->do_debug = $this->SMTPDebug; 
    529         $hosts = explode(";", $this->Host); 
    530         $index = 0; 
    531         $connection = ($this->smtp->Connected()); 
    532  
    533         // Retry while there is no connection 
    534         while($index < count($hosts) && $connection == false) 
    535         { 
    536             if(strstr($hosts[$index], ":")) 
    537                 list($host, $port) = explode(":", $hosts[$index]); 
    538             else 
    539             { 
    540                 $host = $hosts[$index]; 
    541                 $port = $this->Port; 
    542             } 
    543  
    544             if($this->smtp->Connect($host, $port, $this->Timeout)) 
    545             { 
    546                 if ($this->Helo != '') 
    547                     $this->smtp->Hello($this->Helo); 
    548                 else 
    549                     $this->smtp->Hello($this->ServerHostname()); 
    550  
    551                 if($this->SMTPAuth) 
    552                 { 
    553                     if(!$this->smtp->Authenticate($this->Username, 
    554                                                   $this->Password)) 
    555                     { 
    556                         $this->SetError($this->Lang("authenticate")); 
    557                         $this->smtp->Reset(); 
    558                         $connection = false; 
    559                     } 
    560                 } 
    561                 $connection = true; 
    562             } 
    563             $index++; 
    564         } 
    565         if(!$connection) 
    566             $this->SetError($this->Lang("connect_host")); 
    567  
    568         return $connection; 
    569     } 
    570  
    571     /** 
    572      * Closes the active SMTP session if one exists. 
    573      * @return void 
    574      */ 
    575     function SmtpClose() { 
    576         if($this->smtp != NULL) 
    577         { 
    578             if($this->smtp->Connected()) 
    579             { 
    580                 $this->smtp->Quit(); 
    581                 $this->smtp->Close(); 
    582             } 
    583         } 
    584     } 
    585  
    586     /** 
    587      * Sets the language for all class error messages.  Returns false 
    588      * if it cannot load the language file.  The default language type 
    589      * is English. 
    590      * @param string $lang_type Type of language (e.g. Portuguese: "br") 
    591      * @param string $lang_path Path to the language file directory 
    592      * @access public 
    593      * @return bool 
    594      */ 
    595     function SetLanguage($lang_type, $lang_path = "language/") { 
    596         if(file_exists($lang_path.'phpmailer.lang-'.$lang_type.'.php')) 
    597             include($lang_path.'phpmailer.lang-'.$lang_type.'.php'); 
    598         else if(file_exists($lang_path.'phpmailer.lang-en.php')) 
    599             include($lang_path.'phpmailer.lang-en.php'); 
    600         else 
    601         { 
    602             $this->SetError("Could not load language file"); 
    603             return false; 
    604         } 
    605         $this->language = $PHPMAILER_LANG; 
    606  
    607         return true; 
    608     } 
    609  
    610     ///////////////////////////////////////////////// 
    611     // MESSAGE CREATION METHODS 
    612     ///////////////////////////////////////////////// 
    613  
    614     /** 
    615      * Creates recipient headers. 
    616      * @access private 
    617      * @return string 
    618      */ 
    619     function AddrAppend($type, $addr) { 
    620         $addr_str = $type . ": "; 
    621         $addr_str .= $this->AddrFormat($addr[0]); 
    622         if(count($addr) > 1) 
    623         { 
    624             for($i = 1; $i < count($addr); $i++) 
    625                 $addr_str .= ", " . $this->AddrFormat($addr[$i]); 
    626         } 
    627         $addr_str .= $this->LE; 
    628  
    629         return $addr_str; 
    630     } 
    631  
    632     /** 
    633      * Formats an address correctly. 
    634      * @access private 
    635      * @return string 
    636      */ 
    637     function AddrFormat($addr) { 
    638         if(empty($addr[1])) 
    639             $formatted = $addr[0]; 
    640         else 
    641         { 
    642             $formatted = $this->EncodeHeader($addr[1], 'phrase') . " <" . 
    643                          $addr[0] . ">"; 
    644         } 
    645  
    646         return $formatted; 
    647     } 
    648  
    649     /** 
    650      * Wraps message for use with mailers that do not 
    651      * automatically perform wrapping and for quoted-printable. 
    652      * Original written by philippe. 
    653      * @access private 
    654      * @return string 
    655      */ 
    656     function WrapText($message, $length, $qp_mode = false) { 
    657         $soft_break = ($qp_mode) ? sprintf(" =%s", $this->LE) : $this->LE; 
    658  
    659         $message = $this->FixEOL($message); 
    660         if (substr($message, -1) == $this->LE) 
    661             $message = substr($message, 0, -1); 
    662  
    663         $line = explode($this->LE, $message); 
    664         $message = ""; 
    665         for ($i=0 ;$i < count($line); $i++) 
    666         { 
    667           $line_part = explode(" ", $line[$i]); 
    668           $buf = ""; 
    669           for ($e = 0; $e<count($line_part); $e++) 
    670           { 
    671               $word = $line_part[$e]; 
    672               if ($qp_mode and (strlen($word) > $length)) 
    673               { 
    674                 $space_left = $length - strlen($buf) - 1; 
    675                 if ($e != 0) 
    676                 { 
    677                     if ($space_left > 20) 
    678                     { 
    679                         $len = $space_left; 
    680                         if (substr($word, $len - 1, 1) == "=") 
    681                           $len--; 
    682                         elseif (substr($word, $len - 2, 1) == "=") 
    683                           $len -= 2; 
    684                         $part = substr($word, 0, $len); 
    685                         $word = substr($word, $len); 
    686                         $buf .= " " . $part; 
    687                         $message .= $buf . sprintf("=%s", $this->LE); 
    688                     } 
    689                     else 
    690                     { 
    691                         $message .= $buf . $soft_break; 
    692                     } 
    693                     $buf = ""; 
    694                 } 
    695                 while (strlen($word) > 0) 
    696                 { 
    697                     $len = $length; 
    698                     if (substr($word, $len - 1, 1) == "=") 
    699                         $len--; 
    700                     elseif (substr($word, $len - 2, 1) == "=") 
    701                         $len -= 2; 
    702                     $part = substr($word, 0, $len); 
    703                     $word = substr($word, $len); 
    704  
    705                     if (strlen($word) > 0) 
    706                         $message .= $part . sprintf("=%s", $this->LE); 
    707                     else 
    708                         $buf = $part; 
    709                 } 
    710               } 
    711               else 
    712               { 
    713                 $buf_o = $buf; 
    714                 $buf .= ($e == 0) ? $word : (" " . $word); 
    715  
    716                 if (strlen($buf) > $length and $buf_o != "") 
    717                 { 
    718                     $message .= $buf_o . $soft_break; 
    719                     $buf = $word; 
    720                 } 
    721               } 
    722           } 
    723           $message .= $buf . $this->LE; 
    724         } 
    725  
    726         return $message; 
    727     } 
    728  
    729     /** 
    730      * Set the body wrapping. 
    731      * @access private 
    732      * @return void 
    733      */ 
    734     function SetWordWrap() { 
    735         if($this->WordWrap < 1) 
    736             return; 
    737  
    738         switch($this->message_type) 
    739         { 
    740            case "alt": 
    741               // fall through 
    742            case "alt_attachments": 
    743               $this->AltBody = $this->WrapText($this->AltBody, $this->WordWrap); 
    744               break; 
    745            default: 
    746               $this->Body = $this->WrapText($this->Body, $this->WordWrap); 
    747               break; 
    748         } 
    749     } 
    750  
    751     /** 
    752      * Assembles message header. 
    753      * @access private 
    754      * @return string 
    755      */ 
    756     function CreateHeader() { 
    757         $result = ""; 
    758  
    759         // Set the boundaries 
    760         $uniq_id = md5(uniqid(time())); 
    761         $this->boundary[1] = "b1_" . $uniq_id; 
    762         $this->boundary[2] = "b2_" . $uniq_id; 
    763  
    764         $result .= $this->HeaderLine("Date", $this->RFCDate()); 
    765         if($this->Sender == "") 
    766             $result .= $this->HeaderLine("Return-Path", trim($this->From)); 
    767         else 
    768             $result .= $this->HeaderLine("Return-Path", trim($this->Sender)); 
    769  
    770         // To be created automatically by mail() 
    771         if($this->Mailer != "mail") 
    772         { 
    773             if(count($this->to) > 0) 
    774                 $result .= $this->AddrAppend("To", $this->to); 
    775             else if (count($this->cc) == 0) 
    776                 $result .= $this->HeaderLine("To", "undisclosed-recipients:;"); 
    777             if(count($this->cc) > 0) 
    778                 $result .= $this->AddrAppend("Cc", $this->cc); 
    779         } 
    780  
    781         $from = array(); 
    782         $from[0][0] = trim($this->From); 
    783         $from[0][1] = $this->FromName; 
    784         $result .= $this->AddrAppend("From", $from); 
    785  
    786         // sendmail and mail() extract Bcc from the header before sending 
    787         if((($this->Mailer == "sendmail") || ($this->Mailer == "mail")) && (count($this->bcc) > 0)) 
    788             $result .= $this->AddrAppend("Bcc", $this->bcc); 
    789  
    790         if(count($this->ReplyTo) > 0) 
    791             $result .= $this->AddrAppend("Reply-to", $this->ReplyTo); 
    792  
    793         // mail() sets the subject itself 
    794         if($this->Mailer != "mail") 
    795             $result .= $this->HeaderLine("Subject", $this->EncodeHeader(trim($this->Subject))); 
    796  
    797         $result .= sprintf("Message-ID: <%s@%s>%s", $uniq_id, $this->ServerHostname(), $this->LE); 
    798         $result .= $this->HeaderLine("X-Priority", $this->Priority); 
    799  
    800         if($this->ConfirmReadingTo != "") 
    801         { 
    802             $result .= $this->HeaderLine("Disposition-Notification-To", 
    803                        "<" . trim($this->ConfirmReadingTo) . ">"); 
    804         } 
    805  
    806         // Add custom headers 
    807         for($index = 0; $index < count($this->CustomHeader); $index++) 
    808         { 
    809             $result .= $this->HeaderLine(trim($this->CustomHeader[$index][0]), 
    810                        $this->EncodeHeader(trim($this->CustomHeader[$index][1]))); 
    811         } 
    812         $result .= $this->HeaderLine("MIME-Version", "1.0"); 
    813  
    814         switch($this->message_type) 
    815         { 
    816             case "plain": 
    817                 $result .= $this->HeaderLine("Content-Transfer-Encoding", $this->Encoding); 
    818                 $result .= sprintf("Content-Type: %s; charset=\"%s\"", 
    819                                     $this->ContentType, $this->CharSet); 
    820                 break; 
    821             case "attachments": 
    822                 // fall through 
    823             case "alt_attachments": 
    824                 if($this->InlineImageExists()) 
    825                 { 
    826                     $result .= sprintf("Content-Type: %s;%s\ttype=\"text/html\";%s\tboundary=\"%s\"%s", 
    827                                     "multipart/related", $this->LE, $this->LE, 
    828                                     $this->boundary[1], $this->LE); 
    829                 } 
    830                 else 
    831                 { 
    832                     $result .= $this->HeaderLine("Content-Type", "multipart/mixed;"); 
    833                     $result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . '"'); 
    834                 } 
    835                 break; 
    836             case "alt": 
    837                 $result .= $this->HeaderLine("Content-Type", "multipart/alternative;"); 
    838                 $result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . '"'); 
    839                 break; 
    840         } 
    841  
    842         if($this->Mailer != "mail") 
    843             $result .= $this->LE.$this->LE; 
    844  
    845         return $result; 
    846     } 
    847  
    848     /** 
    849      * Assembles the message body.  Returns an empty string on failure. 
    850      * @access private 
    851      * @return string 
    852      */ 
    853     function CreateBody() { 
    854         $result = ""; 
    855  
    856         $this->SetWordWrap(); 
    857  
    858         switch($this->message_type) 
    859         { 
    860             case "alt": 
    861                 $result .= $this->GetBoundary($this->boundary[1], "", 
    862                                               "text/plain", ""); 
    863                 $result .= $this->EncodeString($this->AltBody, $this->Encoding); 
    864                 $result .= $this->LE.$this->LE; 
    865                 $result .= $this->GetBoundary($this->boundary[1], "", 
    866                                               "text/html", ""); 
    867  
    868                 $result .= $this->EncodeString($this->Body, $this->Encoding); 
    869                 $result .= $this->LE.$this->LE; 
    870  
    871                 $result .= $this->EndBoundary($this->boundary[1]); 
    872                 break; 
    873             case "plain": 
    874                 $result .= $this->EncodeString($this->Body, $this->Encoding); 
    875                 break; 
    876             case "attachments": 
    877                 $result .= $this->GetBoundary($this->boundary[1], "", "", ""); 
    878                 $result .= $this->EncodeString($this->Body, $this->Encoding); 
    879                 $result .= $this->LE; 
    880  
    881                 $result .= $this->AttachAll(); 
    882                 break; 
    883             case "alt_attachments": 
    884                 $result .= sprintf("--%s%s", $this->boundary[1], $this->LE); 
    885                 $result .= sprintf("Content-Type: %s;%s" . 
    886                                    "\tboundary=\"%s\"%s", 
    887                                    "multipart/alternative", $this->LE, 
    888                                    $this->boundary[2], $this->LE.$this->LE); 
    889  
    890                 // Create text body 
    891                 $result .= $this->GetBoundary($this->boundary[2], "", 
    892                                               "text/plain", "") . $this->LE; 
    893  
    894                 $result .= $this->EncodeString($this->AltBody, $this->Encoding); 
    895                 $result .= $this->LE.$this->LE; 
    896  
    897                 // Create the HTML body 
    898                 $result .= $this->GetBoundary($this->boundary[2], "", 
    899                                               "text/html", "") . $this->LE; 
    900  
    901                 $result .= $this->EncodeString($this->Body, $this->Encoding); 
    902                 $result .= $this->LE.$this->LE; 
    903  
    904                 $result .= $this->EndBoundary($this->boundary[2]); 
    905  
    906                 $result .= $this->AttachAll(); 
    907                 break; 
    908         } 
    909         if($this->IsError()) 
    910             $result = ""; 
    911  
    912         return $result; 
    913     } 
    914  
    915     /** 
    916      * Returns the start of a message boundary. 
    917      * @access private 
    918      */ 
    919     function GetBoundary($boundary, $charSet, $contentType, $encoding) { 
    920         $result = ""; 
    921         if($charSet == "") { $charSet = $this->CharSet; } 
    922         if($contentType == "") { $contentType = $this->ContentType; } 
    923         if($encoding == "") { $encoding = $this->Encoding; } 
    924  
    925         $result .= $this->TextLine("--" . $boundary); 
    926         $result .= sprintf("Content-Type: %s; charset = \"%s\"", 
    927                             $contentType, $charSet); 
    928         $result .= $this->LE; 
    929         $result .= $this->HeaderLine("Content-Transfer-Encoding", $encoding); 
    930         $result .= $this->LE; 
    931  
    932         return $result; 
    933     } 
    934  
    935     /** 
    936      * Returns the end of a message boundary. 
    937      * @access private 
    938      */ 
    939     function EndBoundary($boundary) { 
    940         return $this->LE . "--" . $boundary . "--" . $this->LE; 
    941     } 
    942  
    943     /** 
    944      * Sets the message type. 
    945      * @access private 
    946      * @return void 
    947      */ 
    948     function SetMessageType() { 
    949         if(count($this->attachment) < 1 && strlen($this->AltBody) < 1) 
    950             $this->message_type = "plain"; 
    951         else 
    952         { 
    953             if(count($this->attachment) > 0) 
    954                 $this->message_type = "attachments"; 
    955             if(strlen($this->AltBody) > 0 && count($this->attachment) < 1) 
    956                 $this->message_type = "alt"; 
    957             if(strlen($this->AltBody) > 0 && count($this->attachment) > 0) 
    958                 $this->message_type = "alt_attachments"; 
    959         } 
    960     } 
    961  
    962     /** 
    963      * Returns a formatted header line. 
    964      * @access private 
    965      * @return string 
    966      */ 
    967     function HeaderLine($name, $value) { 
    968         return $name . ": " . $value . $this->LE; 
    969     } 
    970  
    971     /** 
    972      * Returns a formatted mail line. 
    973      * @access private 
    974      * @return string 
    975      */ 
    976     function TextLine($value) { 
    977         return $value . $this->LE; 
    978     } 
    979  
    980     ///////////////////////////////////////////////// 
    981     // ATTACHMENT METHODS 
    982     ///////////////////////////////////////////////// 
    983  
    984     /** 
    985      * Adds an attachment from a path on the filesystem. 
    986      * Returns false if the file could not be found 
    987      * or accessed. 
    988      * @param string $path Path to the attachment. 
    989      * @param string $name Overrides the attachment name. 
    990      * @param string $encoding File encoding (see $Encoding). 
    991      * @param string $type File extension (MIME) type. 
    992      * @return bool 
    993      */ 
    994     function AddAttachment($path, $name = "", $encoding = "base64", 
    995                            $type = "application/octet-stream") { 
    996         if(!@is_file($path)) 
    997         { 
    998             $this->SetError($this->Lang("file_access") . $path); 
    999             return false; 
    1000         } 
    1001  
    1002         $filename = basename($path); 
    1003         if($name == "") 
    1004             $name = $filename; 
    1005  
    1006         $cur = count($this->attachment); 
    1007         $this->attachment[$cur][0] = $path; 
    1008         $this->attachment[$cur][1] = $filename; 
    1009         $this->attachment[$cur][2] = $name; 
    1010         $this->attachment[$cur][3] = $encoding; 
    1011         $this->attachment[$cur][4] = $type; 
    1012         $this->attachment[$cur][5] = false; // isStringAttachment 
    1013         $this->attachment[$cur][6] = "attachment"; 
    1014         $this->attachment[$cur][7] = 0; 
    1015  
    1016         return true; 
    1017     } 
    1018  
    1019     /** 
    1020      * Attaches all fs, string, and binary attachments to the message. 
    1021      * Returns an empty string on failure. 
    1022      * @access private 
    1023      * @return string 
    1024      */ 
    1025     function AttachAll() { 
    1026         // Return text of body 
    1027         $mime = array(); 
    1028  
    1029         // Add all attachments 
    1030         for($i = 0; $i < count($this->attachment); $i++) 
    1031         { 
    1032             // Check for string attachment 
    1033             $bString = $this->attachment[$i][5]; 
    1034             if ($bString) 
    1035                 $string = $this->attachment[$i][0]; 
    1036             else 
    1037                 $path = $this->attachment[$i][0]; 
    1038  
    1039             $filename    = $this->attachment[$i][1]; 
    1040             $name        = $this->attachment[$i][2]; 
    1041             $encoding    = $this->attachment[$i][3]; 
    1042             $type        = $this->attachment[$i][4]; 
    1043             $disposition = $this->attachment[$i][6]; 
    1044             $cid         = $this->attachment[$i][7]; 
    1045  
    1046             $mime[] = sprintf("--%s%s", $this->boundary[1], $this->LE); 
    1047             $mime[] = sprintf("Content-Type: %s; name=\"%s\"%s", $type, $name, $this->LE); 
    1048             $mime[] = sprintf("Content-Transfer-Encoding: %s%s", $encoding, $this->LE); 
    1049  
    1050             if($disposition == "inline") 
    1051                 $mime[] = sprintf("Content-ID: <%s>%s", $cid, $this->LE); 
    1052  
    1053             $mime[] = sprintf("Content-Disposition: %s; filename=\"%s\"%s", 
    1054                               $disposition, $name, $this->LE.$this->LE); 
    1055  
    1056             // Encode as string attachment 
    1057             if($bString) 
    1058             { 
    1059                 $mime[] = $this->EncodeString($string, $encoding); 
    1060                 if($this->IsError()) { return ""; } 
    1061                 $mime[] = $this->LE.$this->LE; 
    1062             } 
    1063             else 
    1064             { 
    1065                 $mime[] = $this->EncodeFile($path, $encoding); 
    1066                 if($this->IsError()) { return ""; } 
    1067                 $mime[] = $this->LE.$this->LE; 
    1068             } 
    1069         } 
    1070  
    1071         $mime[] = sprintf("--%s--%s", $this->boundary[1], $this->LE); 
    1072  
    1073         return join("", $mime); 
    1074     } 
    1075  
    1076     /** 
    1077      * Encodes attachment in requested format.  Returns an 
    1078      * empty string on failure. 
    1079      * @access private 
    1080      * @return string 
    1081      */ 
    1082     function EncodeFile ($path, $encoding = "base64") { 
    1083         if(!@$fd = fopen($path, "rb")) 
    1084         { 
    1085             $this->SetError($this->Lang("file_open") . $path); 
    1086             return ""; 
    1087         } 
    1088         $magic_quotes = get_magic_quotes_runtime(); 
    1089         set_magic_quotes_runtime(0); 
    1090         $file_buffer = fread($fd, filesize($path)); 
    1091         $file_buffer = $this->EncodeString($file_buffer, $encoding); 
    1092         fclose($fd); 
    1093         set_magic_quotes_runtime($magic_quotes); 
    1094  
    1095         return $file_buffer; 
    1096     } 
    1097  
    1098     /** 
    1099      * Encodes string to requested format. Returns an 
    1100      * empty string on failure. 
    1101      * @access private 
    1102      * @return string 
    1103      */ 
    1104     function EncodeString ($str, $encoding = "base64") { 
    1105         $encoded = ""; 
    1106         switch(strtolower($encoding)) { 
    1107           case "base64": 
    1108               // chunk_split is found in PHP >= 3.0.6 
    1109               $encoded = chunk_split(base64_encode($str), 76, $this->LE); 
    1110               break; 
    1111           case "7bit": 
    1112           case "8bit": 
    1113               $encoded = $this->FixEOL($str); 
    1114               if (substr($encoded, -(strlen($this->LE))) != $this->LE) 
    1115                 $encoded .= $this->LE; 
    1116               break; 
    1117           case "binary": 
    1118               $encoded = $str; 
    1119               break; 
    1120           case "quoted-printable": 
    1121               $encoded = $this->EncodeQP($str); 
    1122               break; 
    1123           default: 
    1124               $this->SetError($this->Lang("encoding") . $encoding); 
    1125               break; 
    1126         } 
    1127         return $encoded; 
    1128     } 
    1129  
    1130     /** 
    1131      * Encode a header string to best of Q, B, quoted or none. 
    1132      * @access private 
    1133      * @return string 
    1134      */ 
    1135     function EncodeHeader ($str, $position = 'text') { 
    1136       $x = 0; 
    1137  
    1138       switch (strtolower($position)) { 
    1139         case 'phrase': 
    1140           if (!preg_match('/[\200-\377]/', $str)) { 
    1141             // Can't use addslashes as we don't know what value has magic_quotes_sybase. 
    1142             $encoded = addcslashes($str, "\0..\37\177\\\""); 
    1143  
    1144             if (($str == $encoded) && !preg_match('/[^A-Za-z0-9!#$%&\'*+\/=?^_`{|}~ -]/', $str)) 
    1145               return ($encoded); 
    1146             else 
    1147               return ("\"$encoded\""); 
    1148           } 
    1149           $x = preg_match_all('/[^\040\041\043-\133\135-\176]/', $str, $matches); 
    1150           break; 
    1151         case 'comment': 
    1152           $x = preg_match_all('/[()"]/', $str, $matches); 
    1153           // Fall-through 
    1154         case 'text': 
    1155         default: 
    1156           $x += preg_match_all('/[\000-\010\013\014\016-\037\177-\377]/', $str, $matches); 
    1157           break; 
    1158       } 
    1159  
    1160       if ($x == 0) 
    1161         return ($str); 
    1162  
    1163       $maxlen = 75 - 7 - strlen($this->CharSet); 
    1164       // Try to select the encoding which should produce the shortest output 
    1165       if (strlen($str)/3 < $x) { 
    1166         $encoding = 'B'; 
     1264        $x = preg_match_all('/[^\040\041\043-\133\135-\176]/', $str, $matches); 
     1265        break; 
     1266      case 'comment': 
     1267        $x = preg_match_all('/[()"]/', $str, $matches); 
     1268        /* Fall-through */ 
     1269      case 'text': 
     1270      default: 
     1271        $x += preg_match_all('/[\000-\010\013\014\016-\037\177-\377]/', $str, $matches); 
     1272        break; 
     1273    } 
     1274 
     1275    if ($x == 0) { 
     1276      return ($str); 
     1277    } 
     1278 
     1279    $maxlen = 75 - 7 - strlen($this->CharSet); 
     1280    /* Try to select the encoding which should produce the shortest output */ 
     1281    if (strlen($str)/3 < $x) { 
     1282      $encoding = 'B'; 
     1283      if (function_exists('mb_strlen') && $this->HasMultiBytes($str)) { 
     1284     // Use a custom function which correctly encodes and wraps long 
     1285     // multibyte strings without breaking lines within a character 
     1286        $encoded = $this->Base64EncodeWrapMB($str); 
     1287      } else { 
    11671288        $encoded = base64_encode($str); 
    11681289        $maxlen -= $maxlen % 4; 
    11691290        $encoded = trim(chunk_split($encoded, $maxlen, "\n")); 
    1170       } else { 
    1171         $encoding = 'Q'; 
    1172         $encoded = $this->EncodeQ($str, $position); 
    1173         $encoded = $this->WrapText($encoded, $maxlen, true); 
    1174         $encoded = str_replace("=".$this->LE, "\n", trim($encoded)); 
    1175       } 
    1176  
    1177       $encoded = preg_replace('/^(.*)$/m', " =?".$this->CharSet."?$encoding?\\1?=", $encoded); 
    1178       $encoded = trim(str_replace("\n", $this->LE, $encoded)); 
    1179  
    1180       return $encoded; 
    1181     } 
    1182  
    1183     /** 
    1184      * Encode string to quoted-printable. 
    1185      * @access private 
    1186      * @return string 
    1187      */ 
    1188     function EncodeQP ($str) { 
    1189         $encoded = $this->FixEOL($str); 
    1190         if (substr($encoded, -(strlen($this->LE))) != $this->LE) 
    1191             $encoded .= $this->LE; 
    1192  
    1193         // Replace every high ascii, control and = characters 
    1194         $encoded = preg_replace('/([\000-\010\013\014\016-\037\075\177-\377])/e', 
    1195                   "'='.sprintf('%02X', ord('\\1'))", $encoded); 
    1196         // Replace every spaces and tabs when it's the last character on a line 
    1197         $encoded = preg_replace("/([\011\040])".$this->LE."/e", 
    1198                   "'='.sprintf('%02X', ord('\\1')).'".$this->LE."'", $encoded); 
    1199  
    1200         // Maximum line length of 76 characters before CRLF (74 + space + '=') 
    1201         $encoded = $this->WrapText($encoded, 74, true); 
    1202  
    1203         return $encoded; 
    1204     } 
    1205  
    1206     /** 
    1207      * Encode string to q encoding. 
    1208      * @access private 
    1209      * @return string 
    1210      */ 
    1211     function EncodeQ ($str, $position = "text") { 
    1212         // There should not be any EOL in the string 
    1213         $encoded = preg_replace("[\r\n]", "", $str); 
    1214  
    1215         switch (strtolower($position)) { 
    1216           case "phrase": 
    1217             $encoded = preg_replace("/([^A-Za-z0-9!*+\/ -])/e", "'='.sprintf('%02X', ord('\\1'))", $encoded); 
    1218             break; 
    1219           case "comment": 
    1220             $encoded = preg_replace("/([\(\)\"])/e", "'='.sprintf('%02X', ord('\\1'))", $encoded); 
    1221           case "text": 
    1222           default: 
    1223             // Replace every high ascii, control =, ? and _ characters 
    1224             $encoded = preg_replace('/([\000-\011\013\014\016-\037\075\077\137\177-\377])/e', 
    1225                   "'='.sprintf('%02X', ord('\\1'))", $encoded); 
    1226             break; 
     1291      } 
     1292    } else { 
     1293      $encoding = 'Q'; 
     1294      $encoded = $this->EncodeQ($str, $position); 
     1295      $encoded = $this->WrapText($encoded, $maxlen, true); 
     1296      $encoded = str_replace('='.$this->LE, "\n", trim($encoded)); 
     1297    } 
     1298 
     1299    $encoded = preg_replace('/^(.*)$/m', " =?".$this->CharSet."?$encoding?\\1?=", $encoded); 
     1300    $encoded = trim(str_replace("\n", $this->LE, $encoded)); 
     1301 
     1302    return $encoded; 
     1303  } 
     1304 
     1305  /** 
     1306   * Checks if a string contains multibyte characters. 
     1307   * @access private 
     1308   * @param string $str multi-byte text to wrap encode 
     1309   * @return bool 
     1310   */ 
     1311  function HasMultiBytes($str) { 
     1312    if (function_exists('mb_strlen')) { 
     1313      return (strlen($str) > mb_strlen($str, $this->CharSet)); 
     1314    } else { // Assume no multibytes (we can't handle without mbstring functions anyway) 
     1315      return False; 
     1316    } 
     1317  } 
     1318 
     1319  /** 
     1320   * Correctly encodes and wraps long multibyte strings for mail headers 
     1321   * without breaking lines within a character. 
     1322   * Adapted from a function by paravoid at http://uk.php.net/manual/en/function.mb-encode-mimeheader.php 
     1323   * @access private 
     1324   * @param string $str multi-byte text to wrap encode 
     1325   * @return string 
     1326   */ 
     1327  function Base64EncodeWrapMB($str) { 
     1328    $start = "=?".$this->CharSet."?B?"; 
     1329    $end = "?="; 
     1330    $encoded = ""; 
     1331 
     1332    $mb_length = mb_strlen($str, $this->CharSet); 
     1333    // Each line must have length <= 75, including $start and $end 
     1334    $length = 75 - strlen($start) - strlen($end); 
     1335    // Average multi-byte ratio 
     1336    $ratio = $mb_length / strlen($str); 
     1337    // Base64 has a 4:3 ratio 
     1338    $offset = $avgLength = floor($length * $ratio * .75); 
     1339 
     1340    for ($i = 0; $i < $mb_length; $i += $offset) { 
     1341      $lookBack = 0; 
     1342 
     1343      do { 
     1344        $offset = $avgLength - $lookBack; 
     1345        $chunk = mb_substr($str, $i, $offset, $this->CharSet); 
     1346        $chunk = base64_encode($chunk); 
     1347        $lookBack++; 
     1348      } 
     1349      while (strlen($chunk) > $length); 
     1350 
     1351      $encoded .= $chunk . $this->LE; 
     1352    } 
     1353 
     1354    // Chomp the last linefeed 
     1355    $encoded = substr($encoded, 0, -strlen($this->LE)); 
     1356    return $encoded; 
     1357  } 
     1358 
     1359  /** 
     1360   * Encode string to quoted-printable. 
     1361   * @access private 
     1362   * @return string 
     1363   */ 
     1364  function EncodeQP( $input = '', $line_max = 76, $space_conv = false ) { 
     1365    $hex = array('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'); 
     1366    $lines = preg_split('/(?:\r\n|\r|\n)/', $input); 
     1367    $eol = "\r\n"; 
     1368    $escape = '='; 
     1369    $output = ''; 
     1370    while( list(, $line) = each($lines) ) { 
     1371      $linlen = strlen($line); 
     1372      $newline = ''; 
     1373      for($i = 0; $i < $linlen; $i++) { 
     1374        $c = substr( $line, $i, 1 ); 
     1375        $dec = ord( $c ); 
     1376        if ( ( $i == 0 ) && ( $dec == 46 ) ) { // convert first point in the line into =2E 
     1377          $c = '=2E'; 
    12271378        } 
    1228  
    1229         // Replace every spaces to _ (more readable than =20) 
    1230         $encoded = str_replace(" ", "_", $encoded); 
    1231  
    1232         return $encoded; 
    1233     } 
    1234  
    1235     /** 
    1236      * Adds a string or binary attachment (non-filesystem) to the list. 
    1237      * This method can be used to attach ascii or binary data, 
    1238      * such as a BLOB record from a database. 
    1239      * @param string $string String attachment data. 
    1240      * @param string $filename Name of the attachment. 
    1241      * @param string $encoding File encoding (see $Encoding). 
    1242      * @param string $type File extension (MIME) type. 
    1243      * @return void 
    1244      */ 
    1245     function AddStringAttachment($string, $filename, $encoding = "base64", 
    1246                                  $type = "application/octet-stream") { 
    1247         // Append to $attachment array 
    1248         $cur = count($this->attachment); 
    1249         $this->attachment[$cur][0] = $string; 
    1250         $this->attachment[$cur][1] = $filename; 
    1251         $this->attachment[$cur][2] = $filename; 
    1252         $this->attachment[$cur][3] = $encoding; 
    1253         $this->attachment[$cur][4] = $type; 
    1254         $this->attachment[$cur][5] = true; // isString 
    1255         $this->attachment[$cur][6] = "attachment"; 
    1256         $this->attachment[$cur][7] = 0; 
    1257     } 
    1258  
    1259     /** 
    1260      * Adds an embedded attachment.  This can include images, sounds, and 
    1261      * just about any other document.  Make sure to set the $type to an 
    1262      * image type.  For JPEG images use "image/jpeg" and for GIF images 
    1263      * use "image/gif". 
    1264      * @param string $path Path to the attachment. 
    1265      * @param string $cid Content ID of the attachment.  Use this to identify 
    1266      *        the Id for accessing the image in an HTML form. 
    1267      * @param string $name Overrides the attachment name. 
    1268      * @param string $encoding File encoding (see $Encoding). 
    1269      * @param string $type File extension (MIME) type. 
    1270      * @return bool 
    1271      */ 
    1272     function AddEmbeddedImage($path, $cid, $name = "", $encoding = "base64", 
    1273                               $type = "application/octet-stream") { 
    1274  
    1275         if(!@is_file($path)) 
    1276         { 
    1277             $this->SetError($this->Lang("file_access") . $path); 
    1278             return false; 
     1379        if ( $dec == 32 ) { 
     1380          if ( $i == ( $linlen - 1 ) ) { // convert space at eol only 
     1381            $c = '=20'; 
     1382          } else if ( $space_conv ) { 
     1383            $c = '=20'; 
     1384          } 
     1385        } elseif ( ($dec == 61) || ($dec < 32 ) || ($dec > 126) ) { // always encode "\t", which is *not* required 
     1386          $h2 = floor($dec/16); 
     1387          $h1 = floor($dec%16); 
     1388          $c = $escape.$hex[$h2].$hex[$h1]; 
    12791389        } 
    1280  
    1281         $filename = basename($path); 
    1282         if($name == "") 
    1283             $name = $filename; 
    1284  
    1285         // Append to $attachment array 
    1286         $cur = count($this->attachment); 
    1287         $this->attachment[$cur][0] = $path; 
    1288         $this->attachment[$cur][1] = $filename; 
    1289         $this->attachment[$cur][2] = $name; 
    1290         $this->attachment[$cur][3] = $encoding; 
    1291         $this->attachment[$cur][4] = $type; 
    1292         $this->attachment[$cur][5] = false; // isStringAttachment 
    1293         $this->attachment[$cur][6] = "inline"; 
    1294         $this->attachment[$cur][7] = $cid; 
    1295  
    1296         return true; 
    1297     } 
    1298  
    1299     /** 
    1300      * Returns true if an inline attachment is present. 
    1301      * @access private 
    1302      * @return bool 
    1303      */ 
    1304     function InlineImageExists() { 
    1305         $result = false; 
    1306         for($i = 0; $i < count($this->attachment); $i++) 
    1307         { 
    1308             if($this->attachment[$i][6] == "inline") 
    1309             { 
    1310                 $result = true; 
    1311                 break; 
    1312             } 
     1390        if ( (strlen($newline) + strlen($c)) >= $line_max ) { // CRLF is not counted 
     1391          $output .= $newline.$escape.$eol; //  soft line break; " =\r\n" is okay 
     1392          $newline = ''; 
     1393          // check if newline first character will be point or not 
     1394          if ( $dec == 46 ) { 
     1395            $c = '=2E'; 
     1396          } 
    13131397        } 
    1314  
    1315         return $result; 
    1316     } 
    1317  
    1318     ///////////////////////////////////////////////// 
    1319     // MESSAGE RESET METHODS 
    1320     ///////////////////////////////////////////////// 
    1321  
    1322     /** 
    1323      * Clears all recipients assigned in the TO array.  Returns void. 
    1324      * @return void 
    1325      */ 
    1326     function ClearAddresses() { 
    1327         $this->to = array(); 
    1328     } 
    1329  
    1330     /** 
    1331      * Clears all recipients assigned in the CC array.  Returns void. 
    1332      * @return void 
    1333      */ 
    1334     function ClearCCs() { 
    1335         $this->cc = array(); 
    1336     } 
    1337  
    1338     /** 
    1339      * Clears all recipients assigned in the BCC array.  Returns void. 
    1340      * @return void 
    1341      */ 
    1342     function ClearBCCs() { 
    1343         $this->bcc = array(); 
    1344     } 
    1345  
    1346     /** 
    1347      * Clears all recipients assigned in the ReplyTo array.  Returns void. 
    1348      * @return void 
    1349      */ 
    1350     function ClearReplyTos() { 
    1351         $this->ReplyTo = array(); 
    1352     } 
    1353  
    1354     /** 
    1355      * Clears all recipients assigned in the TO, CC and BCC 
    1356      * array.  Returns void. 
    1357      * @return void 
    1358      */ 
    1359     function ClearAllRecipients() { 
    1360         $this->to = array(); 
    1361         $this->cc = array(); 
    1362         $this->bcc = array(); 
    1363     } 
    1364  
    1365     /** 
    1366      * Clears all previously set filesystem, string, and binary 
    1367      * attachments.  Returns void. 
    1368      * @return void 
    1369      */ 
    1370     function ClearAttachments() { 
    1371         $this->attachment = array(); 
    1372     } 
    1373  
    1374     /** 
    1375      * Clears all custom headers.  Returns void. 
    1376      * @return void 
    1377      */ 
    1378     function ClearCustomHeaders() { 
    1379         $this->CustomHeader = array(); 
    1380     } 
    1381  
    1382  
    1383     ///////////////////////////////////////////////// 
    1384     // MISCELLANEOUS METHODS 
    1385     ///////////////////////////////////////////////// 
    1386  
    1387     /** 
    1388      * Adds the error message to the error container. 
    1389      * Returns void. 
    1390      * @access private 
    1391      * @return void 
    1392      */ 
    1393     function SetError($msg) { 
    1394         $this->error_count++; 
    1395         $this->ErrorInfo = $msg; 
    1396     } 
    1397  
    1398     /** 
    1399      * Returns the proper RFC 822 formatted date. 
    1400      * @access private 
    1401      * @return string 
    1402      */ 
    1403     function RFCDate() { 
    1404         $tz = date("Z"); 
    1405         $tzs = ($tz < 0) ? "-" : "+"; 
    1406         $tz = abs($tz); 
    1407         $tz = ($tz/3600)*100 + ($tz%3600)/60; 
    1408         $result = sprintf("%s %s%04d", date("D, j M Y H:i:s"), $tzs, $tz); 
    1409  
    1410         return $result; 
    1411     } 
    1412  
    1413     /** 
    1414      * Returns the appropriate server variable.  Should work with both 
    1415      * PHP 4.1.0+ as well as older versions.  Returns an empty string 
    1416      * if nothing is found. 
    1417      * @access private 
    1418      * @return mixed 
    1419      */ 
    1420     function ServerVar($varName) { 
    1421         global $HTTP_SERVER_VARS; 
    1422         global $HTTP_ENV_VARS; 
    1423  
    1424         if(!isset($_SERVER)) 
    1425         { 
    1426             $_SERVER = $HTTP_SERVER_VARS; 
    1427             if(!isset($_SERVER["REMOTE_ADDR"])) 
    1428                 $_SERVER = $HTTP_ENV_VARS; // must be Apache 
     1398        $newline .= $c; 
     1399      } // end of for 
     1400      $output .= $newline.$eol; 
     1401    } // end of while 
     1402    return trim($output); 
     1403  } 
     1404 
     1405  /** 
     1406   * Encode string to q encoding. 
     1407   * @access private 
     1408   * @return string 
     1409   */ 
     1410  function EncodeQ ($str, $position = 'text') { 
     1411    /* There should not be any EOL in the string */ 
     1412    $encoded = preg_replace("[\r\n]", '', $str); 
     1413 
     1414    switch (strtolower($position)) { 
     1415      case 'phrase': 
     1416        $encoded = preg_replace("/([^A-Za-z0-9!*+\/ -])/e", "'='.sprintf('%02X', ord('\\1'))", $encoded); 
     1417        break; 
     1418      case 'comment': 
     1419        $encoded = preg_replace("/([\(\)\"])/e", "'='.sprintf('%02X', ord('\\1'))", $encoded); 
     1420      case 'text': 
     1421      default: 
     1422        /* Replace every high ascii, control =, ? and _ characters */ 
     1423        $encoded = preg_replace('/([\000-\011\013\014\016-\037\075\077\137\177-\377])/e', 
     1424              "'='.sprintf('%02X', ord('\\1'))", $encoded); 
     1425        break; 
     1426    } 
     1427 
     1428    /* Replace every spaces to _ (more readable than =20) */ 
     1429    $encoded = str_replace(' ', '_', $encoded); 
     1430 
     1431    return $encoded; 
     1432  } 
     1433 
     1434  /** 
     1435   * Adds a string or binary attachment (non-filesystem) to the list. 
     1436   * This method can be used to attach ascii or binary data, 
     1437   * such as a BLOB record from a database. 
     1438   * @param string $string String attachment data. 
     1439   * @param string $filename Name of the attachment. 
     1440   * @param string $encoding File encoding (see $Encoding). 
     1441   * @param string $type File extension (MIME) type. 
     1442   * @return void 
     1443   */ 
     1444  function AddStringAttachment($string, $filename, $encoding = 'base64', $type = 'application/octet-stream') { 
     1445    /* Append to $attachment array */ 
     1446    $cur = count($this->attachment); 
     1447    $this->attachment[$cur][0] = $string; 
     1448    $this->attachment[$cur][1] = $filename; 
     1449    $this->attachment[$cur][2] = $filename; 
     1450    $this->attachment[$cur][3] = $encoding; 
     1451    $this->attachment[$cur][4] = $type; 
     1452    $this->attachment[$cur][5] = true; // isString 
     1453    $this->attachment[$cur][6] = 'attachment'; 
     1454    $this->attachment[$cur][7] = 0; 
     1455  } 
     1456 
     1457  /** 
     1458   * Adds an embedded attachment.  This can include images, sounds, and 
     1459   * just about any other document.  Make sure to set the $type to an 
     1460   * image type.  For JPEG images use "image/jpeg" and for GIF images 
     1461   * use "image/gif". 
     1462   * @param string $path Path to the attachment. 
     1463   * @param string $cid Content ID of the attachment.  Use this to identify 
     1464   *        the Id for accessing the image in an HTML form. 
     1465   * @param string $name Overrides the attachment name. 
     1466   * @param string $encoding File encoding (see $Encoding). 
     1467   * @param string $type File extension (MIME) type. 
     1468   * @return bool 
     1469   */ 
     1470  function AddEmbeddedImage($path, $cid, $name = '', $encoding = 'base64', $type = 'application/octet-stream') { 
     1471 
     1472    if(!@is_file($path)) { 
     1473      $this->SetError($this->Lang('file_access') . $path); 
     1474      return false; 
     1475    } 
     1476 
     1477    $filename = basename($path); 
     1478    if($name == '') { 
     1479      $name = $filename; 
     1480    } 
     1481 
     1482    /* Append to $attachment array */ 
     1483    $cur = count($this->attachment); 
     1484    $this->attachment[$cur][0] = $path; 
     1485    $this->attachment[$cur][1] = $filename; 
     1486    $this->attachment[$cur][2] = $name; 
     1487    $this->attachment[$cur][3] = $encoding; 
     1488    $this->attachment[$cur][4] = $type; 
     1489    $this->attachment[$cur][5] = false; 
     1490    $this->attachment[$cur][6] = 'inline'; 
     1491    $this->attachment[$cur][7] = $cid; 
     1492 
     1493    return true; 
     1494  } 
     1495 
     1496  /** 
     1497   * Returns true if an inline attachment is present. 
     1498   * @access private 
     1499   * @return bool 
     1500   */ 
     1501  function InlineImageExists() { 
     1502    $result = false; 
     1503    for($i = 0; $i < count($this->attachment); $i++) { 
     1504      if($this->attachment[$i][6] == 'inline') { 
     1505        $result = true; 
     1506        break; 
     1507      } 
     1508    } 
     1509 
     1510    return $result; 
     1511  } 
     1512 
     1513  ///////////////////////////////////////////////// 
     1514  // CLASS METHODS, MESSAGE RESET 
     1515  ///////////////////////////////////////////////// 
     1516 
     1517  /** 
     1518   * Clears all recipients assigned in the TO array.  Returns void. 
     1519   * @return void 
     1520   */ 
     1521  function ClearAddresses() { 
     1522    $this->to = array(); 
     1523  } 
     1524 
     1525  /** 
     1526   * Clears all recipients assigned in the CC array.  Returns void. 
     1527   * @return void 
     1528   */ 
     1529  function ClearCCs() { 
     1530    $this->cc = array(); 
     1531  } 
     1532 
     1533  /** 
     1534   * Clears all recipients assigned in the BCC array.  Returns void. 
     1535   * @return void 
     1536   */ 
     1537  function ClearBCCs() { 
     1538    $this->bcc = array(); 
     1539  } 
     1540 
     1541  /** 
     1542   * Clears all recipients assigned in the ReplyTo array.  Returns void. 
     1543   * @return void 
     1544   */ 
     1545  function ClearReplyTos() { 
     1546    $this->ReplyTo = array(); 
     1547  } 
     1548 
     1549  /** 
     1550   * Clears all recipients assigned in the TO, CC and BCC 
     1551   * array.  Returns void. 
     1552   * @return void 
     1553   */ 
     1554  function ClearAllRecipients() { 
     1555    $this->to = array(); 
     1556    $this->cc = array(); 
     1557    $this->bcc = array(); 
     1558  } 
     1559 
     1560  /** 
     1561   * Clears all previously set filesystem, string, and binary 
     1562   * attachments.  Returns void. 
     1563   * @return void 
     1564   */ 
     1565  function ClearAttachments() { 
     1566    $this->attachment = array(); 
     1567  } 
     1568 
     1569  /** 
     1570   * Clears all custom headers.  Returns void. 
     1571   * @return void 
     1572   */ 
     1573  function ClearCustomHeaders() { 
     1574    $this->CustomHeader = array(); 
     1575  } 
     1576 
     1577  ///////////////////////////////////////////////// 
     1578  // CLASS METHODS, MISCELLANEOUS 
     1579  ///////////////////////////////////////////////// 
     1580 
     1581  /** 
     1582   * Adds the error message to the error container. 
     1583   * Returns void. 
     1584   * @access private 
     1585   * @return void 
     1586   */ 
     1587  function SetError($msg) { 
     1588    $this->error_count++; 
     1589    $this->ErrorInfo = $msg; 
     1590  } 
     1591 
     1592  /** 
     1593   * Returns the proper RFC 822 formatted date. 
     1594   * @access private 
     1595   * @return string 
     1596   */ 
     1597  function RFCDate() { 
     1598    $tz = date('Z'); 
     1599    $tzs = ($tz < 0) ? '-' : '+'; 
     1600    $tz = abs($tz); 
     1601    $tz = (int)($tz/3600)*100 + ($tz%3600)/60; 
     1602    $result = sprintf("%s %s%04d", date('D, j M Y H:i:s'), $tzs, $tz); 
     1603 
     1604    return $result; 
     1605  } 
     1606 
     1607  /** 
     1608   * Returns the appropriate server variable.  Should work with both 
     1609   * PHP 4.1.0+ as well as older versions.  Returns an empty string 
     1610   * if nothing is found. 
     1611   * @access private 
     1612   * @return mixed 
     1613   */ 
     1614  function ServerVar($varName) { 
     1615    global $HTTP_SERVER_VARS; 
     1616    global $HTTP_ENV_VARS; 
     1617 
     1618    if(!isset($_SERVER)) { 
     1619      $_SERVER = $HTTP_SERVER_VARS; 
     1620      if(!isset($_SERVER['REMOTE_ADDR'])) { 
     1621        $_SERVER = $HTTP_ENV_VARS; // must be Apache 
     1622      } 
     1623    } 
     1624 
     1625    if(isset($_SERVER[$varName])) { 
     1626      return $_SERVER[$varName]; 
     1627    } else { 
     1628      return ''; 
     1629    } 
     1630  } 
     1631 
     1632  /** 
     1633   * Returns the server hostname or 'localhost.localdomain' if unknown. 
     1634   * @access private 
     1635   * @return string 
     1636   */ 
     1637  function ServerHostname() { 
     1638    if ($this->Hostname != '') { 
     1639      $result = $this->Hostname; 
     1640    } elseif ($this->ServerVar('SERVER_NAME') != '') { 
     1641      $result = $this->ServerVar('SERVER_NAME'); 
     1642    } else { 
     1643      $result = 'localhost.localdomain'; 
     1644    } 
     1645 
     1646    return $result; 
     1647  } 
     1648 
     1649  /** 
     1650   * Returns a message in the appropriate language. 
     1651   * @access private 
     1652   * @return string 
     1653   */ 
     1654  function Lang($key) { 
     1655    if(count($this->language) < 1) { 
     1656      $this->SetLanguage('en'); // set the default language 
     1657    } 
     1658 
     1659    if(isset($this->language[$key])) { 
     1660      return $this->language[$key]; 
     1661    } else { 
     1662      return 'Language string failed to load: ' . $key; 
     1663    } 
     1664  } 
     1665 
     1666  /** 
     1667   * Returns true if an error occurred. 
     1668   * @return bool 
     1669   */ 
     1670  function IsError() { 
     1671    return ($this->error_count > 0); 
     1672  } 
     1673 
     1674  /** 
     1675   * Changes every end of line from CR or LF to CRLF. 
     1676   * @access private 
     1677   * @return string 
     1678   */ 
     1679  function FixEOL($str) { 
     1680    $str = str_replace("\r\n", "\n", $str); 
     1681    $str = str_replace("\r", "\n", $str); 
     1682    $str = str_replace("\n", $this->LE, $str); 
     1683    return $str; 
     1684  } 
     1685 
     1686  /** 
     1687   * Adds a custom header. 
     1688   * @return void 
     1689   */ 
     1690  function AddCustomHeader($custom_header) { 
     1691    $this->CustomHeader[] = explode(':', $custom_header, 2); 
     1692  } 
     1693 
     1694  /** 
     1695   * Evaluates the message and returns modifications for inline images and backgrounds 
     1696   * @access public 
     1697   * @return $message 
     1698   */ 
     1699  function MsgHTML($message,$basedir='') { 
     1700    preg_match_all("/(src|background)=\"(.*)\"/Ui", $message, $images); 
     1701    if(isset($images[2])) { 
     1702      foreach($images[2] as $i => $url) { 
     1703        // do not change urls for absolute images (thanks to corvuscorax) 
     1704        if (!preg_match('/^[A-z][A-z]*:\/\//',$url)) { 
     1705          $filename = basename($url); 
     1706          $directory = dirname($url); 
     1707          ($directory == '.')?$directory='':''; 
     1708          $cid = 'cid:' . md5($filename); 
     1709          $fileParts = split("\.", $filename); 
     1710          $ext = $fileParts[1]; 
     1711          $mimeType = $this->_mime_types($ext); 
     1712          if ( strlen($basedir) > 1 && substr($basedir,-1) != '/') { $basedir .= '/'; } 
     1713          if ( strlen($directory) > 1 && substr($basedir,-1) != '/') { $directory .= '/'; } 
     1714          $this->AddEmbeddedImage($basedir.$directory.$filename, md5($filename), $filename, 'base64', $mimeType); 
     1715          if ( $this->AddEmbeddedImage($basedir.$directory.$filename, md5($filename), $filename, 'base64',$mimeType) ) { 
     1716            $message = preg_replace("/".$images[1][$i]."=\"".preg_quote($url, '/')."\"/Ui", $images[1][$i]."=\"".$cid."\"", $message); 
     1717          } 
    14291718        } 
    1430  
    1431         if(isset($_SERVER[$varName])) 
    1432             return $_SERVER[$varName]; 
    1433         else 
    1434             return ""; 
    1435     } 
    1436  
    1437     /** 
    1438      * Returns the server hostname or 'localhost.localdomain' if unknown. 
    1439      * @access private 
    1440      * @return string 
    1441      */ 
    1442     function ServerHostname() { 
    1443         if ($this->Hostname != "") 
    1444             $result = $this->Hostname; 
    1445         elseif ($this->ServerVar('SERVER_NAME') != "") 
    1446             $result = $this->ServerVar('SERVER_NAME'); 
    1447         else 
    1448             $result = "localhost.localdomain"; 
    1449  
    1450         return $result; 
    1451     } 
    1452  
    1453     /** 
    1454      * Returns a message in the appropriate language. 
    1455      * @access private 
    1456      * @return string 
    1457      */ 
    1458     function Lang($key) { 
    1459         if(count($this->language) < 1) 
    1460             $this->SetLanguage("en"); // set the default language 
    1461  
    1462         if(isset($this->language[$key])) 
    1463             return $this->language[$key]; 
    1464         else 
    1465             return "Language string failed to load: " . $key; 
    1466     } 
    1467  
    1468     /** 
    1469      * Returns true if an error occurred. 
    1470      * @return bool 
    1471      */ 
    1472     function IsError() { 
    1473         return ($this->error_count > 0); 
    1474     } 
    1475  
    1476     /** 
    1477      * Changes every end of line from CR or LF to CRLF. 
    1478      * @access private 
    1479      * @return string 
    1480      */ 
    1481     function FixEOL($str) { 
    1482         $str = str_replace("\r\n", "\n", $str); 
    1483         $str = str_replace("\r", "\n", $str); 
    1484         $str = str_replace("\n", $this->LE, $str); 
    1485         return $str; 
    1486     } 
    1487  
    1488     /** 
    1489      * Adds a custom header. 
    1490      * @return void 
    1491      */ 
    1492     function AddCustomHeader($custom_header) { 
    1493         $this->CustomHeader[] = explode(":", $custom_header, 2); 
    1494     } 
     1719      } 
     1720    } 
     1721    $this->IsHTML(true); 
     1722    $this->Body = $message; 
     1723    $textMsg = trim(strip_tags(preg_replace('/<(head|title|style|script)[^>]*>.*?<\/\\1>/s','',$message))); 
     1724    if ( !empty($textMsg) && empty($this->AltBody) ) { 
     1725      $this->AltBody = $textMsg; 
     1726    } 
     1727    if ( empty($this->AltBody) ) { 
     1728      $this->AltBody = 'To view this email message, open the email in with HTML compatibility!' . "\n\n"; 
     1729    } 
     1730  } 
     1731 
     1732  /** 
     1733   * Gets the mime type of the embedded or inline image 
     1734   * @access private 
     1735   * @return mime type of ext 
     1736   */ 
     1737  function _mime_types($ext = '') { 
     1738    $mimes = array( 
     1739      'hqx'  =>  'application/mac-binhex40', 
     1740      'cpt'   =>  'application/mac-compactpro', 
     1741      'doc'   =>  'application/msword', 
     1742      'bin'   =>  'application/macbinary', 
     1743      'dms'   =>  'application/octet-stream', 
     1744      'lha'   =>  'application/octet-stream', 
     1745      'lzh'   =>  'application/octet-stream', 
     1746      'exe'   =>  'application/octet-stream', 
     1747      'class' =>  'application/octet-stream', 
     1748      'psd'   =>  'application/octet-stream', 
     1749      'so'    =>  'application/octet-stream', 
     1750      'sea'   =>  'application/octet-stream', 
     1751      'dll'   =>  'application/octet-stream', 
     1752      'oda'   =>  'application/oda', 
     1753      'pdf'   =>  'application/pdf', 
     1754      'ai'    =>  'application/postscript', 
     1755      'eps'   =>  'application/postscript', 
     1756      'ps'    =>  'application/postscript', 
     1757      'smi'   =>  'application/smil', 
     1758      'smil'  =>  'application/smil', 
     1759      'mif'   =>  'application/vnd.mif', 
     1760      'xls'   =>  'application/vnd.ms-excel', 
     1761      'ppt'   =>  'application/vnd.ms-powerpoint', 
     1762      'wbxml' =>  'application/vnd.wap.wbxml', 
     1763      'wmlc'  =>  'application/vnd.wap.wmlc', 
     1764      'dcr'   =>  'application/x-director', 
     1765      'dir'   =>  'application/x-director', 
     1766      'dxr'   =>  'application/x-director', 
     1767      'dvi'   =>  'application/x-dvi', 
     1768      'gtar'  =>  'application/x-gtar', 
     1769      'php'   =>  'application/x-httpd-php', 
     1770      'php4'  =>  'application/x-httpd-php', 
     1771      'php3'  =>  'application/x-httpd-php', 
     1772      'phtml' =>  'application/x-httpd-php', 
     1773      'phps'  =>  'application/x-httpd-php-source', 
     1774      'js'    =>  'application/x-javascript', 
     1775      'swf'   =>  'application/x-shockwave-flash', 
     1776      'sit'   =>  'application/x-stuffit', 
     1777      'tar'   =>  'application/x-tar', 
     1778      'tgz'   =>  'application/x-tar', 
     1779      'xhtml' =>  'application/xhtml+xml', 
     1780      'xht'   =>  'application/xhtml+xml', 
     1781      'zip'   =>  'application/zip', 
     1782      'mid'   =>  'audio/midi', 
     1783      'midi'  =>  'audio/midi', 
     1784      'mpga'  =>  'audio/mpeg', 
     1785      'mp2'   =>  'audio/mpeg', 
     1786      'mp3'   =>  'audio/mpeg', 
     1787      'aif'   =>  'audio/x-aiff', 
     1788      'aiff'  =>  'audio/x-aiff', 
     1789      'aifc'  =>  'audio/x-aiff', 
     1790      'ram'   =>  'audio/x-pn-realaudio', 
     1791      'rm'    =>  'audio/x-pn-realaudio', 
     1792      'rpm'   =>  'audio/x-pn-realaudio-plugin', 
     1793      'ra'    =>  'audio/x-realaudio', 
     1794      'rv'    =>  'video/vnd.rn-realvideo', 
     1795      'wav'   =>  'audio/x-wav', 
     1796      'bmp'   =>  'image/bmp', 
     1797      'gif'   =>  'image/gif', 
     1798      'jpeg'  =>  'image/jpeg', 
     1799      'jpg'   =>  'image/jpeg', 
     1800      'jpe'   =>  'image/jpeg', 
     1801      'png'   =>  'image/png', 
     1802      'tiff'  =>  'image/tiff', 
     1803      'tif'   =>  'image/tiff', 
     1804      'css'   =>  'text/css', 
     1805      'html'  =>  'text/html', 
     1806      'htm'   =>  'text/html', 
     1807      'shtml' =>  'text/html', 
     1808      'txt'   =>  'text/plain', 
     1809      'text'  =>  'text/plain', 
     1810      'log'   =>  'text/plain', 
     1811      'rtx'   =>  'text/richtext', 
     1812      'rtf'   =>  'text/rtf', 
     1813      'xml'   =>  'text/xml', 
     1814      'xsl'   =>  'text/xml', 
     1815      'mpeg'  =>  'video/mpeg', 
     1816      'mpg'   =>  'video/mpeg', 
     1817      'mpe'   =>  'video/mpeg', 
     1818      'qt'    =>  'video/quicktime', 
     1819      'mov'   =>  'video/quicktime', 
     1820      'avi'   =>  'video/x-msvideo', 
     1821      'movie' =>  'video/x-sgi-movie', 
     1822      'doc'   =>  'application/msword', 
     1823      'word'  =>  'application/msword', 
     1824      'xl'    =>  'application/excel', 
     1825      'eml'   =>  'message/rfc822' 
     1826    ); 
     1827    return ( ! isset($mimes[strtolower($ext)])) ? 'application/octet-stream' : $mimes[strtolower($ext)]; 
     1828  } 
     1829 
     1830  /** 
     1831   * Set (or reset) Class Objects (variables) 
     1832   * 
     1833   * Usage Example: 
     1834   * $page->set('X-Priority', '3'); 
     1835   * 
     1836   * @access public 
     1837   * @param string $name Parameter Name 
     1838   * @param mixed $value Parameter Value 
     1839   * NOTE: will not work with arrays, there are no arrays to set/reset 
     1840   */ 
     1841  function set ( $name, $value = '' ) { 
     1842    if ( isset($this->$name) ) { 
     1843      $this->$name = $value; 
     1844    } else { 
     1845      $this->SetError('Cannot set or reset variable ' . $name); 
     1846      return false; 
     1847    } 
     1848  } 
     1849 
     1850  /** 
     1851   * Read a file from a supplied filename and return it. 
     1852   * 
     1853   * @access public 
     1854   * @param string $filename Parameter File Name 
     1855   */ 
     1856  function getFile($filename) { 
     1857    $return = ''; 
     1858    if ($fp = fopen($filename, 'rb')) { 
     1859      while (!feof($fp)) { 
     1860        $return .= fread($fp, 1024); 
     1861      } 
     1862      fclose($fp); 
     1863      return $return; 
     1864    } else { 
     1865      return false; 
     1866    } 
     1867  } 
     1868 
     1869  /** 
     1870   * Strips newlines to prevent header injection. 
     1871   * @access private 
     1872   * @param string $str String 
     1873   * @return string 
     1874   */ 
     1875  function SecureHeader($str) { 
     1876    $str = trim($str); 
     1877    $str = str_replace("\r", "", $str); 
     1878    $str = str_replace("\n", "", $str); 
     1879    return $str; 
     1880  } 
     1881 
     1882  /** 
     1883   * Set the private key file and password to sign the message. 
     1884   * 
     1885   * @access public 
     1886   * @param string $key_filename Parameter File Name 
     1887   * @param string $key_pass Password for private key 
     1888   */ 
     1889  function Sign($key_filename, $key_pass) { 
     1890    $this->sign_key_file = $key_filename; 
     1891    $this->sign_key_pass = $key_pass; 
     1892  } 
     1893 
    14951894} 
    14961895 
  • trunk/wp-includes/class-pop3.php

    r8082 r8762  
    11<?php 
     2/*~ class.pop3.php 
     3.---------------------------------------------------------------------------. 
     4|  Software: PHPMailer - PHP email class                                    | 
     5|   Version: 2.0.2                                                          | 
     6|   Contact: via sourceforge.net support pages (also www.codeworxtech.com)  | 
     7|      Info: http://phpmailer.sourceforge.net                               | 
     8|   Support: http://sourceforge.net/projects/phpmailer/                     | 
     9| ------------------------------------------------------------------------- | 
     10|    Author: Andy Prevost (project admininistrator)                         | 
     11|    Author: Brent R. Matzelle (original founder)                           | 
     12| Copyright (c) 2004-2007, Andy Prevost. All Rights Reserved.               | 
     13| Copyright (c) 2001-2003, Brent R. Matzelle                                | 
     14| ------------------------------------------------------------------------- | 
     15|   License: Distributed under the Lesser General Public License (LGPL)     | 
     16|            http://www.gnu.org/copyleft/lesser.html                        | 
     17| This program is distributed in the hope that it will be useful - WITHOUT  | 
     18| ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or     | 
     19| FITNESS FOR A PARTICULAR PURPOSE.                                         | 
     20| ------------------------------------------------------------------------- | 
     21| We offer a number of paid services (www.codeworxtech.com):                | 
     22| - Web Hosting on highly optimized fast and secure servers                 | 
     23| - Technology Consulting                                                   | 
     24| - Oursourcing (highly qualified programmers and graphic designers)        | 
     25'---------------------------------------------------------------------------' 
     26 
    227/** 
    3  * mail_fetch/setup.php 
     28 * POP Before SMTP Authentication Class 
    429 * 
    5  * @package SquirrelMail 
     30 * Author: Richard Davey (rich@corephp.co.uk) 
     31 * License: LGPL, see PHPMailer License 
    632 * 
    7  * @copyright (c) 1999-2006 The SquirrelMail Project Team 
     33 * Specifically for PHPMailer to allow POP before SMTP authentication. 
     34 * Does not yet work with APOP - if you have an APOP account, contact me 
     35 * and we can test changes to this script. 
    836 * 
    9  * @copyright (c) 1999 CDI (cdi@thewebmasters.net) All Rights Reserved 
    10  * Modified by Philippe Mingo 2001 mingo@rotedic.com 
    11  * An RFC 1939 compliant wrapper class for the POP3 protocol. 
     37 * This class is based on the structure of the SMTP class by Chris Ryan 
    1238 * 
    13  * Licensed under the GNU GPL. For full terms see the file COPYING. 
     39 * This class is rfc 1939 compliant and implements all the commands 
     40 * required for POP3 connection, authentication and disconnection. 
    1441 * 
    15  * pop3 class 
    16  * 
    17  * $Id$ 
     42 * @package PHPMailer 
     43 * @author Richard Davey 
    1844 */ 
    1945 
    20 /** 
    21  * POP3 
    22  * 
    23  * @package SquirrelMail 
    24  */ 
    25 class POP3 { 
    26     var $ERROR      = '';       //  Error string. 
    27  
    28     var $TIMEOUT    = 60;       //  Default timeout before giving up on a 
    29                                 //  network operation. 
    30  
    31     var $COUNT      = -1;       //  Mailbox msg count 
    32  
    33     var $BUFFER     = 512;      //  Socket buffer for socket fgets() calls. 
    34                                 //  Per RFC 1939 the returned line a POP3 
    35                                 //  server can send is 512 bytes. 
    36  
    37     var $FP         = '';       //  The connection to the server's 
    38                                 //  file descriptor 
    39  
    40     var $MAILSERVER = '';       // Set this to hard code the server name 
    41  
    42     var $DEBUG      = FALSE;    // set to true to echo pop3 
    43                                 // commands and responses to error_log 
    44                                 // this WILL log passwords! 
    45  
    46     var $BANNER     = '';       //  Holds the banner returned by the 
    47                                 //  pop server - used for apop() 
    48  
    49     var $ALLOWAPOP  = FALSE;    //  Allow or disallow apop() 
    50                                 //  This must be set to true 
    51                                 //  manually 
    52  
    53     function POP3 ( $server = '', $timeout = '' ) { 
    54         settype($this->BUFFER,"integer"); 
    55         if( !empty($server) ) { 
    56             // Do not allow programs to alter MAILSERVER 
    57             // if it is already specified. They can get around 
    58             // this if they -really- want to, so don't count on it. 
    59             if(empty($this->MAILSERVER)) 
    60                 $this->MAILSERVER = $server; 
    61         } 
    62         if(!empty($timeout)) { 
    63             settype($timeout,"integer"); 
    64             $this->TIMEOUT = $timeout; 
    65             if (!ini_get('safe_mode')) 
    66                 set_time_limit($timeout); 
    67         } 
     46class POP3 
     47{ 
     48  /** 
     49   * Default POP3 port 
     50   * @var int 
     51   */ 
     52  var $POP3_PORT = 110; 
     53 
     54  /** 
     55   * Default Timeout 
     56   * @var int 
     57   */ 
     58  var $POP3_TIMEOUT = 30; 
     59 
     60  /** 
     61   * POP3 Carriage Return + Line Feed 
     62   * @var string 
     63   */ 
     64  var $CRLF = "\r\n"; 
     65 
     66  /** 
     67   * Displaying Debug warnings? (0 = now, 1+ = yes) 
     68   * @var int 
     69   */ 
     70  var $do_debug = 2; 
     71 
     72  /** 
     73   * POP3 Mail Server 
     74   * @var string 
     75   */ 
     76  var $host; 
     77 
     78  /** 
     79   * POP3 Port 
     80   * @var int 
     81   */ 
     82  var $port; 
     83 
     84  /** 
     85   * POP3 Timeout Value 
     86   * @var int 
     87   */ 
     88  var $tval; 
     89 
     90  /** 
     91   * POP3 Username 
     92   * @var string 
     93   */ 
     94  var $username; 
     95 
     96  /** 
     97   * POP3 Password 
     98   * @var string 
     99   */ 
     100  var $password; 
     101 
     102  /**#@+ 
     103   * @access private 
     104   */ 
     105  var $pop_conn; 
     106  var $connected; 
     107  var $error;     //  Error log array 
     108  /**#@-*/ 
     109 
     110  /** 
     111   * Constructor, sets the initial values 
     112   * 
     113   * @return POP3 
     114   */ 
     115  function POP3 () 
     116    { 
     117      $this->pop_conn = 0; 
     118      $this->connected = false; 
     119      $this->error = null; 
     120    } 
     121 
     122  /** 
     123   * Combination of public events - connect, login, disconnect 
     124   * 
     125   * @param string $host 
     126   * @param integer $port 
     127   * @param integer $tval 
     128   * @param string $username 
     129   * @param string $password 
     130   */ 
     131  function Authorise ($host, $port = false, $tval = false, $username, $password, $debug_level = 0) 
     132  { 
     133    $this->host = $host; 
     134 
     135    //  If no port value is passed, retrieve it 
     136    if ($port == false) 
     137    { 
     138      $this->port = $this->POP3_PORT; 
     139    } 
     140    else 
     141    { 
     142      $this->port = $port; 
     143    } 
     144 
     145    //  If no port value is passed, retrieve it 
     146    if ($tval == false) 
     147    { 
     148      $this->tval = $this->POP3_TIMEOUT; 
     149    } 
     150    else 
     151    { 
     152      $this->tval = $tval; 
     153    } 
     154 
     155    $this->do_debug = $debug_level; 
     156    $this->username = $username; 
     157    $this->password = $password; 
     158 
     159    //  Refresh the error log 
     160      $this->error = null; 
     161 
     162      //  Connect 
     163    $result = $this->Connect($this->host, $this->port, $this->tval); 
     164 
     165    if ($result) 
     166    { 
     167      $login_result = $this->Login($this->username, $this->password); 
     168 
     169      if ($login_result) 
     170      { 
     171        $this->Disconnect(); 
     172 
    68173        return true; 
    69     } 
    70  
    71     function update_timer () { 
    72         if (!ini_get('safe_mode')) 
    73             set_time_limit($this->TIMEOUT); 
     174      } 
     175 
     176    } 
     177 
     178    //  We need to disconnect regardless if the login succeeded 
     179    $this->Disconnect(); 
     180 
     181    return false; 
     182  } 
     183 
     184  /** 
     185   * Connect to the POP3 server 
     186   * 
     187   * @param string $host 
     188   * @param integer $port 
     189   * @param integer $tval 
     190   * @return boolean 
     191   */ 
     192  function Connect ($host, $port = false, $tval = 30) 
     193    { 
     194    //  Are we already connected? 
     195    if ($this->connected) 
     196    { 
     197      return true; 
     198    } 
     199 
     200    /* 
     201      On Windows this will raise a PHP Warning error if the hostname doesn't exist. 
     202      Rather than supress it with @fsockopen, let's capture it cleanly instead 
     203    */ 
     204 
     205    set_error_handler(array(&$this, 'catchWarning')); 
     206 
     207    //  Connect to the POP3 server 
     208    $this->pop_conn = fsockopen($host,    //  POP3 Host 
     209                  $port,    //  Port # 
     210                  $errno,   //  Error Number 
     211                  $errstr,  //  Error Message 
     212                  $tval);   //  Timeout (seconds) 
     213 
     214    //  Restore the error handler 
     215    restore_error_handler(); 
     216 
     217    //  Does the Error Log now contain anything? 
     218    if ($this->error && $this->do_debug >= 1) 
     219    { 
     220        $this->displayErrors(); 
     221    } 
     222 
     223    //  Did we connect? 
     224      if ($this->pop_conn == false) 
     225      { 
     226        //  It would appear not... 
     227        $this->error = array( 
     228          'error' => "Failed to connect to server $host on port $port", 
     229          'errno' => $errno, 
     230          'errstr' => $errstr 
     231        ); 
     232 
     233        if ($this->do_debug >= 1) 
     234        { 
     235          $this->displayErrors(); 
     236        } 
     237 
     238        return false; 
     239      } 
     240 
     241      //  Increase the stream time-out 
     242 
     243      //  Check for PHP 4.3.0 or later 
     244      if (version_compare(phpversion(), '4.3.0', 'ge')) 
     245      { 
     246        stream_set_timeout($this->pop_conn, $tval, 0); 
     247      } 
     248      else 
     249      { 
     250        //  Does not work on Windows 
     251        if (substr(PHP_OS, 0, 3) !== 'WIN') 
     252        { 
     253          socket_set_timeout($this->pop_conn, $tval, 0); 
     254        } 
     255      } 
     256 
     257    //  Get the POP3 server response 
     258      $pop3_response = $this->getResponse(); 
     259 
     260      //  Check for the +OK 
     261      if ($this->checkResponse($pop3_response)) 
     262      { 
     263      //  The connection is established and the POP3 server is talking 
     264      $this->connected = true; 
    74265        return true; 
    75     } 
    76  
    77     function connect ($server, $port = 110)  { 
    78         //  Opens a socket to the specified server. Unless overridden, 
    79         //  port defaults to 110. Returns true on success, false on fail 
    80  
    81         // If MAILSERVER is set, override $server with it's value 
    82  
    83     if (!isset($port) || !$port) {$port = 110;} 
    84         if(!empty($this->MAILSERVER)) 
    85             $server = $this->MAILSERVER; 
    86  
    87         if(empty($server)){ 
    88             $this->ERROR = "POP3 connect: " . _("No server specified"); 
    89             unset($this->FP); 
    90             return false; 
    91         } 
    92  
    93         $fp = @fsockopen("$server", $port, $errno, $errstr); 
    94  
    95         if(!$fp) { 
    96             $this->ERROR = "POP3 connect: " . _("Error ") . "[$errno] [$errstr]"; 
    97             unset($this->FP); 
    98             return false; 
    99         } 
    100  
    101         socket_set_blocking($fp,-1); 
    102         $this->update_timer(); 
    103         $reply = fgets($fp,$this->BUFFER); 
    104         $reply = $this->strip_clf($reply); 
    105         if($this->DEBUG) 
    106             error_log("POP3 SEND [connect: $server] GOT [$reply]",0); 
    107         if(!$this->is_ok($reply)) { 
    108             $this->ERROR = "POP3 connect: " . _("Error ") . "[$reply]"; 
    109             unset($this->FP); 
    110             return false; 
    111         } 
    112         $this->FP = $fp; 
    113         $this->BANNER = $this->parse_banner($reply); 
     266      } 
     267 
     268    } 
     269 
     270    /** 
     271     * Login to the POP3 server (does not support APOP yet) 
     272     * 
     273     * @param string $username 
     274     * @param string $password 
     275     * @return boolean 
     276     */ 
     277    function Login ($username = '', $password = '') 
     278    { 
     279      if ($this->connected == false) 
     280      { 
     281        $this->error = 'Not connected to POP3 server'; 
     282 
     283        if ($this->do_debug >= 1) 
     284        { 
     285          $this->displayErrors(); 
     286        } 
     287      } 
     288 
     289      if (empty($username)) 
     290      { 
     291        $username = $this->username; 
     292      } 
     293 
     294      if (empty($password)) 
     295      { 
     296        $password = $this->password; 
     297      } 
     298 
     299    $pop_username = "USER $username" . $this->CRLF; 
     300    $pop_password = "PASS $password" . $this->CRLF; 
     301 
     302      //  Send the Username 
     303      $this->sendString($pop_username); 
     304      $pop3_response = $this->getResponse(); 
     305 
     306      if ($this->checkResponse($pop3_response)) 
     307      { 
     308        //  Send the Password 
     309        $this->sendString($pop_password); 
     310        $pop3_response = $this->getResponse(); 
     311 
     312        if ($this->checkResponse($pop3_response)) 
     313        { 
     314          return true; 
     315        } 
     316        else 
     317        { 
     318          return false; 
     319        } 
     320      } 
     321      else 
     322      { 
     323        return false; 
     324      } 
     325    } 
     326 
     327    /** 
     328     * Disconnect from the POP3 server 
     329     */ 
     330    function Disconnect () 
     331    { 
     332      $this->sendString('QUIT'); 
     333 
     334      fclose($this->pop_conn); 
     335    } 
     336 
     337    /* 
     338      --------------- 
     339      Private Methods 
     340      --------------- 
     341    */ 
     342 
     343    /** 
     344     * Get the socket response back. 
     345     * $size is the maximum number of bytes to retrieve 
     346     * 
     347     * @param integer $size 
     348     * @return string 
     349     */ 
     350    function getResponse ($size = 128) 
     351    { 
     352      $pop3_response = fgets($this->pop_conn, $size); 
     353 
     354      return $pop3_response; 
     355    } 
     356 
     357    /** 
     358     * Send a string down the open socket connection to the POP3 server 
     359     * 
     360     * @param string $string 
     361     * @return integer 
     362     */ 
     363    function sendString ($string) 
     364    { 
     365      $bytes_sent = fwrite($this->pop_conn, $string, strlen($string)); 
     366 
     367      return $bytes_sent; 
     368 
     369    } 
     370 
     371    /** 
     372     * Checks the POP3 server response for +OK or -ERR 
     373     * 
     374     * @param string $string 
     375     * @return boolean 
     376     */ 
     377    function checkResponse ($string) 
     378    { 
     379      if (substr($string, 0, 3) !== '+OK') 
     380      { 
     381        $this->error = array( 
     382          'error' => "Server reported an error: $string", 
     383          'errno' => 0, 
     384          'errstr' => '' 
     385        ); 
     386 
     387        if ($this->do_debug >= 1) 
     388        { 
     389          $this->displayErrors(); 
     390        } 
     391 
     392        return false; 
     393      } 
     394      else 
     395      { 
    114396        return true; 
    115     } 
    116  
    117     function user ($user = "") { 
    118         // Sends the USER command, returns true or false 
    119  
    120         if( empty($user) ) { 
    121             $this->ERROR = "POP3 user: " . _("no login ID submitted"); 
    122             return false; 
    123         } elseif(!isset($this->FP)) { 
    124             $this->ERROR = "POP3 user: " . _("connection not established"); 
    125             return false; 
    126         } else { 
    127             $reply = $this->send_cmd("USER $user"); 
    128             if(!$this->is_ok($reply)) { 
    129                 $this->ERROR = "POP3 user: " . _("Error ") . "[$reply]"; 
    130                 return false; 
    131             } else 
    132                 return true; 
    133         } 
    134     } 
    135  
    136     function pass ($pass = "")     { 
    137         // Sends the PASS command, returns # of msgs in mailbox, 
    138         // returns false (undef) on Auth failure 
    139  
    140         if(empty($pass)) { 
    141             $this->ERROR = "POP3 pass: " . _("No password submitted"); 
    142             return false; 
    143         } elseif(!isset($this->FP)) { 
    144             $this->ERROR = "POP3 pass: " . _("connection not established"); 
    145             return false; 
    146         } else { 
    147             $reply = $this->send_cmd("PASS $pass"); 
    148             if(!$this->is_ok($reply)) { 
    149                 $this->ERROR = "POP3 pass: " . _("Authentication failed") . " [$reply]"; 
    150                 $this->quit(); 
    151                 return false; 
    152             } else { 
    153                 //  Auth successful. 
    154                 $count = $this->last("count"); 
    155                 $this->COUNT = $count; 
    156                 return $count; 
    157             } 
    158         } 
    159     } 
    160  
    161     function apop ($login,$pass) { 
    162         //  Attempts an APOP login. If this fails, it'll 
    163         //  try a standard login. YOUR SERVER MUST SUPPORT 
    164         //  THE USE OF THE APOP COMMAND! 
    165         //  (apop is optional per rfc1939) 
    166  
    167         if(!isset($this->FP)) { 
    168             $this->ERROR = "POP3 apop: " . _("No connection to server"); 
    169             return false; 
    170         } elseif(!$this->ALLOWAPOP) { 
    171             $retVal = $this->login($login,$pass); 
    172             return $retVal; 
    173         } elseif(empty($login)) { 
    174             $this->ERROR = "POP3 apop: " . _("No login ID submitted"); 
    175             return false; 
    176         } elseif(empty($pass)) { 
    177             $this->ERROR = "POP3 apop: " . _("No password submitted"); 
    178             return false; 
    179         } else { 
    180             $banner = $this->BANNER; 
    181             if( (!$banner) or (empty($banner)) ) { 
    182                 $this->ERROR = "POP3 apop: " . _("No server banner") . ' - ' . _("abort"); 
    183                 $retVal = $this->login($login,$pass); 
    184                 return $retVal; 
    185             } else { 
    186                 $AuthString = $banner; 
    187                 $AuthString .= $pass; 
    188                 $APOPString = md5($AuthString); 
    189                 $cmd = "APOP $login $APOPString"; 
    190                 $reply = $this->send_cmd($cmd); 
    191                 if(!$this->is_ok($reply)) { 
    192                     $this->ERROR = "POP3 apop: " . _("apop authentication failed") . ' - ' . _("abort"); 
    193                     $retVal = $this->login($login,$pass); 
    194                     return $retVal; 
    195                 } else { 
    196                     //  Auth successful. 
    197                     $count = $this->last("count"); 
    198                     $this->COUNT = $count; 
    199                     return $count; 
    200                 } 
    201             } 
    202         } 
    203     } 
    204  
    205     function login ($login = "", $pass = "") { 
    206         // Sends both user and pass. Returns # of msgs in mailbox or 
    207         // false on failure (or -1, if the error occurs while getting 
    208         // the number of messages.) 
    209  
    210         if( !isset($this->FP) ) { 
    211             $this->ERROR = "POP3 login: " . _("No connection to server"); 
    212             return false; 
    213         } else { 
    214             $fp = $this->FP; 
    215             if( !$this->user( $login ) ) { 
    216                 //  Preserve the error generated by user() 
    217                 return false; 
    218             } else { 
    219                 $count = $this->pass($pass); 
    220                 if( (!$count) || ($count == -1) ) { 
    221                     //  Preserve the error generated by last() and pass() 
    222                     return false; 
    223                 } else 
    224                     return $count; 
    225             } 
    226         } 
    227     } 
    228  
    229     function top ($msgNum, $numLines = "0") { 
    230         //  Gets the header and first $numLines of the msg body 
    231         //  returns data in an array with each returned line being 
    232         //  an array element. If $numLines is empty, returns 
    233         //  only the header information, and none of the body. 
    234  
    235         if(!isset($this->FP)) { 
    236             $this->ERROR = "POP3 top: " . _("No connection to server"); 
    237             return false; 
    238         } 
    239         $this->update_timer(); 
    240  
    241         $fp = $this->FP; 
    242         $buffer = $this->BUFFER; 
    243         $cmd = "TOP $msgNum $numLines"; 
    244         fwrite($fp, "TOP $msgNum $numLines\r\n"); 
    245         $reply = fgets($fp, $buffer); 
    246         $reply = $this->strip_clf($reply); 
    247         if($this->DEBUG) { 
    248             @error_log("POP3 SEND [$cmd] GOT [$reply]",0); 
    249         } 
    250         if(!$this->is_ok($reply)) 
    251         { 
    252             $this->ERROR = "POP3 top: " . _("Error ") . "[$reply]"; 
    253             return false; 
    254         } 
    255  
    256         $count = 0; 
    257         $MsgArray = array(); 
    258  
    259         $line = fgets($fp,$buffer); 
    260         while ( !ereg("^\.\r\n",$line)) 
    261         { 
    262             $MsgArray[$count] = $line; 
    263             $count++; 
    264             $line = fgets($fp,$buffer); 
    265             if(empty($line))    { break; } 
    266         } 
    267  
    268         return $MsgArray; 
    269     } 
    270  
    271     function pop_list ($msgNum = "") { 
    272         //  If called with an argument, returns that msgs' size in octets 
    273         //  No argument returns an associative array of undeleted 
    274         //  msg numbers and their sizes in octets 
    275  
    276         if(!isset($this->FP)) 
    277         { 
    278             $this->ERROR = "POP3 pop_list: " . _("No connection to server"); 
    279             return false; 
    280         } 
    281         $fp = $this->FP; 
    282         $Total = $this->COUNT; 
    283         if( (!$Total) or ($Total == -1) ) 
    284         { 
    285             return false; 
    286         } 
    287         if($Total == 0) 
    288         { 
    289             return array("0","0"); 
    290             // return -1;   // mailbox empty 
    291         } 
    292  
    293         $this->update_timer(); 
    294  
    295         if(!empty($msgNum)) 
    296         { 
    297             $cmd = "LIST $msgNum"; 
    298             fwrite($fp,"$cmd\r\n"); 
    299             $reply = fgets($fp,$this->BUFFER); 
    300             $reply = $this->strip_clf($reply); 
    301             if($this->DEBUG) { 
    302                 @error_log("POP3 SEND [$cmd] GOT [$reply]",0); 
    303             } 
    304             if(!$this->is_ok($reply)) 
    305             { 
    306                 $this->ERROR = "POP3 pop_list: " . _("Error ") . "[$reply]"; 
    307                 return false; 
    308             } 
    309             list($junk,$num,$size) = preg_split('/\s+/',$reply); 
    310             return $size; 
    311         } 
    312         $cmd = "LIST"; 
    313         $reply = $this->send_cmd($cmd); 
    314         if(!$this->is_ok($reply)) 
    315         { 
    316             $reply = $this->strip_clf($reply); 
    317             $this->ERROR = "POP3 pop_list: " . _("Error ") .  "[$reply]"; 
    318             return false; 
    319         } 
    320         $MsgArray = array(); 
    321         $MsgArray[0] = $Total; 
    322         for($msgC=1;$msgC <= $Total; $msgC++) 
    323         { 
    324             if($msgC > $Total) { break; } 
    325             $line = fgets($fp,$this->BUFFER); 
    326             $line = $this->strip_clf($line); 
    327             if(ereg("^\.",$line)) 
    328             { 
    329                 $this->ERROR = "POP3 pop_list: " . _("Premature end of list"); 
    330                 return false; 
    331             } 
    332             list($thisMsg,$msgSize) = preg_split('/\s+/',$line); 
    333             settype($thisMsg,"integer"); 
    334             if($thisMsg != $msgC) 
    335             { 
    336                 $MsgArray[$msgC] = "deleted"; 
    337             } 
    338             else 
    339             { 
    340                 $MsgArray[$msgC] = $msgSize; 
    341             } 
    342         } 
    343         return $MsgArray; 
    344     } 
    345  
    346     function get ($msgNum) { 
    347         //  Retrieve the specified msg number. Returns an array 
    348         //  where each line of the msg is an array element. 
    349  
    350         if(!isset($this->FP)) 
    351         { 
    352             $this->ERROR = "POP3 get: " . _("No connection to server"); 
    353             return false; 
    354         } 
    355  
    356         $this->update_timer(); 
    357  
    358         $fp = $this->FP; 
    359         $buffer = $this->BUFFER; 
    360         $cmd = "RETR $msgNum"; 
    361         $reply = $this->send_cmd($cmd); 
    362  
    363         if(!$this->is_ok($reply)) 
    364         { 
    365             $this->ERROR = "POP3 get: " . _("Error ") . "[$reply]"; 
    366             return false; 
    367         } 
    368  
    369         $count = 0; 
    370         $MsgArray = array(); 
    371  
    372         $line = fgets($fp,$buffer); 
    373         while ( !ereg("^\.\r\n",$line)) 
    374         { 
    375             if ( $line{0} == '.' ) { $line = substr($line,1); } 
    376             $MsgArray[$count] = $line; 
    377             $count++; 
    378             $line = fgets($fp,$buffer); 
    379             if(empty($line))    { break; } 
    380         } 
    381         return $MsgArray; 
    382     } 
    383  
    384     function last ( $type = "count" ) { 
    385         //  Returns the highest msg number in the mailbox. 
    386         //  returns -1 on error, 0+ on success, if type != count 
    387         //  results in a popstat() call (2 element array returned) 
    388  
    389         $last = -1; 
    390         if(!isset($this->FP)) 
    391         { 
    392             $this->ERROR = "POP3 last: " . _("No connection to server"); 
    393             return $last; 
    394         } 
    395  
    396         $reply = $this->send_cmd("STAT"); 
    397         if(!$this->is_ok($reply)) 
    398         { 
    399             $this->ERROR = "POP3 last: " . _("Error ") . "[$reply]"; 
    400             return $last; 
    401         } 
    402  
    403         $Vars = preg_split('/\s+/',$reply); 
    404         $count = $Vars[1]; 
    405         $size = $Vars[2]; 
    406         settype($count,"integer"); 
    407         settype($size,"integer"); 
    408         if($type != "count") 
    409         { 
    410             return array($count,$size); 
    411         } 
    412         return $count; 
    413     } 
    414  
    415     function reset () { 
    416         //  Resets the status of the remote server. This includes 
    417         //  resetting the status of ALL msgs to not be deleted. 
    418         //  This method automatically closes the connection to the server. 
    419  
    420         if(!isset($this->FP)) 
    421         { 
    422             $this->ERROR = "POP3 reset: " . _("No connection to server"); 
    423             return false; 
    424         } 
    425         $reply = $this->send_cmd("RSET"); 
    426         if(!$this->is_ok($reply)) 
    427         { 
    428             //  The POP3 RSET command -never- gives a -ERR 
    429             //  response - if it ever does, something truely 
    430             //  wild is going on. 
    431  
    432             $this->ERROR = "POP3 reset: " . _("Error ") . "[$reply]"; 
    433             @error_log("POP3 reset: ERROR [$reply]",0); 
    434         } 
    435         $this->quit(); 
    436         return true; 
    437     } 
    438  
    439     function send_cmd ( $cmd = "" ) 
    440     { 
    441         //  Sends a user defined command string to the 
    442         //  POP server and returns the results. Useful for 
    443         //  non-compliant or custom POP servers. 
    444         //  Do NOT includ the \r\n as part of your command 
    445         //  string - it will be appended automatically. 
    446  
    447         //  The return value is a standard fgets() call, which 
    448         //  will read up to $this->BUFFER bytes of data, until it 
    449         //  encounters a new line, or EOF, whichever happens first. 
    450  
    451         //  This method works best if $cmd responds with only 
    452         //  one line of data. 
    453  
    454         if(!isset($this->FP)) 
    455         { 
    456             $this->ERROR = "POP3 send_cmd: " . _("No connection to server"); 
    457             return false; 
    458         } 
    459  
    460         if(empty($cmd)) 
    461         { 
    462             $this->ERROR = "POP3 send_cmd: " . _("Empty command string"); 
    463             return ""; 
    464         } 
    465  
    466         $fp = $this->FP; 
    467         $buffer = $this->BUFFER; 
    468         $this->update_timer(); 
    469         fwrite($fp,"$cmd\r\n"); 
    470         $reply = fgets($fp,$buffer); 
    471         $reply = $this->strip_clf($reply); 
    472         if($this->DEBUG) { @error_log("POP3 SEND [$cmd] GOT [$reply]",0); } 
    473         return $reply; 
    474     } 
    475  
    476     function quit() { 
    477         //  Closes the connection to the POP3 server, deleting 
    478         //  any msgs marked as deleted. 
    479  
    480         if(!isset($this->FP)) 
    481         { 
    482             $this->ERROR = "POP3 quit: " . _("connection does not exist"); 
    483             return false; 
    484         } 
    485         $fp = $this->FP; 
    486         $cmd = "QUIT"; 
    487         fwrite($fp,"$cmd\r\n"); 
    488         $reply = fgets($fp,$this->BUFFER); 
    489         $reply = $this->strip_clf($reply); 
    490         if($this->DEBUG) { @error_log("POP3 SEND [$cmd] GOT [$reply]",0); } 
    491         fclose($fp); 
    492         unset($this->FP); 
    493         return true; 
    494     } 
    495  
    496     function popstat () { 
    497         //  Returns an array of 2 elements. The number of undeleted 
    498         //  msgs in the mailbox, and the size of the mbox in octets. 
    499  
    500         $PopArray = $this->last("array"); 
    501  
    502         if($PopArray == -1) { return false; } 
    503  
    504         if( (!$PopArray) or (empty($PopArray)) ) 
    505         { 
    506             return false; 
    507         } 
    508         return $PopArray; 
    509     } 
    510  
    511     function uidl ($msgNum = "") 
    512     { 
    513         //  Returns the UIDL of the msg specified. If called with 
    514         //  no arguments, returns an associative array where each 
    515         //  undeleted msg num is a key, and the msg's uidl is the element 
    516         //  Array element 0 will contain the total number of msgs 
    517  
    518         if(!isset($this->FP)) { 
    519             $this->ERROR = "POP3 uidl: " . _("No connection to server"); 
    520             return false; 
    521         } 
    522  
    523         $fp = $this->FP; 
    524         $buffer = $this->BUFFER; 
    525  
    526         if(!empty($msgNum)) { 
    527             $cmd = "UIDL $msgNum"; 
    528             $reply = $this->send_cmd($cmd); 
    529             if(!$this->is_ok($reply)) 
    530             { 
    531                 $this->ERROR = "POP3 uidl: " . _("Error ") . "[$reply]"; 
    532                 return false; 
    533             } 
    534             list ($ok,$num,$myUidl) = preg_split('/\s+/',$reply); 
    535             return $myUidl; 
    536         } else { 
    537             $this->update_timer(); 
    538  
    539             $UIDLArray = array(); 
    540             $Total = $this->COUNT; 
    541             $UIDLArray[0] = $Total; 
    542  
    543             if ($Total < 1) 
    544             { 
    545                 return $UIDLArray; 
    546             } 
    547             $cmd = "UIDL"; 
    548             fwrite($fp, "UIDL\r\n"); 
    549             $reply = fgets($fp, $buffer); 
    550             $reply = $this->strip_clf($reply); 
    551             if($this->DEBUG) { @error_log("POP3 SEND [$cmd] GOT [$reply]",0); } 
    552             if(!$this->is_ok($reply)) 
    553             { 
    554                 $this->ERROR = "POP3 uidl: " . _("Error ") . "[$reply]"; 
    555                 return false; 
    556             } 
    557  
    558             $line = ""; 
    559             $count = 1; 
    560             $line = fgets($fp,$buffer); 
    561             while ( !ereg("^\.\r\n",$line)) { 
    562                 if(ereg("^\.\r\n",$line)) { 
    563                     break; 
    564                 } 
    565                 list ($msg,$msgUidl) = preg_split('/\s+/',$line); 
    566                 $msgUidl = $this->strip_clf($msgUidl); 
    567                 if($count == $msg) { 
    568                     $UIDLArray[$msg] = $msgUidl; 
    569                 } 
    570                 else 
    571                 { 
    572                     $UIDLArray[$count] = 'deleted'; 
    573                 } 
    574                 $count++; 
    575                 $line = fgets($fp,$buffer); 
    576             } 
    577         } 
    578         return $UIDLArray; 
    579     } 
    580  
    581     function delete ($msgNum = "") { 
    582         //  Flags a specified msg as deleted. The msg will not 
    583         //  be deleted until a quit() method is called. 
    584  
    585         if(!isset($this->FP)) 
    586         { 
    587             $this->ERROR = "POP3 delete: " . _("No connection to server"); 
    588             return false; 
    589         } 
    590         if(empty($msgNum)) 
    591         { 
    592             $this->ERROR = "POP3 delete: " . _("No msg number submitted"); 
    593             return false; 
    594         } 
    595         $reply = $this->send_cmd("DELE $msgNum"); 
    596         if(!$this->is_ok($reply)) 
    597         { 
    598             $this->ERROR = "POP3 delete: " . _("Command failed ") . "[$reply]"; 
    599             return false; 
    600         } 
    601         return true; 
    602     } 
    603  
    604     //  ********************************************************* 
    605  
    606     //  The following methods are internal to the class. 
    607  
    608     function is_ok ($cmd = "") { 
    609         //  Return true or false on +OK or -ERR 
    610  
    611         if( empty($cmd) ) 
    612             return false; 
    613         else 
    614             return( ereg ("^\+OK", $cmd ) ); 
    615     } 
    616  
    617     function strip_clf ($text = "") { 
    618         // Strips \r\n from server responses 
    619  
    620         if(empty($text)) 
    621             return $text; 
    622         else { 
    623             $stripped = str_replace("\r",'',$text); 
    624             $stripped = str_replace("\n",'',$stripped); 
    625             return $stripped; 
    626         } 
    627     } 
    628  
    629     function parse_banner ( $server_text ) { 
    630         $outside = true; 
    631         $banner = ""; 
    632         $length = strlen($server_text); 
    633         for($count =0; $count < $length; $count++) 
    634         { 
    635             $digit = substr($server_text,$count,1); 
    636             if(!empty($digit))             { 
    637                 if( (!$outside) && ($digit != '<') && ($digit != '>') ) 
    638                 { 
    639                     $banner .= $digit; 
    640                 } 
    641                 if ($digit == '<') 
    642                 { 
    643                     $outside = false; 
    644                 } 
    645                 if($digit == '>') 
    646                 { 
    647                     $outside = true; 
    648                 } 
    649             } 
    650         } 
    651         $banner = $this->strip_clf($banner);    // Just in case 
    652         return "<$banner>"; 
    653     } 
    654  
    655 }   // End class 
     397      } 
     398 
     399    } 
     400 
     401    /** 
     402     * If debug is enabled, display the error message array 
     403     * 
     404     */ 
     405    function displayErrors () 
     406    { 
     407      echo '<pre>'; 
     408 
     409      foreach ($this->error as $single_error) 
     410    { 
     411        print_r($single_error); 
     412    } 
     413 
     414      echo '</pre>'; 
     415    } 
     416 
     417  /** 
     418   * Takes over from PHP for the socket warning handler 
     419   * 
     420   * @param integer $errno 
     421   * @param string $errstr 
     422   * @param string $errfile 
     423   * @param integer $errline 
     424   */ 
     425  function catchWarning ($errno, $errstr, $errfile, $errline) 
     426  { 
     427    $this->error[] = array( 
     428      'error' => "Connecting to the POP3 server raised a PHP warning: ", 
     429      'errno' => $errno, 
     430      'errstr' => $errstr 
     431    ); 
     432  } 
     433 
     434  //  End of class 
     435} 
    656436?> 
  • trunk/wp-includes/class-smtp.php

    r8187 r8762  
    11<?php 
    2 /** 
    3  * SMTP - PHP SMTP class 
    4  * 
    5  * Define an SMTP class that can be used to connect and communicate with any 
    6  * SMTP server. It implements all the SMTP functions defined in RFC821 except 
    7  * TURN. 
    8  * 
    9  * @version 1.02 
    10  * @author Chris Ryan 
    11  * @license LGPL 
    12  * @package PHPMailer 
    13  */ 
     2/*~ class.smtp.php 
     3.---------------------------------------------------------------------------. 
     4|  Software: PHPMailer - PHP email class                                    | 
     5|   Version: 2.0.2                                                          | 
     6|   Contact: via sourceforge.net support pages (also www.codeworxtech.com)  | 
     7|      Info: http://phpmailer.sourceforge.net                               | 
     8|   Support: http://sourceforge.net/projects/phpmailer/                     | 
     9| ------------------------------------------------------------------------- | 
     10|    Author: Andy Prevost (project admininistrator)                         | 
     11|    Author: Brent R. Matzelle (original founder)                           | 
     12| Copyright (c) 2004-2007, Andy Prevost. All Rights Reserved.               | 
     13| Copyright (c) 2001-2003, Brent R. Matzelle                                | 
     14| ------------------------------------------------------------------------- | 
     15|   License: Distributed under the Lesser General Public License (LGPL)     | 
     16|            http://www.gnu.org/copyleft/lesser.html                        | 
     17| This program is distributed in the hope that it will be useful - WITHOUT  | 
     18| ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or     | 
     19| FITNESS FOR A PARTICULAR PURPOSE.                                         | 
     20| ------------------------------------------------------------------------- | 
     21| We offer a number of paid services (www.codeworxtech.com):                | 
     22| - Web Hosting on highly optimized fast and secure servers                 | 
     23| - Technology Consulting                                                   | 
     24| - Oursourcing (highly qualified programmers and graphic designers)        | 
     25'---------------------------------------------------------------------------' 
    1426 
    1527/** 
     
    1830 * error. SMTP also provides some utility methods for sending mail 
    1931 * to an SMTP server. 
    20  * 
    2132 * @package PHPMailer 
    2233 * @author Chris Ryan 
    2334 */ 
     35 
    2436class SMTP 
    2537{ 
    26     /** 
    27      *  SMTP server port 
    28      *  @var int 
    29      */ 
    30     var $SMTP_PORT = 25; 
    31  
    32     /** 
    33      *  SMTP reply line ending 
    34      *  @var string 
    35      */ 
    36     var $CRLF = "\r\n"; 
    37  
    38     /** 
    39      *  Sets whether debugging is turned on 
    40      *  @var bool 
    41      */ 
    42     var $do_debug;       # the level of debug to perform 
    43  
    44     /**#@+ 
    45      * @access private 
    46      */ 
    47     var $smtp_conn;      # the socket to the server 
    48     var $error;          # error if any on the last call 
    49     var $helo_rply;      # the reply the server sent to us for HELO 
    50     /**#@-*/ 
    51  
    52     /** 
    53      * Initialize the class so that the data is in a known state. 
    54      * @access public 
    55      * @return void 
    56      */ 
    57     function SMTP() { 
    58         $this->smtp_conn = 0; 
    59         $this->error = null; 
    60         $this->helo_rply = null; 
    61  
    62         $this->do_debug = 0; 
    63     } 
    64  
    65     /************************************************************* 
    66      *                    CONNECTION FUNCTIONS                  * 
    67      ***********************************************************/ 
    68  
    69     /** 
    70      * Connect to the server specified on the port specified. 
    71      * If the port is not specified use the default SMTP_PORT. 
    72      * If tval is specified then a connection will try and be 
    73      * established with the server for that number of seconds. 
    74      * If tval is not specified the default is 30 seconds to 
    75      * try on the connection. 
    76      * 
    77      * SMTP CODE SUCCESS: 220 
    78      * SMTP CODE FAILURE: 421 
    79      * @access public 
    80      * @return bool 
    81      */ 
    82     function Connect($host,$port=0,$tval=30) { 
    83         # set the error val to null so there is no confusion 
    84         $this->error = null; 
    85  
    86         # make sure we are __not__ connected 
    87         if($this->connected()) { 
    88             # ok we are connected! what should we do? 
    89             # for now we will just give an error saying we 
    90             # are already connected 
    91             $this->error = 
    92                 array("error" => "Already connected to a server"); 
    93             return false; 
     38  /** 
     39   *  SMTP server port 
     40   *  @var int 
     41   */ 
     42  var $SMTP_PORT = 25; 
     43 
     44  /** 
     45   *  SMTP reply line ending 
     46   *  @var string 
     47   */ 
     48  var $CRLF = "\r\n"; 
     49 
     50  /** 
     51   *  Sets whether debugging is turned on 
     52   *  @var bool 
     53   */ 
     54  var $do_debug;       # the level of debug to perform 
     55 
     56  /** 
     57   *  Sets VERP use on/off (default is off) 
     58   *  @var bool 
     59   */ 
     60  var $do_verp = false; 
     61 
     62  /**#@+ 
     63   * @access private 
     64   */ 
     65  var $smtp_conn;      # the socket to the server 
     66  var $error;          # error if any on the last call 
     67  var $helo_rply;      # the reply the server sent to us for HELO 
     68  /**#@-*/ 
     69 
     70  /** 
     71   * Initialize the class so that the data is in a known state. 
     72   * @access public 
     73   * @return void 
     74   */ 
     75  function SMTP() { 
     76    $this->smtp_conn = 0; 
     77    $this->error = null; 
     78    $this->helo_rply = null; 
     79 
     80    $this->do_debug = 0; 
     81  } 
     82 
     83  /************************************************************* 
     84   *                    CONNECTION FUNCTIONS                  * 
     85   ***********************************************************/ 
     86 
     87  /** 
     88   * Connect to the server specified on the port specified. 
     89   * If the port is not specified use the default SMTP_PORT. 
     90   * If tval is specified then a connection will try and be 
     91   * established with the server for that number of seconds. 
     92   * If tval is not specified the default is 30 seconds to 
     93   * try on the connection. 
     94   * 
     95   * SMTP CODE SUCCESS: 220 
     96   * SMTP CODE FAILURE: 421 
     97   * @access public 
     98   * @return bool 
     99   */ 
     100  function Connect($host,$port=0,$tval=30) { 
     101    # set the error val to null so there is no confusion 
     102    $this->error = null; 
     103 
     104    # make sure we are __not__ connected 
     105    if($this->connected()) { 
     106      # ok we are connected! what should we do? 
     107      # for now we will just give an error saying we 
     108      # are already connected 
     109      $this->error = array("error" => "Already connected to a server"); 
     110      return false; 
     111    } 
     112 
     113    if(empty($port)) { 
     114      $port = $this->SMTP_PORT; 
     115    } 
     116 
     117    #connect to the smtp server 
     118    $this->smtp_conn = fsockopen($host,    # the host of the server 
     119                                 $port,    # the port to use 
     120                                 $errno,   # error number if any 
     121                                 $errstr,  # error message if any 
     122                                 $tval);   # give up after ? secs 
     123    # verify we connected properly 
     124    if(empty($this->smtp_conn)) { 
     125      $this->error = array("error" => "Failed to connect to server", 
     126                           "errno" => $errno, 
     127                           "errstr" => $errstr); 
     128      if($this->do_debug >= 1) { 
     129        echo "SMTP -> ERROR: " . $this->error["error"] . 
     130                 ": $errstr ($errno)" . $this->CRLF; 
     131      } 
     132      return false; 
     133    } 
     134 
     135    # sometimes the SMTP server takes a little longer to respond 
     136    # so we will give it a longer timeout for the first read 
     137    // Windows still does not have support for this timeout function 
     138    if(substr(PHP_OS, 0, 3) != "WIN") 
     139     socket_set_timeout($this->smtp_conn, $tval, 0); 
     140 
     141    # get any announcement stuff 
     142    $announce = $this->get_lines(); 
     143 
     144    # set the timeout  of any socket functions at 1/10 of a second 
     145    //if(function_exists("socket_set_timeout")) 
     146    //   socket_set_timeout($this->smtp_conn, 0, 100000); 
     147 
     148    if($this->do_debug >= 2) { 
     149      echo "SMTP -> FROM SERVER:" . $this->CRLF . $announce; 
     150    } 
     151 
     152    return true; 
     153  } 
     154 
     155  /** 
     156   * Performs SMTP authentication.  Must be run after running the 
     157   * Hello() method.  Returns true if successfully authenticated. 
     158   * @access public 
     159   * @return bool 
     160   */ 
     161  function Authenticate($username, $password) { 
     162    // Start authentication 
     163    fputs($this->smtp_conn,"AUTH LOGIN" . $this->CRLF); 
     164 
     165    $rply = $this->get_lines(); 
     166    $code = substr($rply,0,3); 
     167 
     168    if($code != 334) { 
     169      $this->error = 
     170        array("error" => "AUTH not accepted from server", 
     171              "smtp_code" => $code, 
     172              "smtp_msg" => substr($rply,4)); 
     173      if($this->do_debug >= 1) { 
     174        echo "SMTP -> ERROR: " . $this->error["error"] . 
     175                 ": " . $rply . $this->CRLF; 
     176      } 
     177      return false; 
     178    } 
     179 
     180    // Send encoded username 
     181    fputs($this->smtp_conn, base64_encode($username) . $this->CRLF); 
     182 
     183    $rply = $this->get_lines(); 
     184    $code = substr($rply,0,3); 
     185 
     186    if($code != 334) { 
     187      $this->error = 
     188        array("error" => "Username not accepted from server", 
     189              "smtp_code" => $code, 
     190              "smtp_msg" => substr($rply,4)); 
     191      if($this->do_debug >= 1) { 
     192        echo "SMTP -> ERROR: " . $this->error["error"] . 
     193                 ": " . $rply . $this->CRLF; 
     194      } 
     195      return false; 
     196    } 
     197 
     198    // Send encoded password 
     199    fputs($this->smtp_conn, base64_encode($password) . $this->CRLF); 
     200 
     201    $rply = $this->get_lines(); 
     202    $code = substr($rply,0,3); 
     203 
     204    if($code != 235) { 
     205      $this->error = 
     206        array("error" => "Password not accepted from server", 
     207              "smtp_code" => $code, 
     208              "smtp_msg" => substr($rply,4)); 
     209      if($this->do_debug >= 1) { 
     210        echo "SMTP -> ERROR: " . $this->error["error"] . 
     211                 ": " . $rply . $this->CRLF; 
     212      } 
     213      return false; 
     214    } 
     215 
     216    return true; 
     217  } 
     218 
     219  /** 
     220   * Returns true if connected to a server otherwise false 
     221   * @access private 
     222   * @return bool 
     223   */ 
     224  function Connected() { 
     225    if(!empty($this->smtp_conn)) { 
     226      $sock_status = socket_get_status($this->smtp_conn); 
     227      if($sock_status["eof"]) { 
     228        # hmm this is an odd situation... the socket is 
     229        # valid but we are not connected anymore 
     230        if($this->do_debug >= 1) { 
     231            echo "SMTP -> NOTICE:" . $this->CRLF . 
     232                 "EOF caught while checking if connected"; 
    94233        } 
    95  
    96         if(empty($port)) { 
    97             $port = $this->SMTP_PORT; 
     234        $this->Close(); 
     235        return false; 
     236      } 
     237      return true; # everything looks good 
     238    } 
     239    return false; 
     240  } 
     241 
     242  /** 
     243   * Closes the socket and cleans up the state of the class. 
     244   * It is not considered good to use this function without 
     245   * first trying to use QUIT. 
     246   * @access public 
     247   * @return void 
     248   */ 
     249  function Close() { 
     250    $this->error = null; # so there is no confusion 
     251    $this->helo_rply = null; 
     252    if(!empty($this->smtp_conn)) { 
     253      # close the connection and cleanup 
     254      fclose($this->smtp_conn); 
     255      $this->smtp_conn = 0; 
     256    } 
     257  } 
     258 
     259  /*************************************************************** 
     260   *                        SMTP COMMANDS                       * 
     261   *************************************************************/ 
     262 
     263  /** 
     264   * Issues a data command and sends the msg_data to the server 
     265   * finializing the mail transaction. $msg_data is the message 
     266   * that is to be send with the headers. Each header needs to be 
     267   * on a single line followed by a <CRLF> with the message headers 
     268   * and the message body being seperated by and additional <CRLF>. 
     269   * 
     270   * Implements rfc 821: DATA <CRLF> 
     271   * 
     272   * SMTP CODE INTERMEDIATE: 354 
     273   *     [data] 
     274   *     <CRLF>.<CRLF> 
     275   *     SMTP CODE SUCCESS: 250 
     276   *     SMTP CODE FAILURE: 552,554,451,452 
     277   * SMTP CODE FAILURE: 451,554 
     278   * SMTP CODE ERROR  : 500,501,503,421 
     279   * @access public 
     280   * @return bool 
     281   */ 
     282  function Data($msg_data) { 
     283    $this->error = null; # so no confusion is caused 
     284 
     285    if(!$this->connected()) { 
     286      $this->error = array( 
     287              "error" => "Called Data() without being connected"); 
     288      return false; 
     289    } 
     290 
     291    fputs($this->smtp_conn,"DATA" . $this->CRLF); 
     292 
     293    $rply = $this->get_lines(); 
     294    $code = substr($rply,0,3); 
     295 
     296    if($this->do_debug >= 2) { 
     297      echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; 
     298    } 
     299 
     300    if($code != 354) { 
     301      $this->error = 
     302        array("error" => "DATA command not accepted from server", 
     303              "smtp_code" => $code, 
     304              "smtp_msg" => substr($rply,4)); 
     305      if($this->do_debug >= 1) { 
     306        echo "SMTP -> ERROR: " . $this->error["error"] . 
     307                 ": " . $rply . $this->CRLF; 
     308      } 
     309      return false; 
     310    } 
     311 
     312    # the server is ready to accept data! 
     313    # according to rfc 821 we should not send more than 1000 
     314    # including the CRLF 
     315    # characters on a single line so we will break the data up 
     316    # into lines by \r and/or \n then if needed we will break 
     317    # each of those into smaller lines to fit within the limit. 
     318    # in addition we will be looking for lines that start with 
     319    # a period '.' and append and additional period '.' to that 
     320    # line. NOTE: this does not count towards are limit. 
     321 
     322    # normalize the line breaks so we know the explode works 
     323    $msg_data = str_replace("\r\n","\n",$msg_data); 
     324    $msg_data = str_replace("\r","\n",$msg_data); 
     325    $lines = explode("\n",$msg_data); 
     326 
     327    # we need to find a good way to determine is headers are 
     328    # in the msg_data or if it is a straight msg body 
     329    # currently I am assuming rfc 822 definitions of msg headers 
     330    # and if the first field of the first line (':' sperated) 
     331    # does not contain a space then it _should_ be a header 
     332    # and we can process all lines before a blank "" line as 
     333    # headers. 
     334    $field = substr($lines[0],0,strpos($lines[0],":")); 
     335    $in_headers = false; 
     336    if(!empty($field) && !strstr($field," ")) { 
     337      $in_headers = true; 
     338    } 
     339 
     340    $max_line_length = 998; # used below; set here for ease in change 
     341 
     342    while(list(,$line) = @each($lines)) { 
     343      $lines_out = null; 
     344      if($line == "" && $in_headers) { 
     345        $in_headers = false; 
     346      } 
     347      # ok we need to break this line up into several 
     348      # smaller lines 
     349      while(strlen($line) > $max_line_length) { 
     350        $pos = strrpos(substr($line,0,$max_line_length)," "); 
     351 
     352        # Patch to fix DOS attack 
     353        if(!$pos) { 
     354          $pos = $max_line_length - 1; 
    98355        } 
    99356 
    100         #connect to the smtp server 
    101         $this->smtp_conn = fsockopen($host,    # the host of the server 
    102                                      $port,    # the port to use 
    103                                      $errno,   # error number if any 
    104                                      $errstr,  # error message if any 
    105                                      $tval);   # give up after ? secs 
    106         # verify we connected properly 
    107         if(empty($this->smtp_conn)) { 
    108             $this->error = array("error" => "Failed to connect to server", 
    109                                  "errno" => $errno, 
    110                                  "errstr" => $errstr); 
    111             if($this->do_debug >= 1) { 
    112                 echo "SMTP -> ERROR: " . $this->error["error"] . 
    113                          ": $errstr ($errno)" . $this->CRLF; 
    114             } 
    115             return false; 
     357        $lines_out[] = substr($line,0,$pos); 
     358        $line = substr($line,$pos + 1); 
     359        # if we are processing headers we need to 
     360        # add a LWSP-char to the front of the new line 
     361        # rfc 822 on long msg headers 
     362        if($in_headers) { 
     363          $line = "\t" . $line; 
    116364        } 
    117  
    118         # sometimes the SMTP server takes a little longer to respond 
    119         # so we will give it a longer timeout for the first read 
    120         // Windows still does not have support for this timeout function 
    121         if(substr(PHP_OS, 0, 3) != "WIN") 
    122            socket_set_timeout($this->smtp_conn, $tval, 0); 
    123  
    124         # get any announcement stuff 
    125         $announce = $this->get_lines(); 
    126  
    127         # set the timeout  of any socket functions at 1/10 of a second 
    128         //if(function_exists("socket_set_timeout")) 
    129         //   socket_set_timeout($this->smtp_conn, 0, 100000); 
    130  
    131         if($this->do_debug >= 2) { 
    132             echo "SMTP -> FROM SERVER:" . $this->CRLF . $announce; 
     365      } 
     366      $lines_out[] = $line; 
     367 
     368      # now send the lines to the server 
     369      while(list(,$line_out) = @each($lines_out)) { 
     370        if(strlen($line_out) > 0) 
     371        { 
     372          if(substr($line_out, 0, 1) == ".") { 
     373            $line_out = "." . $line_out; 
     374          } 
    133375        } 
    134  
    135         return true; 
    136     } 
    137  
    138     /** 
    139      * Performs SMTP authentication.  Must be run after running the 
    140      * Hello() method.  Returns true if successfully authenticated. 
    141      * @access public 
    142      * @return bool 
    143      */ 
    144     function Authenticate($username, $password) { 
    145         // Start authentication 
    146         fputs($this->smtp_conn,"AUTH LOGIN" . $this->CRLF); 
    147  
    148         $rply = $this->get_lines(); 
    149         $code = substr($rply,0,3); 
    150  
    151         if($code != 334) { 
    152             $this->error = 
    153                 array("error" => "AUTH not accepted from server", 
    154                       "smtp_code" => $code, 
    155                       "smtp_msg" => substr($rply,4)); 
    156             if($this->do_debug >= 1) { 
    157                 echo "SMTP -> ERROR: " . $this->error["error"] . 
    158                          ": " . $rply . $this->CRLF; 
    159             } 
    160             return false; 
    161         } 
    162  
    163         // Send encoded username 
    164         fputs($this->smtp_conn, base64_encode($username) . $this->CRLF); 
    165  
    166         $rply = $this->get_lines(); 
    167         $code = substr($rply,0,3); 
    168  
    169         if($code != 334) { 
    170             $this->error = 
    171                 array("error" => "Username not accepted from server", 
    172                       "smtp_code" => $code, 
    173                       "smtp_msg" => substr($rply,4)); 
    174             if($this->do_debug >= 1) { 
    175                 echo "SMTP -> ERROR: " . $this->error["error"] . 
    176                          ": " . $rply . $this->CRLF; 
    177             } 
    178             return false; 
    179         } 
    180  
    181         // Send encoded password 
    182         fputs($this->smtp_conn, base64_encode($password) . $this->CRLF); 
    183  
    184         $rply = $this->get_lines(); 
    185         $code = substr($rply,0,3); 
    186  
    187         if($code != 235) { 
    188             $this->error = 
    189                 array("error" => "Password not accepted from server", 
    190                       "smtp_code" => $code, 
    191                       "smtp_msg" => substr($rply,4)); 
    192             if($this->do_debug >= 1) { 
    193                 echo "SMTP -> ERROR: " . $this->error["error"] . 
    194                          ": " . $rply . $this->CRLF; 
    195             } 
    196             return false; 
    197         } 
    198  
    199         return true; 
    200     } 
    201  
    202     /** 
    203      * Returns true if connected to a server otherwise false 
    204      * @access private 
    205      * @return bool 
    206      */ 
    207     function Connected() { 
    208         if(!empty($this->smtp_conn)) { 
    209             $sock_status = socket_get_status($this->smtp_conn); 
    210             if($sock_status["eof"]) { 
    211                 # hmm this is an odd situation... the socket is 
    212                 # valid but we aren't connected anymore 
    213                 if($this->do_debug >= 1) { 
    214                     echo "SMTP -> NOTICE:" . $this->CRLF . 
    215                          "EOF caught while checking if connected"; 
    216                 } 
    217                 $this->Close(); 
    218                 return false; 
    219             } 
    220             return true; # everything looks good 
    221         } 
    222         return false; 
    223     } 
    224  
    225     /** 
    226      * Closes the socket and cleans up the state of the class. 
    227      * It is not considered good to use this function without 
    228      * first trying to use QUIT. 
    229      * @access public 
    230      * @return void 
    231      */ 
    232     function Close() { 
    233         $this->error = null; # so there is no confusion 
    234         $this->helo_rply = null; 
    235         if(!empty($this->smtp_conn)) { 
    236             # close the connection and cleanup 
    237             fclose($this->smtp_conn); 
    238             $this->smtp_conn = 0; 
    239         } 
    240     } 
    241  
    242  
    243     /*************************************************************** 
    244      *                        SMTP COMMANDS                       * 
    245      *************************************************************/ 
    246  
    247     /** 
    248      * Issues a data command and sends the msg_data to the server 
    249      * finializing the mail transaction. $msg_data is the message 
    250      * that is to be send with the headers. Each header needs to be 
    251      * on a single line followed by a <CRLF> with the message headers 
    252      * and the message body being separated by and additional <CRLF>. 
    253      * 
    254      * Implements rfc 821: DATA <CRLF> 
    255      * 
    256      * SMTP CODE INTERMEDIATE: 354 
    257      *     [data] 
    258      *     <CRLF>.<CRLF> 
    259      *     SMTP CODE SUCCESS: 250 
    260      *     SMTP CODE FAILURE: 552,554,451,452 
    261      * SMTP CODE FAILURE: 451,554 
    262      * SMTP CODE ERROR  : 500,501,503,421 
    263      * @access public 
    264      * @return bool 
    265      */ 
    266     function Data($msg_data) { 
    267         $this->error = null; # so no confusion is caused 
    268  
    269         if(!$this->connected()) { 
    270             $this->error = array( 
    271                     "error" => "Called Data() without being connected"); 
    272             return false; 
    273         } 
    274  
    275         fputs($this->smtp_conn,"DATA" . $this->CRLF); 
    276  
    277         $rply = $this->get_lines(); 
    278         $code = substr($rply,0,3); 
    279  
    280         if($this->do_debug >= 2) { 
    281             echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; 
    282         } 
    283  
    284         if($code != 354) { 
    285             $this->error = 
    286                 array("error" => "DATA command not accepted from server", 
    287                       "smtp_code" => $code, 
    288                       "smtp_msg" => substr($rply,4)); 
    289             if($this->do_debug >= 1) { 
    290                 echo "SMTP -> ERROR: " . $this->error["error"] . 
    291                          ": " . $rply . $this->CRLF; 
    292             } 
    293             return false; 
    294         } 
    295  
    296         # the server is ready to accept data! 
    297         # according to rfc 821 we should not send more than 1000 
    298         # including the CRLF 
    299         # characters on a single line so we will break the data up 
    300         # into lines by \r and/or \n then if needed we will break 
    301         # each of those into smaller lines to fit within the limit. 
    302         # in addition we will be looking for lines that start with 
    303         # a period '.' and append and additional period '.' to that 
    304         # line. NOTE: this does not count towards are limit. 
    305  
    306         # normalize the line breaks so we know the explode works 
    307         $msg_data = str_replace("\r\n","\n",$msg_data); 
    308         $msg_data = str_replace("\r","\n",$msg_data); 
    309         $lines = explode("\n",$msg_data); 
    310  
    311         # we need to find a good way to determine is headers are 
    312         # in the msg_data or if it is a straight msg body 
    313         # currently I'm assuming rfc 822 definitions of msg headers 
    314         # and if the first field of the first line (':' sperated) 
    315         # does not contain a space then it _should_ be a header 
    316         # and we can process all lines before a blank "" line as 
    317         # headers. 
    318         $field = substr($lines[0],0,strpos($lines[0],":")); 
    319         $in_headers = false; 
    320         if(!empty($field) && !strstr($field," ")) { 
    321             $in_headers = true; 
    322         } 
    323  
    324         $max_line_length = 998; # used below; set here for ease in change 
    325  
    326         while(list(,$line) = @each($lines)) { 
    327             $lines_out = null; 
    328             if($line == "" && $in_headers) { 
    329                 $in_headers = false; 
    330             } 
    331             # ok we need to break this line up into several 
    332             # smaller lines 
    333             while(strlen($line) > $max_line_length) { 
    334                 $pos = strrpos(substr($line,0,$max_line_length)," "); 
    335  
    336                 # Patch to fix DOS attack 
    337                 if(!$pos) { 
    338                     $pos = $max_line_length - 1; 
    339                 } 
    340  
    341                 $lines_out[] = substr($line,0,$pos); 
    342                 $line = substr($line,$pos + 1); 
    343                 # if we are processing headers we need to 
    344                 # add a LWSP-char to the front of the new line 
    345                 # rfc 822 on long msg headers 
    346                 if($in_headers) { 
    347                     $line = "\t" . $line; 
    348                 } 
    349             } 
    350             $lines_out[] = $line; 
    351  
    352             # now send the lines to the server 
    353             while(list(,$line_out) = @each($lines_out)) { 
    354                 if(strlen($line_out) > 0) 
    355                 { 
    356                     if(substr($line_out, 0, 1) == ".") { 
    357                         $line_out = "." . $line_out; 
    358                     } 
    359                 } 
    360                 fputs($this->smtp_conn,$line_out . $this->CRLF); 
    361             } 
    362         } 
    363  
    364         # ok all the message data has been sent so lets get this 
    365         # over with aleady 
    366         fputs($this->smtp_conn, $this->CRLF . "." . $this->CRLF); 
    367  
    368         $rply = $this->get_lines(); 
    369         $code = substr($rply,0,3); 
    370  
    371         if($this->do_debug >= 2) { 
    372             echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; 
    373         } 
    374  
    375         if($code != 250) { 
    376             $this->error = 
    377                 array("error" => "DATA not accepted from server", 
    378                       "smtp_code" => $code, 
    379                       "smtp_msg" => substr($rply,4)); 
    380             if($this->do_debug >= 1) { 
    381                 echo "SMTP -> ERROR: " . $this->error["error"] . 
    382                          ": " . $rply . $this->CRLF; 
    383             } 
    384             return false; 
    385         } 
    386         return true; 
    387     } 
    388  
    389     /** 
    390      * Expand takes the name and asks the server to list all the 
    391      * people who are members of the _list_. Expand will return 
    392      * back and array of the result or false if an error occurs. 
    393      * Each value in the array returned has the format of: 
    394      *     [ <full-name> <sp> ] <path> 
    395      * The definition of <path> is defined in rfc 821 
    396      * 
    397      * Implements rfc 821: EXPN <SP> <string> <CRLF> 
    398      * 
    399      * SMTP CODE SUCCESS: 250 
    400      * SMTP CODE FAILURE: 550 
    401      * SMTP CODE ERROR  : 500,501,502,504,421 
    402      * @access public 
    403      * @return string array 
    404      */ 
    405     function Expand($name) { 
    406         $this->error = null; # so no confusion is caused 
    407  
    408         if(!$this->connected()) { 
    409             $this->error = array( 
    410                     "error" => "Called Expand() without being connected"); 
    411             return false; 
    412         } 
    413  
    414         fputs($this->smtp_conn,"EXPN " . $name . $this->CRLF); 
    415  
    416         $rply = $this->get_lines(); 
    417         $code = substr($rply,0,3); 
    418  
    419         if($this->do_debug >= 2) { 
    420             echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; 
    421         } 
    422  
    423         if($code != 250) { 
    424             $this->error = 
    425                 array("error" => "EXPN not accepted from server", 
    426                       "smtp_code" => $code, 
    427                       "smtp_msg" => substr($rply,4)); 
    428             if($this->do_debug >= 1) { 
    429                 echo "SMTP -> ERROR: " . $this->error["error"] . 
    430                          ": " . $rply . $this->CRLF; 
    431             } 
    432             return false; 
    433         } 
    434  
    435         # parse the reply and place in our array to return to user 
    436         $entries = explode($this->CRLF,$rply); 
    437         while(list(,$l) = @each($entries)) { 
    438             $list[] = substr($l,4); 
    439         } 
    440  
    441         return $list; 
    442     } 
    443  
    444     /** 
    445      * Sends the HELO command to the smtp server. 
    446      * This makes sure that we and the server are in 
    447      * the same known state. 
    448      * 
    449      * Implements from rfc 821: HELO <SP> <domain> <CRLF> 
    450      * 
    451      * SMTP CODE SUCCESS: 250 
    452      * SMTP CODE ERROR  : 500, 501, 504, 421 
    453      * @access public 
    454      * @return bool 
    455      */ 
    456     function Hello($host="") { 
    457         $this->error = null; # so no confusion is caused 
    458  
    459         if(!$this->connected()) { 
    460             $this->error = array( 
    461                     "error" => "Called Hello() without being connected"); 
    462             return false; 
    463         } 
    464  
    465         # if a hostname for the HELO wasn't specified determine 
    466         # a suitable one to send 
    467         if(empty($host)) { 
    468             # we need to determine some sort of appopiate default 
    469             # to send to the server 
    470             $host = "localhost"; 
    471         } 
    472  
    473         // Send extended hello first (RFC 2821) 
    474         if(!$this->SendHello("EHLO", $host)) 
    475         { 
    476             if(!$this->SendHello("HELO", $host)) 
    477                 return false; 
    478         } 
    479  
    480         return true; 
    481     } 
    482  
    483     /** 
    484      * Sends a HELO/EHLO command. 
    485      * @access private 
    486      * @return bool 
    487      */ 
    488     function SendHello($hello, $host) { 
    489         fputs($this->smtp_conn, $hello . " " . $host . $this->CRLF); 
    490  
    491         $rply = $this->get_lines(); 
    492         $code = substr($rply,0,3); 
    493  
    494         if($this->do_debug >= 2) { 
    495             echo "SMTP -> FROM SERVER: " . $this->CRLF . $rply; 
    496         } 
    497  
    498         if($code != 250) { 
    499             $this->error = 
    500                 array("error" => $hello . " not accepted from server", 
    501                       "smtp_code" => $code, 
    502                       "smtp_msg" => substr($rply,4)); 
    503             if($this->do_debug >= 1) { 
    504                 echo "SMTP -> ERROR: " . $this->error["error"] . 
    505                          ": " . $rply . $this->CRLF; 
    506             } 
    507             return false; 
    508         } 
    509  
    510         $this->helo_rply = $rply; 
    511  
    512         return true; 
    513     } 
    514  
    515     /** 
    516      * Gets help information on the keyword specified. If the keyword 
    517      * is not specified then returns generic help, ussually contianing 
    518      * A list of keywords that help is available on. This function 
    519      * returns the results back to the user. It is up to the user to 
    520      * handle the returned data. If an error occurs then false is 
    521      * returned with $this->error set appropiately. 
    522      * 
    523      * Implements rfc 821: HELP [ <SP> <string> ] <CRLF> 
    524      * 
    525      * SMTP CODE SUCCESS: 211,214 
    526      * SMTP CODE ERROR  : 500,501,502,504,421 
    527      * @access public 
    528      * @return string 
    529      */ 
    530     function Help($keyword="") { 
    531         $this->error = null; # to avoid confusion 
    532  
    533         if(!$this->connected()) { 
    534             $this->error = array( 
    535                     "error" => "Called Help() without being connected"); 
    536             return false; 
    537         } 
    538  
    539         $extra = ""; 
    540         if(!empty($keyword)) { 
    541             $extra = " " . $keyword; 
    542         } 
    543  
    544         fputs($this->smtp_conn,"HELP" . $extra . $this->CRLF); 
    545  
    546         $rply = $this->get_lines(); 
    547         $code = substr($rply,0,3); 
    548  
    549         if($this->do_debug >= 2) { 
    550             echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; 
    551         } 
    552  
    553         if($code != 211 && $code != 214) { 
    554             $this->error = 
    555                 array("error" => "HELP not accepted from server", 
    556                       "smtp_code" => $code, 
    557                       "smtp_msg" => substr($rply,4)); 
    558             if($this->do_debug >= 1) { 
    559                 echo "SMTP -> ERROR: " . $this->error["error"] . 
    560                          ": " . $rply . $this->CRLF; 
    561             } 
    562             return false; 
    563         } 
    564  
    565         return $rply; 
    566     } 
    567  
    568     /** 
    569      * Starts a mail transaction from the email address specified in 
    570      * $from. Returns true if successful or false otherwise. If True 
    571      * the mail transaction is started and then one or more Recipient 
    572      * commands may be called followed by a Data command. 
    573      * 
    574      * Implements rfc 821: MAIL <SP> FROM:<reverse-path> <CRLF> 
    575      * 
    576      * SMTP CODE SUCCESS: 250 
    577      * SMTP CODE SUCCESS: 552,451,452 
    578      * SMTP CODE SUCCESS: 500,501,421 
    579      * @access public 
    580      * @return bool 
    581      */ 
    582     function Mail($from) { 
    583         $this->error = null; # so no confusion is caused 
    584  
    585         if(!$this->connected()) { 
    586             $this->error = array( 
    587                     "error" => "Called Mail() without being connected"); 
    588             return false; 
    589         } 
    590  
    591         fputs($this->smtp_conn,"MAIL FROM:<" . $from . ">" . $this->CRLF); 
    592  
    593         $rply = $this->get_lines(); 
    594         $code = substr($rply,0,3); 
    595  
    596         if($this->do_debug >= 2) { 
    597             echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; 
    598         } 
    599  
    600         if($code != 250) { 
    601             $this->error = 
    602                 array("error" => "MAIL not accepted from server", 
    603                       "smtp_code" => $code, 
    604                       "smtp_msg" => substr($rply,4)); 
    605             if($this->do_debug >= 1) { 
    606                 echo "SMTP -> ERROR: " . $this->error["error"] . 
    607                          ": " . $rply . $this->CRLF; 
    608             } 
    609             return false; 
    610         } 
    611         return true; 
    612     } 
    613  
    614     /** 
    615      * Sends the command NOOP to the SMTP server. 
    616      * 
    617      * Implements from rfc 821: NOOP <CRLF> 
    618      * 
    619      * SMTP CODE SUCCESS: 250 
    620      * SMTP CODE ERROR  : 500, 421 
    621      * @access public 
    622      * @return bool 
    623      */ 
    624     function Noop() { 
    625         $this->error = null; # so no confusion is caused 
    626  
    627         if(!$this->connected()) { 
    628             $this->error = array( 
    629                     "error" => "Called Noop() without being connected"); 
    630             return false; 
    631         } 
    632  
    633         fputs($this->smtp_conn,"NOOP" . $this->CRLF); 
    634  
    635         $rply = $this->get_lines(); 
    636         $code = substr($rply,0,3); 
    637  
    638         if($this->do_debug >= 2) { 
    639             echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; 
    640         } 
    641  
    642         if($code != 250) { 
    643             $this->error = 
    644                 array("error" => "NOOP not accepted from server", 
    645                       "smtp_code" => $code, 
    646                       "smtp_msg" => substr($rply,4)); 
    647             if($this->do_debug >= 1) { 
    648                 echo "SMTP -> ERROR: " . $this->error["error"] . 
    649                          ": " . $rply . $this->CRLF; 
    650             } 
    651             return false; 
    652         } 
    653         return true; 
    654     } 
    655  
    656     /** 
    657      * Sends the quit command to the server and then closes the socket 
    658      * if there is no error or the $close_on_error argument is true. 
    659      * 
    660      * Implements from rfc 821: QUIT <CRLF> 
    661      * 
    662      * SMTP CODE SUCCESS: 221 
    663      * SMTP CODE ERROR  : 500 
    664      * @access public 
    665      * @return bool 
    666      */ 
    667     function Quit($close_on_error=true) { 
    668         $this->error = null; # so there is no confusion 
    669  
    670         if(!$this->connected()) { 
    671             $this->error = array( 
    672                     "error" => "Called Quit() without being connected"); 
    673             return false; 
    674         } 
    675  
    676         # send the quit command to the server 
    677         fputs($this->smtp_conn,"quit" . $this->CRLF); 
    678  
    679         # get any good-bye messages 
    680         $byemsg = $this->get_lines(); 
    681  
    682         if($this->do_debug >= 2) { 
    683             echo "SMTP -> FROM SERVER:" . $this->CRLF . $byemsg; 
    684         } 
    685  
    686         $rval = true; 
    687         $e = null; 
    688  
    689         $code = substr($byemsg,0,3); 
    690         if($code != 221) { 
    691             # use e as a tmp var cause Close will overwrite $this->error 
    692             $e = array("error" => "SMTP server rejected quit command", 
    693                        "smtp_code" => $code, 
    694                        "smtp_rply" => substr($byemsg,4)); 
    695             $rval = false; 
    696             if($this->do_debug >= 1) { 
    697                 echo "SMTP -> ERROR: " . $e["error"] . ": " . 
    698                          $byemsg . $this->CRLF; 
    699             } 
    700         } 
    701  
    702         if(empty($e) || $close_on_error) { 
    703             $this->Close(); 
    704         } 
    705  
    706         return $rval; 
    707     } 
    708  
    709     /** 
    710      * Sends the command RCPT to the SMTP server with the TO: argument of $to. 
    711      * Returns true if the recipient was accepted false if it was rejected. 
    712      * 
    713      * Implements from rfc 821: RCPT <SP> TO:<forward-path> <CRLF> 
    714      * 
    715      * SMTP CODE SUCCESS: 250,251 
    716      * SMTP CODE FAILURE: 550,551,552,553,450,451,452 
    717      * SMTP CODE ERROR  : 500,501,503,421 
    718      * @access public 
    719      * @return bool 
    720      */ 
    721     function Recipient($to) { 
    722         $this->error = null; # so no confusion is caused 
    723  
    724         if(!$this->connected()) { 
    725             $this->error = array( 
    726                     "error" => "Called Recipient() without being connected"); 
    727             return false; 
    728         } 
    729  
    730         fputs($this->smtp_conn,"RCPT TO:<" . $to . ">" . $this->CRLF); 
    731  
    732         $rply = $this->get_lines(); 
    733         $code = substr($rply,0,3); 
    734  
    735         if($this->do_debug >= 2) { 
    736             echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; 
    737         } 
    738  
    739         if($code != 250 && $code != 251) { 
    740             $this->error = 
    741                 array("error" => "RCPT not accepted from server", 
    742                       "smtp_code" => $code, 
    743                       "smtp_msg" => substr($rply,4)); 
    744             if($this->do_debug >= 1) { 
    745                 echo "SMTP -> ERROR: " . $this->error["error"] . 
    746                          ": " . $rply . $this->CRLF; 
    747             } 
    748             return false; 
    749         } 
    750         return true; 
    751     } 
    752  
    753     /** 
    754      * Sends the RSET command to abort and transaction that is 
    755      * currently in progress. Returns true if successful false 
    756      * otherwise. 
    757      * 
    758      * Implements rfc 821: RSET <CRLF> 
    759      * 
    760      * SMTP CODE SUCCESS: 250 
    761      * SMTP CODE ERROR  : 500,501,504,421 
    762      * @access public 
    763      * @return bool 
    764      */ 
    765     function Reset() { 
    766         $this->error = null; # so no confusion is caused 
    767  
    768         if(!$this->connected()) { 
    769             $this->error = array( 
    770                     "error" => "Called Reset() without being connected"); 
    771             return false; 
    772         } 
    773  
    774         fputs($this->smtp_conn,"RSET" . $this->CRLF); 
    775  
    776         $rply = $this->get_lines(); 
    777         $code = substr($rply,0,3); 
    778  
    779         if($this->do_debug >= 2) { 
    780             echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; 
    781         } 
    782  
    783         if($code != 250) { 
    784             $this->error = 
    785                 array("error" => "RSET failed", 
    786                       "smtp_code" => $code, 
    787                       "smtp_msg" => substr($rply,4)); 
    788             if($this->do_debug >= 1) { 
    789                 echo "SMTP -> ERROR: " . $this->error["error"] . 
    790                          ": " . $rply . $this->CRLF; 
    791             } 
    792             return false; 
    793         } 
    794  
    795         return true; 
    796     } 
    797  
    798     /** 
    799      * Starts a mail transaction from the email address specified in 
    800      * $from. Returns true if successful or false otherwise. If True 
    801      * the mail transaction is started and then one or more Recipient 
    802      * commands may be called followed by a Data command. This command 
    803      * will send the message to the users terminal if they are logged 
    804      * in. 
    805      * 
    806      * Implements rfc 821: SEND <SP> FROM:<reverse-path> <CRLF> 
    807      * 
    808      * SMTP CODE SUCCESS: 250 
    809      * SMTP CODE SUCCESS: 552,451,452 
    810      * SMTP CODE SUCCESS: 500,501,502,421 
    811      * @access public 
    812      * @return bool 
    813      */ 
    814     function Send($from) { 
    815         $this->error = null; # so no confusion is caused 
    816  
    817         if(!$this->connected()) { 
    818             $this->error = array( 
    819                     "error" => "Called Send() without being connected"); 
    820             return false; 
    821         } 
    822  
    823         fputs($this->smtp_conn,"SEND FROM:" . $from . $this->CRLF); 
    824  
    825         $rply = $this->get_lines(); 
    826         $code = substr($rply,0,3); 
    827  
    828         if($this->do_debug >= 2) { 
    829             echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; 
    830         } 
    831  
    832         if($code != 250) { 
    833             $this->error = 
    834                 array("error" => "SEND not accepted from server", 
    835                       "smtp_code" => $code, 
    836                       "smtp_msg" => substr($rply,4)); 
    837             if($this->do_debug >= 1) { 
    838                 echo "SMTP -> ERROR: " . $this->error["error"] . 
    839                          ": " . $rply . $this->CRLF; 
    840             } 
    841             return false; 
    842         } 
    843         return true; 
    844     } 
    845  
    846     /** 
    847      * Starts a mail transaction from the email address specified in 
    848      * $from. Returns true if successful or false otherwise. If True 
    849      * the mail transaction is started and then one or more Recipient 
    850      * commands may be called followed by a Data command. This command 
    851      * will send the message to the users terminal if they are logged 
    852      * in and send them an email. 
    853      * 
    854      * Implements rfc 821: SAML <SP> FROM:<reverse-path> <CRLF> 
    855      * 
    856      * SMTP CODE SUCCESS: 250 
    857      * SMTP CODE SUCCESS: 552,451,452 
    858      * SMTP CODE SUCCESS: 500,501,502,421 
    859      * @access public 
    860      * @return bool 
    861      */ 
    862     function SendAndMail($from) { 
    863         $this->error = null; # so no confusion is caused 
    864  
    865         if(!$this->connected()) { 
    866             $this->error = array( 
    867                 "error" => "Called SendAndMail() without being connected"); 
    868             return false; 
    869         } 
    870  
    871         fputs($this->smtp_conn,"SAML FROM:" . $from . $this->CRLF); 
    872  
    873         $rply = $this->get_lines(); 
    874         $code = substr($rply,0,3); 
    875  
    876         if($this->do_debug >= 2) { 
    877             echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; 
    878         } 
    879  
    880         if($code != 250) { 
    881             $this->error = 
    882                 array("error" => "SAML not accepted from server", 
    883                       "smtp_code" => $code, 
    884                       "smtp_msg" => substr($rply,4)); 
    885             if($this->do_debug >= 1) { 
    886                 echo "SMTP -> ERROR: " . $this->error["error"] . 
    887                          ": " . $rply . $this->CRLF; 
    888             } 
    889             return false; 
    890         } 
    891         return true; 
    892     } 
    893  
    894     /** 
    895      * Starts a mail transaction from the email address specified in 
    896      * $from. Returns true if successful or false otherwise. If True 
    897      * the mail transaction is started and then one or more Recipient 
    898      * commands may be called followed by a Data command. This command 
    899      * will send the message to the users terminal if they are logged 
    900      * in or mail it to them if they are not. 
    901      * 
    902      * Implements rfc 821: SOML <SP> FROM:<reverse-path> <CRLF> 
    903      * 
    904      * SMTP CODE SUCCESS: 250 
    905      * SMTP CODE SUCCESS: 552,451,452 
    906      * SMTP CODE SUCCESS: 500,501,502,421 
    907      * @access public 
    908      * @return bool 
    909      */ 
    910     function SendOrMail($from) { 
    911         $this->error = null; # so no confusion is caused 
    912  
    913         if(!$this->connected()) { 
    914             $this->error = array( 
    915                 "error" => "Called SendOrMail() without being connected"); 
    916             return false; 
    917         } 
    918  
    919         fputs($this->smtp_conn,"SOML FROM:" . $from . $this->CRLF); 
    920  
    921         $rply = $this->get_lines(); 
    922         $code = substr($rply,0,3); 
    923  
    924         if($this->do_debug >= 2) { 
    925             echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; 
    926         } 
    927  
    928         if($code != 250) { 
    929             $this->error = 
    930                 array("error" => "SOML not accepted from server", 
    931                       "smtp_code" => $code, 
    932                       "smtp_msg" => substr($rply,4)); 
    933             if($this->do_debug >= 1) { 
    934                 echo "SMTP -> ERROR: " . $this->error["error"] . 
    935                          ": " . $rply . $this->CRLF; 
    936             } 
    937             return false; 
    938         } 
    939         return true; 
    940     } 
    941  
    942     /** 
    943      * This is an optional command for SMTP that this class does not 
    944      * support. This method is here to make the RFC821 Definition 
    945      * complete for this class and __may__ be implimented in the future 
    946      * 
    947      * Implements from rfc 821: TURN <CRLF> 
    948      * 
    949      * SMTP CODE SUCCESS: 250 
    950      * SMTP CODE FAILURE: 502 
    951      * SMTP CODE ERROR  : 500, 503 
    952      * @access public 
    953      * @return bool 
    954      */ 
    955     function Turn() { 
    956         $this->error = array("error" => "This method, TURN, of the SMTP ". 
    957                                         "is not implemented"); 
    958         if($this->do_debug >= 1) { 
    959             echo "SMTP -> NOTICE: " . $this->error["error"] . $this->CRLF; 
    960         } 
    961         return false; 
    962     } 
    963  
    964     /** 
    965      * Verifies that the name is recognized by the server. 
    966      * Returns false if the name could not be verified otherwise 
    967      * the response from the server is returned. 
    968      * 
    969      * Implements rfc 821: VRFY <SP> <string> <CRLF> 
    970      * 
    971      * SMTP CODE SUCCESS: 250,251 
    972      * SMTP CODE FAILURE: 550,551,553 
    973      * SMTP CODE ERROR  : 500,501,502,421 
    974      * @access public 
    975      * @return int 
    976      */ 
    977     function Verify($name) { 
    978         $this->error = null; # so no confusion is caused 
    979  
    980         if(!$this->connected()) { 
    981             $this->error = array( 
    982                     "error" => "Called Verify() without being connected"); 
    983             return false; 
    984         } 
    985  
    986         fputs($this->smtp_conn,"VRFY " . $name . $this->CRLF); 
    987  
    988         $rply = $this->get_lines(); 
    989         $code = substr($rply,0,3); 
    990  
    991         if($this->do_debug >= 2) { 
    992             echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; 
    993         } 
    994  
    995         if($code != 250 && $code != 251) { 
    996             $this->error = 
    997                 array("error" => "VRFY failed on name '$name'", 
    998                       "smtp_code" => $code, 
    999                       "smtp_msg" => substr($rply,4)); 
    1000             if($this->do_debug >= 1) { 
    1001                 echo "SMTP -> ERROR: " . $this->error["error"] . 
    1002                          ": " . $rply . $this->CRLF; 
    1003             } 
    1004             return false; 
    1005         } 
    1006         return $rply; 
    1007     } 
    1008  
    1009     /******************************************************************* 
    1010      *                       INTERNAL FUNCTIONS                       * 
    1011      ******************************************************************/ 
    1012  
    1013     /** 
    1014      * Read in as many lines as possible 
    1015      * either before eof or socket timeout occurs on the operation. 
    1016      * With SMTP we can tell if we have more lines to read if the 
    1017      * 4th character is '-' symbol. If it is a space then we don't 
    1018      * need to read anything else. 
    1019      * @access private 
    1020      * @return string 
    1021      */ 
    1022     function get_lines() { 
    1023         $data = ""; 
    1024         while($str = fgets($this->smtp_conn,515)) { 
    1025             if($this->do_debug >= 4) { 
    1026                 echo "SMTP -> get_lines(): \$data was \"$data\"" . 
    1027                          $this->CRLF; 
    1028                 echo "SMTP -> get_lines(): \$str is \"$str\"" . 
    1029                          $this->CRLF; 
    1030             } 
    1031             $data .= $str; 
    1032             if($this->do_debug >= 4) { 
    1033                 echo "SMTP -> get_lines(): \$data is \"$data\"" . $this->CRLF; 
    1034             } 
    1035             # if the 4th character is a space then we are done reading 
    1036             # so just break the loop 
    1037             if(substr($str,3,1) == " ") { break; } 
    1038         } 
    1039         return $data; 
    1040     } 
     376        fputs($this->smtp_conn,$line_out . $this->CRLF); 
     377      } 
     378    } 
     379 
     380    # ok all the message data has been sent so lets get this 
     381    # over with aleady 
     382    fputs($this->smtp_conn, $this->CRLF . "." . $this->CRLF); 
     383 
     384    $rply = $this->get_lines(); 
     385    $code = substr($rply,0,3); 
     386 
     387    if($this->do_debug >= 2) { 
     388      echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; 
     389    } 
     390 
     391    if($code != 250) { 
     392      $this->error = 
     393        array("error" => "DATA not accepted from server", 
     394              "smtp_code" => $code, 
     395              "smtp_msg" => substr($rply,4)); 
     396      if($this->do_debug >= 1) { 
     397        echo "SMTP -> ERROR: " . $this->error["error"] . 
     398                 ": " . $rply . $this->CRLF; 
     399      } 
     400      return false; 
     401    } 
     402    return true; 
     403  } 
     404 
     405  /** 
     406   * Expand takes the name and asks the server to list all the 
     407   * people who are members of the _list_. Expand will return 
     408   * back and array of the result or false if an error occurs. 
     409   * Each value in the array returned has the format of: 
     410   *     [ <full-name> <sp> ] <path> 
     411   * The definition of <path> is defined in rfc 821 
     412   * 
     413   * Implements rfc 821: EXPN <SP> <string> <CRLF> 
     414   * 
     415   * SMTP CODE SUCCESS: 250 
     416   * SMTP CODE FAILURE: 550 
     417   * SMTP CODE ERROR  : 500,501,502,504,421 
     418   * @access public 
     419   * @return string array 
     420   */ 
     421  function Expand($name) { 
     422    $this->error = null; # so no confusion is caused 
     423 
     424    if(!$this->connected()) { 
     425      $this->error = array( 
     426            "error" => "Called Expand() without being connected"); 
     427      return false; 
     428    } 
     429 
     430    fputs($this->smtp_conn,"EXPN " . $name . $this->CRLF); 
     431 
     432    $rply = $this->get_lines(); 
     433    $code = substr($rply,0,3); 
     434 
     435    if($this->do_debug >= 2) { 
     436      echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; 
     437    } 
     438 
     439    if($code != 250) { 
     440      $this->error = 
     441        array("error" => "EXPN not accepted from server", 
     442              "smtp_code" => $code, 
     443              "smtp_msg" => substr($rply,4)); 
     444      if($this->do_debug >= 1) { 
     445        echo "SMTP -> ERROR: " . $this->error["error"] . 
     446                 ": " . $rply . $this->CRLF; 
     447      } 
     448      return false; 
     449    } 
     450 
     451    # parse the reply and place in our array to return to user 
     452    $entries = explode($this->CRLF,$rply); 
     453    while(list(,$l) = @each($entries)) { 
     454      $list[] = substr($l,4); 
     455    } 
     456 
     457    return $list; 
     458  } 
     459 
     460  /** 
     461   * Sends the HELO command to the smtp server. 
     462   * This makes sure that we and the server are in 
     463   * the same known state. 
     464   * 
     465   * Implements from rfc 821: HELO <SP> <domain> <CRLF> 
     466   * 
     467   * SMTP CODE SUCCESS: 250 
     468   * SMTP CODE ERROR  : 500, 501, 504, 421 
     469   * @access public 
     470   * @return bool 
     471   */ 
     472  function Hello($host="") { 
     473    $this->error = null; # so no confusion is caused 
     474 
     475    if(!$this->connected()) { 
     476      $this->error = array( 
     477            "error" => "Called Hello() without being connected"); 
     478      return false; 
     479    } 
     480 
     481    # if a hostname for the HELO was not specified determine 
     482    # a suitable one to send 
     483    if(empty($host)) { 
     484      # we need to determine some sort of appopiate default 
     485      # to send to the server 
     486      $host = "localhost"; 
     487    } 
     488 
     489    // Send extended hello first (RFC 2821) 
     490    if(!$this->SendHello("EHLO", $host)) 
     491    { 
     492      if(!$this->SendHello("HELO", $host)) 
     493          return false; 
     494    } 
     495 
     496    return true; 
     497  } 
     498 
     499  /** 
     500   * Sends a HELO/EHLO command. 
     501   * @access private 
     502   * @return bool 
     503   */ 
     504  function SendHello($hello, $host) { 
     505    fputs($this->smtp_conn, $hello . " " . $host . $this->CRLF); 
     506 
     507    $rply = $this->get_lines(); 
     508    $code = substr($rply,0,3); 
     509 
     510    if($this->do_debug >= 2) { 
     511      echo "SMTP -> FROM SERVER: " . $this->CRLF . $rply; 
     512    } 
     513 
     514    if($code != 250) { 
     515      $this->error = 
     516        array("error" => $hello . " not accepted from server", 
     517              "smtp_code" => $code, 
     518              "smtp_msg" => substr($rply,4)); 
     519      if($this->do_debug >= 1) { 
     520        echo "SMTP -> ERROR: " . $this->error["error"] . 
     521                 ": " . $rply . $this->CRLF; 
     522      } 
     523      return false; 
     524    } 
     525 
     526    $this->helo_rply = $rply; 
     527 
     528    return true; 
     529  } 
     530 
     531  /** 
     532   * Gets help information on the keyword specified. If the keyword 
     533   * is not specified then returns generic help, ussually contianing 
     534   * A list of keywords that help is available on. This function 
     535   * returns the results back to the user. It is up to the user to 
     536   * handle the returned data. If an error occurs then false is 
     537   * returned with $this->error set appropiately. 
     538   * 
     539   * Implements rfc 821: HELP [ <SP> <string> ] <CRLF> 
     540   * 
     541   * SMTP CODE SUCCESS: 211,214 
     542   * SMTP CODE ERROR  : 500,501,502,504,421 
     543   * @access public 
     544   * @return string 
     545   */ 
     546  function Help($keyword="") { 
     547    $this->error = null; # to avoid confusion 
     548 
     549    if(!$this->connected()) { 
     550      $this->error = array( 
     551              "error" => "Called Help() without being connected"); 
     552      return false; 
     553    } 
     554 
     555    $extra = ""; 
     556    if(!empty($keyword)) { 
     557      $extra = " " . $keyword; 
     558    } 
     559 
     560    fputs($this->smtp_conn,"HELP" . $extra . $this->CRLF); 
     561 
     562    $rply = $this->get_lines(); 
     563    $code = substr($rply,0,3); 
     564 
     565    if($this->do_debug >= 2) { 
     566      echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; 
     567    } 
     568 
     569    if($code != 211 && $code != 214) { 
     570      $this->error = 
     571        array("error" => "HELP not accepted from server", 
     572              "smtp_code" => $code, 
     573              "smtp_msg" => substr($rply,4)); 
     574      if($this->do_debug >= 1) { 
     575        echo "SMTP -> ERROR: " . $this->error["error"] . 
     576                 ": " . $rply . $this->CRLF; 
     577      } 
     578      return false; 
     579    } 
     580 
     581    return $rply; 
     582  } 
     583 
     584  /** 
     585   * Starts a mail transaction from the email address specified in 
     586   * $from. Returns true if successful or false otherwise. If True 
     587   * the mail transaction is started and then one or more Recipient 
     588   * commands may be called followed by a Data command. 
     589   * 
     590   * Implements rfc 821: MAIL <SP> FROM:<reverse-path> <CRLF> 
     591   * 
     592   * SMTP CODE SUCCESS: 250 
     593   * SMTP CODE SUCCESS: 552,451,452 
     594   * SMTP CODE SUCCESS: 500,501,421 
     595   * @access public 
     596   * @return bool 
     597   */ 
     598  function Mail($from) { 
     599    $this->error = null; # so no confusion is caused 
     600 
     601    if(!$this->connected()) { 
     602      $this->error = array( 
     603              "error" => "Called Mail() without being connected"); 
     604      return false; 
     605    } 
     606 
     607    $useVerp = ($this->do_verp ? "XVERP" : ""); 
     608    fputs($this->smtp_conn,"MAIL FROM:<" . $from . ">" . $useVerp . $this->CRLF); 
     609 
     610    $rply = $this->get_lines(); 
     611    $code = substr($rply,0,3); 
     612 
     613    if($this->do_debug >= 2) { 
     614      echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; 
     615    } 
     616 
     617    if($code != 250) { 
     618      $this->error = 
     619        array("error" => "MAIL not accepted from server", 
     620              "smtp_code" => $code, 
     621              "smtp_msg" => substr($rply,4)); 
     622      if($this->do_debug >= 1) { 
     623        echo "SMTP -> ERROR: " . $this->error["error"] . 
     624                 ": " . $rply . $this->CRLF; 
     625      } 
     626      return false; 
     627    } 
     628    return true; 
     629  } 
     630 
     631  /** 
     632   * Sends the command NOOP to the SMTP server. 
     633   * 
     634   * Implements from rfc 821: NOOP <CRLF> 
     635   * 
     636   * SMTP CODE SUCCESS: 250 
     637   * SMTP CODE ERROR  : 500, 421 
     638   * @access public 
     639   * @return bool 
     640   */ 
     641  function Noop() { 
     642    $this->error = null; # so no confusion is caused 
     643 
     644    if(!$this->connected()) { 
     645      $this->error = array( 
     646              "error" => "Called Noop() without being connected"); 
     647      return false; 
     648    } 
     649 
     650    fputs($this->smtp_conn,"NOOP" . $this->CRLF); 
     651 
     652    $rply = $this->get_lines(); 
     653    $code = substr($rply,0,3); 
     654 
     655    if($this->do_debug >= 2) { 
     656      echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; 
     657    } 
     658 
     659    if($code != 250) { 
     660      $this->error = 
     661        array("error" => "NOOP not accepted from server", 
     662              "smtp_code" => $code, 
     663              "smtp_msg" => substr($rply,4)); 
     664      if($this->do_debug >= 1) { 
     665        echo "SMTP -> ERROR: " . $this->error["error"] . 
     666                 ": " . $rply . $this->CRLF; 
     667      } 
     668      return false; 
     669    } 
     670    return true; 
     671  } 
     672 
     673  /** 
     674   * Sends the quit command to the server and then closes the socket 
     675   * if there is no error or the $close_on_error argument is true. 
     676   * 
     677   * Implements from rfc 821: QUIT <CRLF> 
     678   * 
     679   * SMTP CODE SUCCESS: 221 
     680   * SMTP CODE ERROR  : 500 
     681   * @access public 
     682   * @return bool 
     683   */ 
     684  function Quit($close_on_error=true) { 
     685    $this->error = null; # so there is no confusion 
     686 
     687    if(!$this->connected()) { 
     688      $this->error = array( 
     689              "error" => "Called Quit() without being connected"); 
     690      return false; 
     691    } 
     692 
     693    # send the quit command to the server 
     694    fputs($this->smtp_conn,"quit" . $this->CRLF); 
     695 
     696    # get any good-bye messages 
     697    $byemsg = $this->get_lines(); 
     698 
     699    if($this->do_debug >= 2) { 
     700      echo "SMTP -> FROM SERVER:" . $this->CRLF . $byemsg; 
     701    } 
     702 
     703    $rval = true; 
     704    $e = null; 
     705 
     706    $code = substr($byemsg,0,3); 
     707    if($code != 221) { 
     708      # use e as a tmp var cause Close will overwrite $this->error 
     709      $e = array("error" => "SMTP server rejected quit command", 
     710                 "smtp_code" => $code, 
     711                 "smtp_rply" => substr($byemsg,4)); 
     712      $rval = false; 
     713      if($this->do_debug >= 1) { 
     714        echo "SMTP -> ERROR: " . $e["error"] . ": " . 
     715                 $byemsg . $this->CRLF; 
     716      } 
     717    } 
     718 
     719    if(empty($e) || $close_on_error) { 
     720      $this->Close(); 
     721    } 
     722 
     723    return $rval; 
     724  } 
     725 
     726  /** 
     727   * Sends the command RCPT to the SMTP server with the TO: argument of $to. 
     728   * Returns true if the recipient was accepted false if it was rejected. 
     729   * 
     730   * Implements from rfc 821: RCPT <SP> TO:<forward-path> <CRLF> 
     731   * 
     732   * SMTP CODE SUCCESS: 250,251 
     733   * SMTP CODE FAILURE: 550,551,552,553,450,451,452 
     734   * SMTP CODE ERROR  : 500,501,503,421 
     735   * @access public 
     736   * @return bool 
     737   */ 
     738  function Recipient($to) { 
     739    $this->error = null; # so no confusion is caused 
     740 
     741    if(!$this->connected()) { 
     742      $this->error = array( 
     743              "error" => "Called Recipient() without being connected"); 
     744      return false; 
     745    } 
     746 
     747    fputs($this->smtp_conn,"RCPT TO:<" . $to . ">" . $this->CRLF); 
     748 
     749    $rply = $this->get_lines(); 
     750    $code = substr($rply,0,3); 
     751 
     752    if($this->do_debug >= 2) { 
     753      echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; 
     754    } 
     755 
     756    if($code != 250 && $code != 251) { 
     757      $this->error = 
     758        array("error" => "RCPT not accepted from server", 
     759              "smtp_code" => $code, 
     760              "smtp_msg" => substr($rply,4)); 
     761      if($this->do_debug >= 1) { 
     762        echo "SMTP -> ERROR: " . $this->error["error"] . 
     763                 ": " . $rply . $this->CRLF; 
     764      } 
     765      return false; 
     766    } 
     767    return true; 
     768  } 
     769 
     770  /** 
     771   * Sends the RSET command to abort and transaction that is 
     772   * currently in progress. Returns true if successful false 
     773   * otherwise. 
     774   * 
     775   * Implements rfc 821: RSET <CRLF> 
     776   * 
     777   * SMTP CODE SUCCESS: 250 
     778   * SMTP CODE ERROR  : 500,501,504,421 
     779   * @access public 
     780   * @return bool 
     781   */ 
     782  function Reset() { 
     783    $this->error = null; # so no confusion is caused 
     784 
     785    if(!$this->connected()) { 
     786      $this->error = array( 
     787              "error" => "Called Reset() without being connected"); 
     788      return false; 
     789    } 
     790 
     791    fputs($this->smtp_conn,"RSET" . $this->CRLF); 
     792 
     793    $rply = $this->get_lines(); 
     794    $code = substr($rply,0,3); 
     795 
     796    if($this->do_debug >= 2) { 
     797      echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; 
     798    } 
     799 
     800    if($code != 250) { 
     801      $this->error = 
     802        array("error" => "RSET failed", 
     803              "smtp_code" => $code, 
     804              "smtp_msg" => substr($rply,4)); 
     805      if($this->do_debug >= 1) { 
     806        echo "SMTP -> ERROR: " . $this->error["error"] . 
     807                 ": " . $rply . $this->CRLF; 
     808      } 
     809      return false; 
     810    } 
     811 
     812    return true; 
     813  } 
     814 
     815  /** 
     816   * Starts a mail transaction from the email address specified in 
     817   * $from. Returns true if successful or false otherwise. If True 
     818   * the mail transaction is started and then one or more Recipient 
     819   * commands may be called followed by a Data command. This command 
     820   * will send the message to the users terminal if they are logged 
     821   * in. 
     822   * 
     823   * Implements rfc 821: SEND <SP> FROM:<reverse-path> <CRLF> 
     824   * 
     825   * SMTP CODE SUCCESS: 250 
     826   * SMTP CODE SUCCESS: 552,451,452 
     827   * SMTP CODE SUCCESS: 500,501,502,421 
     828   * @access public 
     829   * @return bool 
     830   */ 
     831  function Send($from) { 
     832    $this->error = null; # so no confusion is caused 
     833 
     834    if(!$this->connected()) { 
     835      $this->error = array( 
     836              "error" => "Called Send() without being connected"); 
     837      return false; 
     838    } 
     839 
     840    fputs($this->smtp_conn,"SEND FROM:" . $from . $this->CRLF); 
     841 
     842    $rply = $this->get_lines(); 
     843    $code = substr($rply,0,3); 
     844 
     845    if($this->do_debug >= 2) { 
     846      echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; 
     847    } 
     848 
     849    if($code != 250) { 
     850      $this->error = 
     851        array("error" => "SEND not accepted from server", 
     852              "smtp_code" => $code, 
     853              "smtp_msg" => substr($rply,4)); 
     854      if($this->do_debug >= 1) { 
     855        echo "SMTP -> ERROR: " . $this->error["error"] . 
     856                 ": " . $rply . $this->CRLF; 
     857      } 
     858      return false; 
     859    } 
     860    return true; 
     861  } 
     862 
     863  /** 
     864   * Starts a mail transaction from the email address specified in 
     865   * $from. Returns true if successful or false otherwise. If True 
     866   * the mail transaction is started and then one or more Recipient 
     867   * commands may be called followed by a Data command. This command 
     868   * will send the message to the users terminal if they are logged 
     869   * in and send them an email. 
     870   * 
     871   * Implements rfc 821: SAML <SP> FROM:<reverse-path> <CRLF> 
     872   * 
     873   * SMTP CODE SUCCESS: 250 
     874   * SMTP CODE SUCCESS: 552,451,452 
     875   * SMTP CODE SUCCESS: 500,501,502,421 
     876   * @access public 
     877   * @return bool 
     878   */ 
     879  function SendAndMail($from) { 
     880    $this->error = null; # so no confusion is caused 
     881 
     882    if(!$this->connected()) { 
     883      $this->error = array( 
     884          "error" => "Called SendAndMail() without being connected"); 
     885      return false; 
     886    } 
     887 
     888    fputs($this->smtp_conn,"SAML FROM:" . $from . $this->CRLF); 
     889 
     890    $rply = $this->get_lines(); 
     891    $code = substr($rply,0,3); 
     892 
     893    if($this->do_debug >= 2) { 
     894      echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; 
     895    } 
     896 
     897    if($code != 250) { 
     898      $this->error =