Source for file class.smtp.php

Documentation is available at class.smtp.php

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

Documentation generated on Thu, 02 Apr 2009 21:19:51 -0400 by phpDocumentor 1.3.0RC3