SMTP

PHPMailer RFC821 SMTP email transport class.

Defined (1)

The class is defined in the following location(s).

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