[ Index ] |
|
Code source de eGroupWare 1.2.106-2 |
1 <?php 2 //////////////////////////////////////////////////// 3 // SMTP - PHP SMTP class 4 // 5 // Version 1.02 6 // 7 // Define an SMTP class that can be used to connect 8 // and communicate with any SMTP server. It implements 9 // all the SMTP functions defined in RFC821 except TURN. 10 // 11 // Author: Chris Ryan 12 // 13 // License: LGPL, see LICENSE 14 //////////////////////////////////////////////////// 15 16 /** 17 * SMTP is rfc 821 compliant and implements all the rfc 821 SMTP 18 * commands except TURN which will always return a not implemented 19 * error. SMTP also provides some utility methods for sending mail 20 * to an SMTP server. 21 * @package PHPMailer 22 * @author Chris Ryan 23 */ 24 class SMTP 25 { 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; 94 } 95 96 if(empty($port)) { 97 $port = $this->SMTP_PORT; 98 } 99 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; 116 } 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; 133 } 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 seperated 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 # get server response 369 $rply = $this->get_lines(); 370 371 # if the server is slow try to get an answer within 30 seconds 372 $timeout_counter = 0; 373 while(($rply=="") && ($timeout_counter<30)) 374 { 375 $timeout_counter+=1; 376 sleep(1); 377 $rply = $this->get_lines(); 378 } 379 # still no response to our data -> fail! 380 if($rply=="") 381 { 382 $this->error = array("error" => "timeout from server after data sent.", 383 "smtp_code" => 0, 384 "smtp_msg" => "(nothing)"); 385 386 if($this->do_debug >= 1) { 387 echo "SMTP -> ERROR: " . $this->error["error"] . 388 ": " . $rply . $this->CRLF; 389 } 390 return false; 391 } 392 393 $code = substr($rply,0,3); 394 395 if($this->do_debug >= 2) { 396 echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; 397 } 398 399 if($code != 250) { 400 $this->error = 401 array("error" => "DATA not accepted from server", 402 "smtp_code" => $code, 403 "smtp_msg" => substr($rply,4)); 404 if($this->do_debug >= 1) { 405 echo "SMTP -> ERROR: " . $this->error["error"] . 406 ": " . $rply . $this->CRLF; 407 } 408 return false; 409 } 410 return true; 411 } 412 413 /** 414 * Expand takes the name and asks the server to list all the 415 * people who are members of the _list_. Expand will return 416 * back and array of the result or false if an error occurs. 417 * Each value in the array returned has the format of: 418 * [ <full-name> <sp> ] <path> 419 * The definition of <path> is defined in rfc 821 420 * 421 * Implements rfc 821: EXPN <SP> <string> <CRLF> 422 * 423 * SMTP CODE SUCCESS: 250 424 * SMTP CODE FAILURE: 550 425 * SMTP CODE ERROR : 500,501,502,504,421 426 * @access public 427 * @return string array 428 */ 429 function Expand($name) { 430 $this->error = null; # so no confusion is caused 431 432 if(!$this->connected()) { 433 $this->error = array( 434 "error" => "Called Expand() without being connected"); 435 return false; 436 } 437 438 fputs($this->smtp_conn,"EXPN " . $name . $this->CRLF); 439 440 $rply = $this->get_lines(); 441 $code = substr($rply,0,3); 442 443 if($this->do_debug >= 2) { 444 echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; 445 } 446 447 if($code != 250) { 448 $this->error = 449 array("error" => "EXPN not accepted from server", 450 "smtp_code" => $code, 451 "smtp_msg" => substr($rply,4)); 452 if($this->do_debug >= 1) { 453 echo "SMTP -> ERROR: " . $this->error["error"] . 454 ": " . $rply . $this->CRLF; 455 } 456 return false; 457 } 458 459 # parse the reply and place in our array to return to user 460 $entries = explode($this->CRLF,$rply); 461 while(list(,$l) = @each($entries)) { 462 $list[] = substr($l,4); 463 } 464 465 return $list; 466 } 467 468 /** 469 * Sends the HELO command to the smtp server. 470 * This makes sure that we and the server are in 471 * the same known state. 472 * 473 * Implements from rfc 821: HELO <SP> <domain> <CRLF> 474 * 475 * SMTP CODE SUCCESS: 250 476 * SMTP CODE ERROR : 500, 501, 504, 421 477 * @access public 478 * @return bool 479 */ 480 function Hello($host="") { 481 $this->error = null; # so no confusion is caused 482 483 if(!$this->connected()) { 484 $this->error = array( 485 "error" => "Called Hello() without being connected"); 486 return false; 487 } 488 489 # if a hostname for the HELO wasn't specified determine 490 # a suitable one to send 491 if(empty($host)) { 492 # we need to determine some sort of appopiate default 493 # to send to the server 494 $host = "localhost"; 495 } 496 497 // Send extended hello first (RFC 2821) 498 if(!$this->SendHello("EHLO", $host)) 499 { 500 if(!$this->SendHello("HELO", $host)) 501 return false; 502 } 503 504 return true; 505 } 506 507 /** 508 * Sends a HELO/EHLO command. 509 * @access private 510 * @return bool 511 */ 512 function SendHello($hello, $host) { 513 fputs($this->smtp_conn, $hello . " " . $host . $this->CRLF); 514 515 $rply = $this->get_lines(); 516 $code = substr($rply,0,3); 517 518 if($this->do_debug >= 2) { 519 echo "SMTP -> FROM SERVER: " . $this->CRLF . $rply; 520 } 521 522 if($code != 250) { 523 $this->error = 524 array("error" => $hello . " not accepted from server", 525 "smtp_code" => $code, 526 "smtp_msg" => substr($rply,4)); 527 if($this->do_debug >= 1) { 528 echo "SMTP -> ERROR: " . $this->error["error"] . 529 ": " . $rply . $this->CRLF; 530 } 531 return false; 532 } 533 534 $this->helo_rply = $rply; 535 536 return true; 537 } 538 539 /** 540 * Gets help information on the keyword specified. If the keyword 541 * is not specified then returns generic help, ussually contianing 542 * A list of keywords that help is available on. This function 543 * returns the results back to the user. It is up to the user to 544 * handle the returned data. If an error occurs then false is 545 * returned with $this->error set appropiately. 546 * 547 * Implements rfc 821: HELP [ <SP> <string> ] <CRLF> 548 * 549 * SMTP CODE SUCCESS: 211,214 550 * SMTP CODE ERROR : 500,501,502,504,421 551 * @access public 552 * @return string 553 */ 554 function Help($keyword="") { 555 $this->error = null; # to avoid confusion 556 557 if(!$this->connected()) { 558 $this->error = array( 559 "error" => "Called Help() without being connected"); 560 return false; 561 } 562 563 $extra = ""; 564 if(!empty($keyword)) { 565 $extra = " " . $keyword; 566 } 567 568 fputs($this->smtp_conn,"HELP" . $extra . $this->CRLF); 569 570 $rply = $this->get_lines(); 571 $code = substr($rply,0,3); 572 573 if($this->do_debug >= 2) { 574 echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; 575 } 576 577 if($code != 211 && $code != 214) { 578 $this->error = 579 array("error" => "HELP not accepted from server", 580 "smtp_code" => $code, 581 "smtp_msg" => substr($rply,4)); 582 if($this->do_debug >= 1) { 583 echo "SMTP -> ERROR: " . $this->error["error"] . 584 ": " . $rply . $this->CRLF; 585 } 586 return false; 587 } 588 589 return $rply; 590 } 591 592 /** 593 * Starts a mail transaction from the email address specified in 594 * $from. Returns true if successful or false otherwise. If True 595 * the mail transaction is started and then one or more Recipient 596 * commands may be called followed by a Data command. 597 * 598 * Implements rfc 821: MAIL <SP> FROM:<reverse-path> <CRLF> 599 * 600 * SMTP CODE SUCCESS: 250 601 * SMTP CODE SUCCESS: 552,451,452 602 * SMTP CODE SUCCESS: 500,501,421 603 * @access public 604 * @return bool 605 */ 606 function Mail($from) { 607 $this->error = null; # so no confusion is caused 608 609 if(!$this->connected()) { 610 $this->error = array( 611 "error" => "Called Mail() without being connected"); 612 return false; 613 } 614 615 fputs($this->smtp_conn,"MAIL FROM:<" . $from . ">" . $this->CRLF); 616 617 $rply = $this->get_lines(); 618 $code = substr($rply,0,3); 619 620 if($this->do_debug >= 2) { 621 echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; 622 } 623 624 if($code != 250) { 625 $this->error = 626 array("error" => "MAIL not accepted from server", 627 "smtp_code" => $code, 628 "smtp_msg" => substr($rply,4)); 629 if($this->do_debug >= 1) { 630 echo "SMTP -> ERROR: " . $this->error["error"] . 631 ": " . $rply . $this->CRLF; 632 } 633 return false; 634 } 635 return true; 636 } 637 638 /** 639 * Sends the command NOOP to the SMTP server. 640 * 641 * Implements from rfc 821: NOOP <CRLF> 642 * 643 * SMTP CODE SUCCESS: 250 644 * SMTP CODE ERROR : 500, 421 645 * @access public 646 * @return bool 647 */ 648 function Noop() { 649 $this->error = null; # so no confusion is caused 650 651 if(!$this->connected()) { 652 $this->error = array( 653 "error" => "Called Noop() without being connected"); 654 return false; 655 } 656 657 fputs($this->smtp_conn,"NOOP" . $this->CRLF); 658 659 $rply = $this->get_lines(); 660 $code = substr($rply,0,3); 661 662 if($this->do_debug >= 2) { 663 echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; 664 } 665 666 if($code != 250) { 667 $this->error = 668 array("error" => "NOOP not accepted from server", 669 "smtp_code" => $code, 670 "smtp_msg" => substr($rply,4)); 671 if($this->do_debug >= 1) { 672 echo "SMTP -> ERROR: " . $this->error["error"] . 673 ": " . $rply . $this->CRLF; 674 } 675 return false; 676 } 677 return true; 678 } 679 680 /** 681 * Sends the quit command to the server and then closes the socket 682 * if there is no error or the $close_on_error argument is true. 683 * 684 * Implements from rfc 821: QUIT <CRLF> 685 * 686 * SMTP CODE SUCCESS: 221 687 * SMTP CODE ERROR : 500 688 * @access public 689 * @return bool 690 */ 691 function Quit($close_on_error=true) { 692 $this->error = null; # so there is no confusion 693 694 if(!$this->connected()) { 695 $this->error = array( 696 "error" => "Called Quit() without being connected"); 697 return false; 698 } 699 700 # send the quit command to the server 701 fputs($this->smtp_conn,"quit" . $this->CRLF); 702 703 # get any good-bye messages 704 $byemsg = $this->get_lines(); 705 706 if($this->do_debug >= 2) { 707 echo "SMTP -> FROM SERVER:" . $this->CRLF . $byemsg; 708 } 709 710 $rval = true; 711 $e = null; 712 713 $code = substr($byemsg,0,3); 714 if($code != 221) { 715 # use e as a tmp var cause Close will overwrite $this->error 716 $e = array("error" => "SMTP server rejected quit command", 717 "smtp_code" => $code, 718 "smtp_rply" => substr($byemsg,4)); 719 $rval = false; 720 if($this->do_debug >= 1) { 721 echo "SMTP -> ERROR: " . $e["error"] . ": " . 722 $byemsg . $this->CRLF; 723 } 724 } 725 726 if(empty($e) || $close_on_error) { 727 $this->Close(); 728 } 729 730 return $rval; 731 } 732 733 /** 734 * Sends the command RCPT to the SMTP server with the TO: argument of $to. 735 * Returns true if the recipient was accepted false if it was rejected. 736 * 737 * Implements from rfc 821: RCPT <SP> TO:<forward-path> <CRLF> 738 * 739 * SMTP CODE SUCCESS: 250,251 740 * SMTP CODE FAILURE: 550,551,552,553,450,451,452 741 * SMTP CODE ERROR : 500,501,503,421 742 * @access public 743 * @return bool 744 */ 745 function Recipient($to) { 746 $this->error = null; # so no confusion is caused 747 748 if(!$this->connected()) { 749 $this->error = array( 750 "error" => "Called Recipient() without being connected"); 751 return false; 752 } 753 754 fputs($this->smtp_conn,"RCPT TO:<" . $to . ">" . $this->CRLF); 755 756 $rply = $this->get_lines(); 757 $code = substr($rply,0,3); 758 759 if($this->do_debug >= 2) { 760 echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; 761 } 762 763 if($code != 250 && $code != 251) { 764 $this->error = 765 array("error" => "RCPT not accepted from server", 766 "smtp_code" => $code, 767 "smtp_msg" => substr($rply,4)); 768 if($this->do_debug >= 1) { 769 echo "SMTP -> ERROR: " . $this->error["error"] . 770 ": " . $rply . $this->CRLF; 771 } 772 return false; 773 } 774 return true; 775 } 776 777 /** 778 * Sends the RSET command to abort and transaction that is 779 * currently in progress. Returns true if successful false 780 * otherwise. 781 * 782 * Implements rfc 821: RSET <CRLF> 783 * 784 * SMTP CODE SUCCESS: 250 785 * SMTP CODE ERROR : 500,501,504,421 786 * @access public 787 * @return bool 788 */ 789 function Reset() { 790 $this->error = null; # so no confusion is caused 791 792 if(!$this->connected()) { 793 $this->error = array( 794 "error" => "Called Reset() without being connected"); 795 return false; 796 } 797 798 fputs($this->smtp_conn,"RSET" . $this->CRLF); 799 800 $rply = $this->get_lines(); 801 $code = substr($rply,0,3); 802 803 if($this->do_debug >= 2) { 804 echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; 805 } 806 807 if($code != 250) { 808 $this->error = 809 array("error" => "RSET failed", 810 "smtp_code" => $code, 811 "smtp_msg" => substr($rply,4)); 812 if($this->do_debug >= 1) { 813 echo "SMTP -> ERROR: " . $this->error["error"] . 814 ": " . $rply . $this->CRLF; 815 } 816 return false; 817 } 818 819 return true; 820 } 821 822 /** 823 * Starts a mail transaction from the email address specified in 824 * $from. Returns true if successful or false otherwise. If True 825 * the mail transaction is started and then one or more Recipient 826 * commands may be called followed by a Data command. This command 827 * will send the message to the users terminal if they are logged 828 * in. 829 * 830 * Implements rfc 821: SEND <SP> FROM:<reverse-path> <CRLF> 831 * 832 * SMTP CODE SUCCESS: 250 833 * SMTP CODE SUCCESS: 552,451,452 834 * SMTP CODE SUCCESS: 500,501,502,421 835 * @access public 836 * @return bool 837 */ 838 function Send($from) { 839 $this->error = null; # so no confusion is caused 840 841 if(!$this->connected()) { 842 $this->error = array( 843 "error" => "Called Send() without being connected"); 844 return false; 845 } 846 847 fputs($this->smtp_conn,"SEND FROM:" . $from . $this->CRLF); 848 849 $rply = $this->get_lines(); 850 $code = substr($rply,0,3); 851 852 if($this->do_debug >= 2) { 853 echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; 854 } 855 856 if($code != 250) { 857 $this->error = 858 array("error" => "SEND not accepted from server", 859 "smtp_code" => $code, 860 "smtp_msg" => substr($rply,4)); 861 if($this->do_debug >= 1) { 862 echo "SMTP -> ERROR: " . $this->error["error"] . 863 ": " . $rply . $this->CRLF; 864 } 865 return false; 866 } 867 return true; 868 } 869 870 /** 871 * Starts a mail transaction from the email address specified in 872 * $from. Returns true if successful or false otherwise. If True 873 * the mail transaction is started and then one or more Recipient 874 * commands may be called followed by a Data command. This command 875 * will send the message to the users terminal if they are logged 876 * in and send them an email. 877 * 878 * Implements rfc 821: SAML <SP> FROM:<reverse-path> <CRLF> 879 * 880 * SMTP CODE SUCCESS: 250 881 * SMTP CODE SUCCESS: 552,451,452 882 * SMTP CODE SUCCESS: 500,501,502,421 883 * @access public 884 * @return bool 885 */ 886 function SendAndMail($from) { 887 $this->error = null; # so no confusion is caused 888 889 if(!$this->connected()) { 890 $this->error = array( 891 "error" => "Called SendAndMail() without being connected"); 892 return false; 893 } 894 895 fputs($this->smtp_conn,"SAML FROM:" . $from . $this->CRLF); 896 897 $rply = $this->get_lines(); 898 $code = substr($rply,0,3); 899 900 if($this->do_debug >= 2) { 901 echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; 902 } 903 904 if($code != 250) { 905 $this->error = 906 array("error" => "SAML not accepted from server", 907 "smtp_code" => $code, 908 "smtp_msg" => substr($rply,4)); 909 if($this->do_debug >= 1) { 910 echo "SMTP -> ERROR: " . $this->error["error"] . 911 ": " . $rply . $this->CRLF; 912 } 913 return false; 914 } 915 return true; 916 } 917 918 /** 919 * Starts a mail transaction from the email address specified in 920 * $from. Returns true if successful or false otherwise. If True 921 * the mail transaction is started and then one or more Recipient 922 * commands may be called followed by a Data command. This command 923 * will send the message to the users terminal if they are logged 924 * in or mail it to them if they are not. 925 * 926 * Implements rfc 821: SOML <SP> FROM:<reverse-path> <CRLF> 927 * 928 * SMTP CODE SUCCESS: 250 929 * SMTP CODE SUCCESS: 552,451,452 930 * SMTP CODE SUCCESS: 500,501,502,421 931 * @access public 932 * @return bool 933 */ 934 function SendOrMail($from) { 935 $this->error = null; # so no confusion is caused 936 937 if(!$this->connected()) { 938 $this->error = array( 939 "error" => "Called SendOrMail() without being connected"); 940 return false; 941 } 942 943 fputs($this->smtp_conn,"SOML FROM:" . $from . $this->CRLF); 944 945 $rply = $this->get_lines(); 946 $code = substr($rply,0,3); 947 948 if($this->do_debug >= 2) { 949 echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; 950 } 951 952 if($code != 250) { 953 $this->error = 954 array("error" => "SOML not accepted from server", 955 "smtp_code" => $code, 956 "smtp_msg" => substr($rply,4)); 957 if($this->do_debug >= 1) { 958 echo "SMTP -> ERROR: " . $this->error["error"] . 959 ": " . $rply . $this->CRLF; 960 } 961 return false; 962 } 963 return true; 964 } 965 966 /** 967 * This is an optional command for SMTP that this class does not 968 * support. This method is here to make the RFC821 Definition 969 * complete for this class and __may__ be implimented in the future 970 * 971 * Implements from rfc 821: TURN <CRLF> 972 * 973 * SMTP CODE SUCCESS: 250 974 * SMTP CODE FAILURE: 502 975 * SMTP CODE ERROR : 500, 503 976 * @access public 977 * @return bool 978 */ 979 function Turn() { 980 $this->error = array("error" => "This method, TURN, of the SMTP ". 981 "is not implemented"); 982 if($this->do_debug >= 1) { 983 echo "SMTP -> NOTICE: " . $this->error["error"] . $this->CRLF; 984 } 985 return false; 986 } 987 988 /** 989 * Verifies that the name is recognized by the server. 990 * Returns false if the name could not be verified otherwise 991 * the response from the server is returned. 992 * 993 * Implements rfc 821: VRFY <SP> <string> <CRLF> 994 * 995 * SMTP CODE SUCCESS: 250,251 996 * SMTP CODE FAILURE: 550,551,553 997 * SMTP CODE ERROR : 500,501,502,421 998 * @access public 999 * @return int 1000 */ 1001 function Verify($name) { 1002 $this->error = null; # so no confusion is caused 1003 1004 if(!$this->connected()) { 1005 $this->error = array( 1006 "error" => "Called Verify() without being connected"); 1007 return false; 1008 } 1009 1010 fputs($this->smtp_conn,"VRFY " . $name . $this->CRLF); 1011 1012 $rply = $this->get_lines(); 1013 $code = substr($rply,0,3); 1014 1015 if($this->do_debug >= 2) { 1016 echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; 1017 } 1018 1019 if($code != 250 && $code != 251) { 1020 $this->error = 1021 array("error" => "VRFY failed on name '$name'", 1022 "smtp_code" => $code, 1023 "smtp_msg" => substr($rply,4)); 1024 if($this->do_debug >= 1) { 1025 echo "SMTP -> ERROR: " . $this->error["error"] . 1026 ": " . $rply . $this->CRLF; 1027 } 1028 return false; 1029 } 1030 return $rply; 1031 } 1032 1033 /******************************************************************* 1034 * INTERNAL FUNCTIONS * 1035 ******************************************************************/ 1036 1037 /** 1038 * Read in as many lines as possible 1039 * either before eof or socket timeout occurs on the operation. 1040 * With SMTP we can tell if we have more lines to read if the 1041 * 4th character is '-' symbol. If it is a space then we don't 1042 * need to read anything else. 1043 * @access private 1044 * @return string 1045 */ 1046 function get_lines() { 1047 $data = ""; 1048 while($str = fgets($this->smtp_conn,515)) { 1049 if($this->do_debug >= 4) { 1050 echo "SMTP -> get_lines(): \$data was \"$data\"" . 1051 $this->CRLF; 1052 echo "SMTP -> get_lines(): \$str is \"$str\"" . 1053 $this->CRLF; 1054 } 1055 $data .= $str; 1056 if($this->do_debug >= 4) { 1057 echo "SMTP -> get_lines(): \$data is \"$data\"" . $this->CRLF; 1058 } 1059 # if the 4th character is a space then we are done reading 1060 # so just break the loop 1061 if(substr($str,3,1) == " ") { break; } 1062 } 1063 return $data; 1064 } 1065 1066 } 1067 1068 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Sun Feb 25 17:20:01 2007 | par Balluche grâce à PHPXref 0.7 |