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