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