/bp-forums/bbpress/bb-includes/backpress/class.mailer-smtp.php

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