1<?php
2/*~ class.smtp.php
3.---------------------------------------------------------------------------.
4|  Software: PHPMailer - PHP email class                                    |
5|   Version: 5.0.0                                                          |
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|     Admin: Andy Prevost (project admininistrator)                         |
11|   Authors: Andy Prevost (codeworxtech) codeworxtech@users.sourceforge.net |
12|          : Marcus Bointon (coolbru) coolbru@users.sourceforge.net         |
13|   Founder: Brent R. Matzelle (original founder)                           |
14| Copyright (c) 2004-2009, Andy Prevost. All Rights Reserved.               |
15| Copyright (c) 2001-2003, Brent R. Matzelle                                |
16| ------------------------------------------------------------------------- |
17|   License: Distributed under the Lesser General Public License (LGPL)     |
18|            http://www.gnu.org/copyleft/lesser.html                        |
19| This program is distributed in the hope that it will be useful - WITHOUT  |
20| ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or     |
21| FITNESS FOR A PARTICULAR PURPOSE.                                         |
22| ------------------------------------------------------------------------- |
23| We offer a number of paid services (www.codeworxtech.com):                |
24| - Web Hosting on highly optimized fast and secure servers                 |
25| - Technology Consulting                                                   |
26| - Oursourcing (highly qualified programmers and graphic designers)        |
27'---------------------------------------------------------------------------'
28*/
29
30/**
31 * PHPMailer - PHP SMTP email transport class
32 * NOTE: Designed for use with PHP version 5 and up
33 * @package PHPMailer
34 * @author Andy Prevost
35 * @author Marcus Bointon
36 * @copyright 2004 - 2008 Andy Prevost
37 * @license http://www.gnu.org/copyleft/lesser.html Distributed under the Lesser General Public License (LGPL)
38 * @version $Id: class.smtp.php 240 2009-03-31 04:40:33Z codeworxtech $
39 */
40
41/**
42 * SMTP is rfc 821 compliant and implements all the rfc 821 SMTP
43 * commands except TURN which will always return a not implemented
44 * error. SMTP also provides some utility methods for sending mail
45 * to an SMTP server.
46 * original author: Chris Ryan
47 */
48
49class SMTP {
50  /**
51   *  SMTP server port
52   *  @var int
53   */
54  public $SMTP_PORT = 25;
55
56  /**
57   *  SMTP reply line ending
58   *  @var string
59   */
60  public $CRLF = "\r\n";
61
62  /**
63   *  Sets whether debugging is turned on
64   *  @var bool
65   */
66  public $do_debug;       // the level of debug to perform
67
68  /**
69   *  Sets VERP use on/off (default is off)
70   *  @var bool
71   */
72  public $do_verp = false;
73
74  /////////////////////////////////////////////////
75  // PROPERTIES, PRIVATE AND PROTECTED
76  /////////////////////////////////////////////////
77
78  private $smtp_conn; // the socket to the server
79  private $error;     // error if any on the last call
80  private $helo_rply; // the reply the server sent to us for HELO
81
82  /**
83   * Initialize the class so that the data is in a known state.
84   * @access public
85   * @return void
86   */
87  public function __construct() {
88    $this->smtp_conn = 0;
89    $this->error = null;
90    $this->helo_rply = null;
91
92    $this->do_debug = 0;
93  }
94
95  /////////////////////////////////////////////////
96  // CONNECTION FUNCTIONS
97  /////////////////////////////////////////////////
98
99  /**
100   * Connect to the server specified on the port specified.
101   * If the port is not specified use the default SMTP_PORT.
102   * If tval is specified then a connection will try and be
103   * established with the server for that number of seconds.
104   * If tval is not specified the default is 30 seconds to
105   * try on the connection.
106   *
107   * SMTP CODE SUCCESS: 220
108   * SMTP CODE FAILURE: 421
109   * @access public
110   * @return bool
111   */
112  public function Connect($host, $port = 0, $tval = 30) {
113    // set the error val to null so there is no confusion
114    $this->error = null;
115
116    // make sure we are __not__ connected
117    if($this->connected()) {
118      // already connected, generate error
119      $this->error = array("error" => "Already connected to a server");
120      return false;
121    }
122
123    if(empty($port)) {
124      $port = $this->SMTP_PORT;
125    }
126
127    // connect to the smtp server
128    $this->smtp_conn = @fsockopen($host,    // the host of the server
129                                 $port,    // the port to use
130                                 $errno,   // error number if any
131                                 $errstr,  // error message if any
132                                 $tval);   // give up after ? secs
133    // verify we connected properly
134    if(empty($this->smtp_conn)) {
135      $this->error = array("error" => "Failed to connect to server",
136                           "errno" => $errno,
137                           "errstr" => $errstr);
138      if($this->do_debug >= 1) {
139        echo "SMTP -> ERROR: " . $this->error["error"] . ": $errstr ($errno)" . $this->CRLF . '<br />';
140      }
141      return false;
142    }
143
144    // SMTP server can take longer to respond, give longer timeout for first read
145    // Windows does not have support for this timeout function
146    if(substr(PHP_OS, 0, 3) != "WIN")
147     socket_set_timeout($this->smtp_conn, $tval, 0);
148
149    // get any announcement
150    $announce = $this->get_lines();
151
152    if($this->do_debug >= 2) {
153      echo "SMTP -> FROM SERVER:" . $announce . $this->CRLF . '<br />';
154    }
155
156    return true;
157  }
158
159  /**
160   * Initiate a TLS communication with the server.
161   *
162   * SMTP CODE 220 Ready to start TLS
163   * SMTP CODE 501 Syntax error (no parameters allowed)
164   * SMTP CODE 454 TLS not available due to temporary reason
165   * @access public
166   * @return bool success
167   */
168  public function StartTLS() {
169    $this->error = null; # to avoid confusion
170
171    if(!$this->connected()) {
172      $this->error = array("error" => "Called StartTLS() without being connected");
173      return false;
174    }
175
176    fputs($this->smtp_conn,"STARTTLS" . $this->CRLF);
177
178    $rply = $this->get_lines();
179    $code = substr($rply,0,3);
180
181    if($this->do_debug >= 2) {
182      echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />';
183    }
184
185    if($code != 220) {
186      $this->error =
187         array("error"     => "STARTTLS not accepted from server",
188               "smtp_code" => $code,
189               "smtp_msg"  => substr($rply,4));
190      if($this->do_debug >= 1) {
191        echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
192      }
193      return false;
194    }
195
196    // Begin encrypted connection
197    if(!stream_socket_enable_crypto($this->smtp_conn, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)) {
198      return false;
199    }
200
201    return true;
202  }
203
204  /**
205   * Performs SMTP authentication.  Must be run after running the
206   * Hello() method.  Returns true if successfully authenticated.
207   * @access public
208   * @return bool
209   */
210  public function Authenticate($username, $password) {
211    // Start authentication
212    fputs($this->smtp_conn,"AUTH LOGIN" . $this->CRLF);
213
214    $rply = $this->get_lines();
215    $code = substr($rply,0,3);
216
217    if($code != 334) {
218      $this->error =
219        array("error" => "AUTH not accepted from server",
220              "smtp_code" => $code,
221              "smtp_msg" => substr($rply,4));
222      if($this->do_debug >= 1) {
223        echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
224      }
225      return false;
226    }
227
228    // Send encoded username
229    fputs($this->smtp_conn, base64_encode($username) . $this->CRLF);
230
231    $rply = $this->get_lines();
232    $code = substr($rply,0,3);
233
234    if($code != 334) {
235      $this->error =
236        array("error" => "Username not accepted from server",
237              "smtp_code" => $code,
238              "smtp_msg" => substr($rply,4));
239      if($this->do_debug >= 1) {
240        echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
241      }
242      return false;
243    }
244
245    // Send encoded password
246    fputs($this->smtp_conn, base64_encode($password) . $this->CRLF);
247
248    $rply = $this->get_lines();
249    $code = substr($rply,0,3);
250
251    if($code != 235) {
252      $this->error =
253        array("error" => "Password not accepted from server",
254              "smtp_code" => $code,
255              "smtp_msg" => substr($rply,4));
256      if($this->do_debug >= 1) {
257        echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
258      }
259      return false;
260    }
261
262    return true;
263  }
264
265  /**
266   * Returns true if connected to a server otherwise false
267   * @access public
268   * @return bool
269   */
270  public function Connected() {
271    if(!empty($this->smtp_conn)) {
272      $sock_status = socket_get_status($this->smtp_conn);
273      if($sock_status["eof"]) {
274        // the socket is valid but we are not connected
275        if($this->do_debug >= 1) {
276            echo "SMTP -> NOTICE:" . $this->CRLF . "EOF caught while checking if connected";
277        }
278        $this->Close();
279        return false;
280      }
281      return true; // everything looks good
282    }
283    return false;
284  }
285
286  /**
287   * Closes the socket and cleans up the state of the class.
288   * It is not considered good to use this function without
289   * first trying to use QUIT.
290   * @access public
291   * @return void
292   */
293  public function Close() {
294    $this->error = null; // so there is no confusion
295    $this->helo_rply = null;
296    if(!empty($this->smtp_conn)) {
297      // close the connection and cleanup
298      fclose($this->smtp_conn);
299      $this->smtp_conn = 0;
300    }
301  }
302
303  /////////////////////////////////////////////////
304  // SMTP COMMANDS
305  /////////////////////////////////////////////////
306
307  /**
308   * Issues a data command and sends the msg_data to the server
309   * finializing the mail transaction. $msg_data is the message
310   * that is to be send with the headers. Each header needs to be
311   * on a single line followed by a <CRLF> with the message headers
312   * and the message body being seperated by and additional <CRLF>.
313   *
314   * Implements rfc 821: DATA <CRLF>
315   *
316   * SMTP CODE INTERMEDIATE: 354
317   *     [data]
318   *     <CRLF>.<CRLF>
319   *     SMTP CODE SUCCESS: 250
320   *     SMTP CODE FAILURE: 552,554,451,452
321   * SMTP CODE FAILURE: 451,554
322   * SMTP CODE ERROR  : 500,501,503,421
323   * @access public
324   * @return bool
325   */
326  public function Data($msg_data) {
327    $this->error = null; // so no confusion is caused
328
329    if(!$this->connected()) {
330      $this->error = array(
331              "error" => "Called Data() without being connected");
332      return false;
333    }
334
335    fputs($this->smtp_conn,"DATA" . $this->CRLF);
336
337    $rply = $this->get_lines();
338    $code = substr($rply,0,3);
339
340    if($this->do_debug >= 2) {
341      echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />';
342    }
343
344    if($code != 354) {
345      $this->error =
346        array("error" => "DATA command not accepted from server",
347              "smtp_code" => $code,
348              "smtp_msg" => substr($rply,4));
349      if($this->do_debug >= 1) {
350        echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
351      }
352      return false;
353    }
354
355    /* the server is ready to accept data!
356     * according to rfc 821 we should not send more than 1000
357     * including the CRLF
358     * characters on a single line so we will break the data up
359     * into lines by \r and/or \n then if needed we will break
360     * each of those into smaller lines to fit within the limit.
361     * in addition we will be looking for lines that start with
362     * a period '.' and append and additional period '.' to that
363     * line. NOTE: this does not count towards limit.
364     */
365
366    // normalize the line breaks so we know the explode works
367    $msg_data = str_replace("\r\n","\n",$msg_data);
368    $msg_data = str_replace("\r","\n",$msg_data);
369    $lines = explode("\n",$msg_data);
370
371    /* we need to find a good way to determine is headers are
372     * in the msg_data or if it is a straight msg body
373     * currently I am assuming rfc 822 definitions of msg headers
374     * and if the first field of the first line (':' sperated)
375     * does not contain a space then it _should_ be a header
376     * and we can process all lines before a blank "" line as
377     * headers.
378     */
379
380    $field = substr($lines[0],0,strpos($lines[0],":"));
381    $in_headers = false;
382    if(!empty($field) && !strstr($field," ")) {
383      $in_headers = true;
384    }
385
386    $max_line_length = 998; // used below; set here for ease in change
387
388    while(list(,$line) = @each($lines)) {
389      $lines_out = null;
390      if($line == "" && $in_headers) {
391        $in_headers = false;
392      }
393      // ok we need to break this line up into several smaller lines
394      while(strlen($line) > $max_line_length) {
395        $pos = strrpos(substr($line,0,$max_line_length)," ");
396
397        // Patch to fix DOS attack
398        if(!$pos) {
399          $pos = $max_line_length - 1;
400          $lines_out[] = substr($line,0,$pos);
401          $line = substr($line,$pos);
402        } else {
403          $lines_out[] = substr($line,0,$pos);
404          $line = substr($line,$pos + 1);
405        }
406
407        /* if processing headers add a LWSP-char to the front of new line
408         * rfc 822 on long msg headers
409         */
410        if($in_headers) {
411          $line = "\t" . $line;
412        }
413      }
414      $lines_out[] = $line;
415
416      // send the lines to the server
417      while(list(,$line_out) = @each($lines_out)) {
418        if(strlen($line_out) > 0)
419        {
420          if(substr($line_out, 0, 1) == ".") {
421            $line_out = "." . $line_out;
422          }
423        }
424        fputs($this->smtp_conn,$line_out . $this->CRLF);
425      }
426    }
427
428    // message data has been sent
429    fputs($this->smtp_conn, $this->CRLF . "." . $this->CRLF);
430
431    $rply = $this->get_lines();
432    $code = substr($rply,0,3);
433
434    if($this->do_debug >= 2) {
435      echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />';
436    }
437
438    if($code != 250) {
439      $this->error =
440        array("error" => "DATA not accepted from server",
441              "smtp_code" => $code,
442              "smtp_msg" => substr($rply,4));
443      if($this->do_debug >= 1) {
444        echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
445      }
446      return false;
447    }
448    return true;
449  }
450
451  /**
452   * Sends the HELO command to the smtp server.
453   * This makes sure that we and the server are in
454   * the same known state.
455   *
456   * Implements from rfc 821: HELO <SP> <domain> <CRLF>
457   *
458   * SMTP CODE SUCCESS: 250
459   * SMTP CODE ERROR  : 500, 501, 504, 421
460   * @access public
461   * @return bool
462   */
463  public function Hello($host = '') {
464    $this->error = null; // so no confusion is caused
465
466    if(!$this->connected()) {
467      $this->error = array(
468            "error" => "Called Hello() without being connected");
469      return false;
470    }
471
472    // if hostname for HELO was not specified send default
473    if(empty($host)) {
474      // determine appropriate default to send to server
475      $host = "localhost";
476    }
477
478    // Send extended hello first (RFC 2821)
479    if(!$this->SendHello("EHLO", $host)) {
480      if(!$this->SendHello("HELO", $host)) {
481        return false;
482      }
483    }
484
485    return true;
486  }
487
488  /**
489   * Sends a HELO/EHLO command.
490   * @access private
491   * @return bool
492   */
493  private function SendHello($hello, $host) {
494    fputs($this->smtp_conn, $hello . " " . $host . $this->CRLF);
495
496    $rply = $this->get_lines();
497    $code = substr($rply,0,3);
498
499    if($this->do_debug >= 2) {
500      echo "SMTP -> FROM SERVER: " . $rply . $this->CRLF . '<br />';
501    }
502
503    if($code != 250) {
504      $this->error =
505        array("error" => $hello . " not accepted from server",
506              "smtp_code" => $code,
507              "smtp_msg" => substr($rply,4));
508      if($this->do_debug >= 1) {
509        echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
510      }
511      return false;
512    }
513
514    $this->helo_rply = $rply;
515
516    return true;
517  }
518
519  /**
520   * Starts a mail transaction from the email address specified in
521   * $from. Returns true if successful or false otherwise. If True
522   * the mail transaction is started and then one or more Recipient
523   * commands may be called followed by a Data command.
524   *
525   * Implements rfc 821: MAIL <SP> FROM:<reverse-path> <CRLF>
526   *
527   * SMTP CODE SUCCESS: 250
528   * SMTP CODE SUCCESS: 552,451,452
529   * SMTP CODE SUCCESS: 500,501,421
530   * @access public
531   * @return bool
532   */
533  public function Mail($from) {
534    $this->error = null; // so no confusion is caused
535
536    if(!$this->connected()) {
537      $this->error = array(
538              "error" => "Called Mail() without being connected");
539      return false;
540    }
541
542    $useVerp = ($this->do_verp ? "XVERP" : "");
543    fputs($this->smtp_conn,"MAIL FROM:<" . $from . ">" . $useVerp . $this->CRLF);
544
545    $rply = $this->get_lines();
546    $code = substr($rply,0,3);
547
548    if($this->do_debug >= 2) {
549      echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />';
550    }
551
552    if($code != 250) {
553      $this->error =
554        array("error" => "MAIL not accepted from server",
555              "smtp_code" => $code,
556              "smtp_msg" => substr($rply,4));
557      if($this->do_debug >= 1) {
558        echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
559      }
560      return false;
561    }
562    return true;
563  }
564
565  /**
566   * Sends the quit command to the server and then closes the socket
567   * if there is no error or the $close_on_error argument is true.
568   *
569   * Implements from rfc 821: QUIT <CRLF>
570   *
571   * SMTP CODE SUCCESS: 221
572   * SMTP CODE ERROR  : 500
573   * @access public
574   * @return bool
575   */
576  public function Quit($close_on_error = true) {
577    $this->error = null; // so there is no confusion
578
579    if(!$this->connected()) {
580      $this->error = array(
581              "error" => "Called Quit() without being connected");
582      return false;
583    }
584
585    // send the quit command to the server
586    fputs($this->smtp_conn,"quit" . $this->CRLF);
587
588    // get any good-bye messages
589    $byemsg = $this->get_lines();
590
591    if($this->do_debug >= 2) {
592      echo "SMTP -> FROM SERVER:" . $byemsg . $this->CRLF . '<br />';
593    }
594
595    $rval = true;
596    $e = null;
597
598    $code = substr($byemsg,0,3);
599    if($code != 221) {
600      // use e as a tmp var cause Close will overwrite $this->error
601      $e = array("error" => "SMTP server rejected quit command",
602                 "smtp_code" => $code,
603                 "smtp_rply" => substr($byemsg,4));
604      $rval = false;
605      if($this->do_debug >= 1) {
606        echo "SMTP -> ERROR: " . $e["error"] . ": " . $byemsg . $this->CRLF . '<br />';
607      }
608    }
609
610    if(empty($e) || $close_on_error) {
611      $this->Close();
612    }
613
614    return $rval;
615  }
616
617  /**
618   * Sends the command RCPT to the SMTP server with the TO: argument of $to.
619   * Returns true if the recipient was accepted false if it was rejected.
620   *
621   * Implements from rfc 821: RCPT <SP> TO:<forward-path> <CRLF>
622   *
623   * SMTP CODE SUCCESS: 250,251
624   * SMTP CODE FAILURE: 550,551,552,553,450,451,452
625   * SMTP CODE ERROR  : 500,501,503,421
626   * @access public
627   * @return bool
628   */
629  public function Recipient($to) {
630    $this->error = null; // so no confusion is caused
631
632    if(!$this->connected()) {
633      $this->error = array(
634              "error" => "Called Recipient() without being connected");
635      return false;
636    }
637
638    fputs($this->smtp_conn,"RCPT TO:<" . $to . ">" . $this->CRLF);
639
640    $rply = $this->get_lines();
641    $code = substr($rply,0,3);
642
643    if($this->do_debug >= 2) {
644      echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />';
645    }
646
647    if($code != 250 && $code != 251) {
648      $this->error =
649        array("error" => "RCPT not accepted from server",
650              "smtp_code" => $code,
651              "smtp_msg" => substr($rply,4));
652      if($this->do_debug >= 1) {
653        echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
654      }
655      return false;
656    }
657    return true;
658  }
659
660  /**
661   * Sends the RSET command to abort and transaction that is
662   * currently in progress. Returns true if successful false
663   * otherwise.
664   *
665   * Implements rfc 821: RSET <CRLF>
666   *
667   * SMTP CODE SUCCESS: 250
668   * SMTP CODE ERROR  : 500,501,504,421
669   * @access public
670   * @return bool
671   */
672  public function Reset() {
673    $this->error = null; // so no confusion is caused
674
675    if(!$this->connected()) {
676      $this->error = array(
677              "error" => "Called Reset() without being connected");
678      return false;
679    }
680
681    fputs($this->smtp_conn,"RSET" . $this->CRLF);
682
683    $rply = $this->get_lines();
684    $code = substr($rply,0,3);
685
686    if($this->do_debug >= 2) {
687      echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />';
688    }
689
690    if($code != 250) {
691      $this->error =
692        array("error" => "RSET failed",
693              "smtp_code" => $code,
694              "smtp_msg" => substr($rply,4));
695      if($this->do_debug >= 1) {
696        echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
697      }
698      return false;
699    }
700
701    return true;
702  }
703
704  /**
705   * Starts a mail transaction from the email address specified in
706   * $from. Returns true if successful or false otherwise. If True
707   * the mail transaction is started and then one or more Recipient
708   * commands may be called followed by a Data command. This command
709   * will send the message to the users terminal if they are logged
710   * in and send them an email.
711   *
712   * Implements rfc 821: SAML <SP> FROM:<reverse-path> <CRLF>
713   *
714   * SMTP CODE SUCCESS: 250
715   * SMTP CODE SUCCESS: 552,451,452
716   * SMTP CODE SUCCESS: 500,501,502,421
717   * @access public
718   * @return bool
719   */
720  public function SendAndMail($from) {
721    $this->error = null; // so no confusion is caused
722
723    if(!$this->connected()) {
724      $this->error = array(
725          "error" => "Called SendAndMail() without being connected");
726      return false;
727    }
728
729    fputs($this->smtp_conn,"SAML FROM:" . $from . $this->CRLF);
730
731    $rply = $this->get_lines();
732    $code = substr($rply,0,3);
733
734    if($this->do_debug >= 2) {
735      echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />';
736    }
737
738    if($code != 250) {
739      $this->error =
740        array("error" => "SAML not accepted from server",
741              "smtp_code" => $code,
742              "smtp_msg" => substr($rply,4));
743      if($this->do_debug >= 1) {
744        echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
745      }
746      return false;
747    }
748    return true;
749  }
750
751  /**
752   * This is an optional command for SMTP that this class does not
753   * support. This method is here to make the RFC821 Definition
754   * complete for this class and __may__ be implimented in the future
755   *
756   * Implements from rfc 821: TURN <CRLF>
757   *
758   * SMTP CODE SUCCESS: 250
759   * SMTP CODE FAILURE: 502
760   * SMTP CODE ERROR  : 500, 503
761   * @access public
762   * @return bool
763   */
764  public function Turn() {
765    $this->error = array("error" => "This method, TURN, of the SMTP ".
766                                    "is not implemented");
767    if($this->do_debug >= 1) {
768      echo "SMTP -> NOTICE: " . $this->error["error"] . $this->CRLF . '<br />';
769    }
770    return false;
771  }
772
773  /**
774  * Get the current error
775  * @access public
776  * @return array
777  */
778  public function getError() {
779    return $this->error;
780  }
781
782  /////////////////////////////////////////////////
783  // INTERNAL FUNCTIONS
784  /////////////////////////////////////////////////
785
786  /**
787   * Read in as many lines as possible
788   * either before eof or socket timeout occurs on the operation.
789   * With SMTP we can tell if we have more lines to read if the
790   * 4th character is '-' symbol. If it is a space then we don't
791   * need to read anything else.
792   * @access private
793   * @return string
794   */
795  private function get_lines() {
796    $data = "";
797    while($str = @fgets($this->smtp_conn,515)) {
798      if($this->do_debug >= 4) {
799        echo "SMTP -> get_lines(): \$data was \"$data\"" . $this->CRLF . '<br />';
800        echo "SMTP -> get_lines(): \$str is \"$str\"" . $this->CRLF . '<br />';
801      }
802      $data .= $str;
803      if($this->do_debug >= 4) {
804        echo "SMTP -> get_lines(): \$data is \"$data\"" . $this->CRLF . '<br />';
805      }
806      // if 4th character is a space, we are done reading, break the loop
807      if(substr($str,3,1) == " ") { break; }
808    }
809    return $data;
810  }
811
812}
813
814?>