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?>