优惠券订单及其他脚本

ClassSmtp.php 36KB

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