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