jablonka.czprosek.czf

freenet-router

Subversion Repositories:
[/] [trunk/] [freenet-router/] [var/] [www/] [freenet-router/] [Framework/] [3rdParty/] [PHPMailer/] [PHPMailer/] [class.smtp.php] - Blame information for rev 2

 

Line No. Rev Author Line
12simandl<?php
2/**
3 * PHPMailer RFC821 SMTP email transport class.
4 * Version 5.2.7
5 * PHP version 5.0.0
6 * @category PHP
7 * @package PHPMailer
8 * @link https://github.com/PHPMailer/PHPMailer/
9 * @author Marcus Bointon (coolbru) <phpmailer@synchromedia.co.uk>
10 * @author Jim Jagielski (jimjag) <jimjag@gmail.com>
11 * @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
12 * @copyright 2013 Marcus Bointon
13 * @copyright 2004 - 2008 Andy Prevost
14 * @copyright 2010 - 2012 Jim Jagielski
15 * @license http://www.gnu.org/copyleft/lesser.html Distributed under the Lesser General Public License (LGPL)
16 */
17 
18/**
19 * PHPMailer RFC821 SMTP email transport class.
20 *
21 * Implements RFC 821 SMTP commands
22 * and provides some utility methods for sending mail to an SMTP server.
23 *
24 * PHP Version 5.0.0
25 *
26 * @category PHP
27 * @package PHPMailer
28 * @link https://github.com/PHPMailer/PHPMailer/blob/master/class.smtp.php
29 * @author Chris Ryan <unknown@example.com>
30 * @author Marcus Bointon <phpmailer@synchromedia.co.uk>
31 * @license http://www.gnu.org/copyleft/lesser.html Distributed under the Lesser General Public License (LGPL)
32 */
33 
34class SMTP
35{
36 /**
37 * The PHPMailer SMTP Version number.
38 */
39 const VERSION = '5.2.7';
40 
41 /**
42 * SMTP line break constant.
43 */
44 const CRLF = "\r\n";
45 
46 /**
47 * The SMTP port to use if one is not specified.
48 */
49 const DEFAULT_SMTP_PORT = 25;
50 
51 /**
52 * The maximum line length allowed by RFC 2822 section 2.1.1
53 */
54 const MAX_LINE_LENGTH = 998;
55 
56 /**
57 * The PHPMailer SMTP Version number.
58 * @type string
59 * @deprecated This should be a constant
60 * @see SMTP::VERSION
61 */
62 public $Version = '5.2.7';
63 
64 /**
65 * SMTP server port number.
66 * @type int
67 * @deprecated This is only ever ued as default value, so should be a constant
68 * @see SMTP::DEFAULT_SMTP_PORT
69 */
70 public $SMTP_PORT = 25;
71 
72 /**
73 * SMTP reply line ending
74 * @type string
75 * @deprecated Use the class constant instead
76 * @see SMTP::CRLF
77 */
78 public $CRLF = "\r\n";
79 
80 /**
81 * Debug output level.
82 * Options:
83 * 0: no output
84 * 1: commands
85 * 2: data and commands
86 * 3: as 2 plus connection status
87 * 4: low level data output
88 * @type int
89 */
90 public $do_debug = 0;
91 
92 /**
93 * The function/method to use for debugging output.
94 * Options: 'echo', 'html' or 'error_log'
95 * @type string
96 */
97 public $Debugoutput = 'echo';
98 
99 /**
100 * Whether to use VERP.
101 * @type bool
102 */
103 public $do_verp = false;
104 
105 /**
106 * The timeout value for connection, in seconds.
107 * Default of 5 minutes (300sec) is from RFC2821 section 4.5.3.2
108 * @type int
109 */
110 public $Timeout = 300;
111 
112 /**
113 * The SMTP timelimit value for reads, in seconds.
114 * @type int
115 */
116 public $Timelimit = 30;
117 
118 /**
119 * The socket for the server connection.
120 * @type resource
121 */
122 protected $smtp_conn;
123 
124 /**
125 * Error message, if any, for the last call.
126 * @type string
127 */
128 protected $error = '';
129 
130 /**
131 * The reply the server sent to us for HELO.
132 * @type string
133 */
134 protected $helo_rply = '';
135 
136 /**
137 * The most recent reply received from the server.
138 * @type string
139 */
140 protected $last_reply = '';
141 
142 /**
143 * Constructor.
144 * @access public
145 */
146 public function __construct()
147 {
148 $this->smtp_conn = 0;
149 $this->error = null;
150 $this->helo_rply = null;
151 
152 $this->do_debug = 0;
153 }
154 
155 /**
156 * Output debugging info via a user-selected method.
157 * @param string $str Debug string to output
158 * @return void
159 */
160 protected function edebug($str)
161 {
162 switch ($this->Debugoutput) {
163 case 'error_log':
164 //Don't output, just log
165 error_log($str);
166 break;
167 case 'html':
168 //Cleans up output a bit for a better looking, HTML-safe output
169 echo htmlentities(
170 preg_replace('/[\r\n]+/', '', $str),
171 ENT_QUOTES,
172 'UTF-8'
173 )
174 . "<br>\n";
175 break;
176 case 'echo':
177 default:
178 echo gmdate('Y-m-d H:i:s')."\t".trim($str)."\n";
179 }
180 }
181 
182 /**
183 * Connect to an SMTP server.
184 * @param string $host SMTP server IP or host name
185 * @param int $port The port number to connect to
186 * @param int $timeout How long to wait for the connection to open
187 * @param array $options An array of options for stream_context_create()
188 * @access public
189 * @return bool
190 */
191 public function connect($host, $port = null, $timeout = 30, $options = array())
192 {
193 // Clear errors to avoid confusion
194 $this->error = null;
195 // Make sure we are __not__ connected
196 if ($this->connected()) {
197 // Already connected, generate error
198 $this->error = array('error' => 'Already connected to a server');
199 return false;
200 }
201 if (empty($port)) {
202 $port = self::DEFAULT_SMTP_PORT;
203 }
204 // Connect to the SMTP server
205 if ($this->do_debug >= 3) {
206 $this->edebug('Connection: opening');
207 }
208 $errno = 0;
209 $errstr = '';
210 $socket_context = stream_context_create($options);
211 //Suppress errors; connection failures are handled at a higher level
212 $this->smtp_conn = @stream_socket_client(
213 $host . ":" . $port,
214 $errno,
215 $errstr,
216 $timeout,
217 STREAM_CLIENT_CONNECT,
218 $socket_context
219 );
220 // Verify we connected properly
221 if (empty($this->smtp_conn)) {
222 $this->error = array(
223 'error' => 'Failed to connect to server',
224 'errno' => $errno,
225 'errstr' => $errstr
226 );
227 if ($this->do_debug >= 1) {
228 $this->edebug(
229 'SMTP ERROR: ' . $this->error['error']
230 . ": $errstr ($errno)"
231 );
232 }
233 return false;
234 }
235 if ($this->do_debug >= 3) {
236 $this->edebug('Connection: opened');
237 }
238 // SMTP server can take longer to respond, give longer timeout for first read
239 // Windows does not have support for this timeout function
240 if (substr(PHP_OS, 0, 3) != 'WIN') {
241 $max = ini_get('max_execution_time');
242 if ($max != 0 && $timeout > $max) { // Don't bother if unlimited
243 @set_time_limit($timeout);
244 }
245 stream_set_timeout($this->smtp_conn, $timeout, 0);
246 }
247 // Get any announcement
248 $announce = $this->get_lines();
249 if ($this->do_debug >= 2) {
250 $this->edebug('SERVER -> CLIENT: ' . $announce);
251 }
252 return true;
253 }
254 
255 /**
256 * Initiate a TLS (encrypted) session.
257 * @access public
258 * @return bool
259 */
260 public function startTLS()
261 {
262 if (!$this->sendCommand('STARTTLS', 'STARTTLS', 220)) {
263 return false;
264 }
265 // Begin encrypted connection
266 if (!stream_socket_enable_crypto(
267 $this->smtp_conn,
268 true,
269 STREAM_CRYPTO_METHOD_TLS_CLIENT
270 )) {
271 return false;
272 }
273 return true;
274 }
275 
276 /**
277 * Perform SMTP authentication.
278 * Must be run after hello().
279 * @see hello()
280 * @param string $username The user name
281 * @param string $password The password
282 * @param string $authtype The auth type (PLAIN, LOGIN, NTLM, CRAM-MD5)
283 * @param string $realm The auth realm for NTLM
284 * @param string $workstation The auth workstation for NTLM
285 * @access public
286 * @return bool True if successfully authenticated.
287 */
288 public function authenticate(
289 $username,
290 $password,
291 $authtype = 'LOGIN',
292 $realm = '',
293 $workstation = ''
294 ) {
295 if (empty($authtype)) {
296 $authtype = 'LOGIN';
297 }
298 switch ($authtype) {
299 case 'PLAIN':
300 // Start authentication
301 if (!$this->sendCommand('AUTH', 'AUTH PLAIN', 334)) {
302 return false;
303 }
304 // Send encoded username and password
305 if (!$this->sendCommand(
306 'User & Password',
307 base64_encode("\0" . $username . "\0" . $password),
308 235
309 )
310 ) {
311 return false;
312 }
313 break;
314 case 'LOGIN':
315 // Start authentication
316 if (!$this->sendCommand('AUTH', 'AUTH LOGIN', 334)) {
317 return false;
318 }
319 if (!$this->sendCommand("Username", base64_encode($username), 334)) {
320 return false;
321 }
322 if (!$this->sendCommand("Password", base64_encode($password), 235)) {
323 return false;
324 }
325 break;
326 case 'NTLM':
327 /*
328 * ntlm_sasl_client.php
329 * Bundled with Permission
330 *
331 * How to telnet in windows:
332 * http://technet.microsoft.com/en-us/library/aa995718%28EXCHG.65%29.aspx
333 * PROTOCOL Docs http://curl.haxx.se/rfc/ntlm.html#ntlmSmtpAuthentication
334 */
335 require_once 'extras/ntlm_sasl_client.php';
336 $temp = new stdClass();
337 $ntlm_client = new ntlm_sasl_client_class;
338 //Check that functions are available
339 if (!$ntlm_client->Initialize($temp)) {
340 $this->error = array('error' => $temp->error);
341 if ($this->do_debug >= 1) {
342 $this->edebug(
343 'You need to enable some modules in your php.ini file: '
344 . $this->error['error']
345 );
346 }
347 return false;
348 }
349 //msg1
350 $msg1 = $ntlm_client->TypeMsg1($realm, $workstation); //msg1
351 
352 if (!$this->sendCommand(
353 'AUTH NTLM',
354 'AUTH NTLM ' . base64_encode($msg1),
355 334
356 )
357 ) {
358 return false;
359 }
360 //Though 0 based, there is a white space after the 3 digit number
361 //msg2
362 $challenge = substr($this->last_reply, 3);
363 $challenge = base64_decode($challenge);
364 $ntlm_res = $ntlm_client->NTLMResponse(
365 substr($challenge, 24, 8),
366 $password
367 );
368 //msg3
369 $msg3 = $ntlm_client->TypeMsg3(
370 $ntlm_res,
371 $username,
372 $realm,
373 $workstation
374 );
375 // send encoded username
376 return $this->sendCommand('Username', base64_encode($msg3), 235);
377 break;
378 case 'CRAM-MD5':
379 // Start authentication
380 if (!$this->sendCommand('AUTH CRAM-MD5', 'AUTH CRAM-MD5', 334)) {
381 return false;
382 }
383 // Get the challenge
384 $challenge = base64_decode(substr($this->last_reply, 4));
385 
386 // Build the response
387 $response = $username . ' ' . $this->hmac($challenge, $password);
388 
389 // send encoded credentials
390 return $this->sendCommand('Username', base64_encode($response), 235);
391 break;
392 }
393 return true;
394 }
395 
396 /**
397 * Calculate an MD5 HMAC hash.
398 * Works like hash_hmac('md5', $data, $key)
399 * in case that function is not available
400 * @param string $data The data to hash
401 * @param string $key The key to hash with
402 * @access protected
403 * @return string
404 */
405 protected function hmac($data, $key)
406 {
407 if (function_exists('hash_hmac')) {
408 return hash_hmac('md5', $data, $key);
409 }
410 
411 // The following borrowed from
412 // http://php.net/manual/en/function.mhash.php#27225
413 
414 // RFC 2104 HMAC implementation for php.
415 // Creates an md5 HMAC.
416 // Eliminates the need to install mhash to compute a HMAC
417 // Hacked by Lance Rushing
418 
419 $b = 64; // byte length for md5
420 if (strlen($key) > $b) {
421 $key = pack('H*', md5($key));
422 }
423 $key = str_pad($key, $b, chr(0x00));
424 $ipad = str_pad('', $b, chr(0x36));
425 $opad = str_pad('', $b, chr(0x5c));
426 $k_ipad = $key ^ $ipad;
427 $k_opad = $key ^ $opad;
428 
429 return md5($k_opad . pack('H*', md5($k_ipad . $data)));
430 }
431 
432 /**
433 * Check connection state.
434 * @access public
435 * @return bool True if connected.
436 */
437 public function connected()
438 {
439 if (!empty($this->smtp_conn)) {
440 $sock_status = stream_get_meta_data($this->smtp_conn);
441 if ($sock_status['eof']) {
442 // the socket is valid but we are not connected
443 if ($this->do_debug >= 1) {
444 $this->edebug(
445 'SMTP NOTICE: EOF caught while checking if connected'
446 );
447 }
448 $this->close();
449 return false;
450 }
451 return true; // everything looks good
452 }
453 return false;
454 }
455 
456 /**
457 * Close the socket and clean up the state of the class.
458 * Don't use this function without first trying to use QUIT.
459 * @see quit()
460 * @access public
461 * @return void
462 */
463 public function close()
464 {
465 $this->error = null; // so there is no confusion
466 $this->helo_rply = null;
467 if (!empty($this->smtp_conn)) {
468 // close the connection and cleanup
469 fclose($this->smtp_conn);
470 if ($this->do_debug >= 3) {
471 $this->edebug('Connection: closed');
472 }
473 $this->smtp_conn = 0;
474 }
475 }
476 
477 /**
478 * Send an SMTP DATA command.
479 * Issues a data command and sends the msg_data to the server,
480 * finializing the mail transaction. $msg_data is the message
481 * that is to be send with the headers. Each header needs to be
482 * on a single line followed by a <CRLF> with the message headers
483 * and the message body being separated by and additional <CRLF>.
484 * Implements rfc 821: DATA <CRLF>
485 * @param string $msg_data Message data to send
486 * @access public
487 * @return bool
488 */
489 public function data($msg_data)
490 {
491 if (!$this->sendCommand('DATA', 'DATA', 354)) {
492 return false;
493 }
494 /* The server is ready to accept data!
495 * According to rfc821 we should not send more than 1000 characters on a single line (including the CRLF)
496 * so we will break the data up into lines by \r and/or \n then if needed we will break each of those into
497 * smaller lines to fit within the limit.
498 * We will also look for lines that start with a '.' and prepend an additional '.'.
499 * NOTE: this does not count towards line-length limit.
500 */
501 
502 // Normalize line breaks before exploding
503 $lines = explode("\n", str_replace(array("\r\n", "\r"), "\n", $msg_data));
504 
505 /* To distinguish between a complete RFC822 message and a plain message body, we check if the first field
506 * of the first line (':' separated) does not contain a space then it _should_ be a header and we will
507 * process all lines before a blank line as headers.
508 */
509 
510 $field = substr($lines[0], 0, strpos($lines[0], ':'));
511 $in_headers = false;
512 if (!empty($field) && strpos($field, ' ') === false) {
513 $in_headers = true;
514 }
515 
516 foreach ($lines as $line) {
517 $lines_out = array();
518 if ($in_headers and $line == '') {
519 $in_headers = false;
520 }
521 // ok we need to break this line up into several smaller lines
522 //This is a small micro-optimisation: isset($str[$len]) is equivalent to (strlen($str) > $len)
523 while (isset($line[self::MAX_LINE_LENGTH])) {
524 //Working backwards, try to find a space within the last MAX_LINE_LENGTH chars of the line to break on
525 //so as to avoid breaking in the middle of a word
526 $pos = strrpos(substr($line, 0, self::MAX_LINE_LENGTH), ' ');
527 if (!$pos) { //Deliberately matches both false and 0
528 //No nice break found, add a hard break
529 $pos = self::MAX_LINE_LENGTH - 1;
530 $lines_out[] = substr($line, 0, $pos);
531 $line = substr($line, $pos);
532 } else {
533 //Break at the found point
534 $lines_out[] = substr($line, 0, $pos);
535 //Move along by the amount we dealt with
536 $line = substr($line, $pos + 1);
537 }
538 /* If processing headers add a LWSP-char to the front of new line
539 * RFC822 section 3.1.1
540 */
541 if ($in_headers) {
542 $line = "\t" . $line;
543 }
544 }
545 $lines_out[] = $line;
546 
547 // Send the lines to the server
548 foreach ($lines_out as $line_out) {
549 //RFC2821 section 4.5.2
550 if (!empty($line_out) and $line_out[0] == '.') {
551 $line_out = '.' . $line_out;
552 }
553 $this->client_send($line_out . self::CRLF);
554 }
555 }
556 
557 // Message data has been sent, complete the command
558 return $this->sendCommand('DATA END', '.', 250);
559 }
560 
561 /**
562 * Send an SMTP HELO or EHLO command.
563 * Used to identify the sending server to the receiving server.
564 * This makes sure that client and server are in a known state.
565 * Implements RFC 821: HELO <SP> <domain> <CRLF>
566 * and RFC 2821 EHLO.
567 * @param string $host The host name or IP to connect to
568 * @access public
569 * @return bool
570 */
571 public function hello($host = '')
572 {
573 // Try extended hello first (RFC 2821)
574 return (bool)($this->sendHello('EHLO', $host) or $this->sendHello('HELO', $host));
575 }
576 
577 /**
578 * Send an SMTP HELO or EHLO command.
579 * Low-level implementation used by hello()
580 * @see hello()
581 * @param string $hello The HELO string
582 * @param string $host The hostname to say we are
583 * @access protected
584 * @return bool
585 */
586 protected function sendHello($hello, $host)
587 {
588 $noerror = $this->sendCommand($hello, $hello . ' ' . $host, 250);
589 $this->helo_rply = $this->last_reply;
590 return $noerror;
591 }
592 
593 /**
594 * Send an SMTP MAIL command.
595 * Starts a mail transaction from the email address specified in
596 * $from. Returns true if successful or false otherwise. If True
597 * the mail transaction is started and then one or more recipient
598 * commands may be called followed by a data command.
599 * Implements rfc 821: MAIL <SP> FROM:<reverse-path> <CRLF>
600 * @param string $from Source address of this message
601 * @access public
602 * @return bool
603 */
604 public function mail($from)
605 {
606 $useVerp = ($this->do_verp ? ' XVERP' : '');
607 return $this->sendCommand(
608 'MAIL FROM',
609 'MAIL FROM:<' . $from . '>' . $useVerp,
610 250
611 );
612 }
613 
614 /**
615 * Send an SMTP QUIT command.
616 * Closes the socket if there is no error or the $close_on_error argument is true.
617 * Implements from rfc 821: QUIT <CRLF>
618 * @param bool $close_on_error Should the connection close if an error occurs?
619 * @access public
620 * @return bool
621 */
622 public function quit($close_on_error = true)
623 {
624 $noerror = $this->sendCommand('QUIT', 'QUIT', 221);
625 $e = $this->error; //Save any error
626 if ($noerror or $close_on_error) {
627 $this->close();
628 $this->error = $e; //Restore any error from the quit command
629 }
630 return $noerror;
631 }
632 
633 /**
634 * Send an SMTP RCPT command.
635 * Sets the TO argument to $to.
636 * Returns true if the recipient was accepted false if it was rejected.
637 * Implements from rfc 821: RCPT <SP> TO:<forward-path> <CRLF>
638 * @param string $to The address the message is being sent to
639 * @access public
640 * @return bool
641 */
642 public function recipient($to)
643 {
644 return $this->sendCommand(
645 'RCPT TO',
646 'RCPT TO:<' . $to . '>',
647 array(250, 251)
648 );
649 }
650 
651 /**
652 * Send an SMTP RSET command.
653 * Abort any transaction that is currently in progress.
654 * Implements rfc 821: RSET <CRLF>
655 * @access public
656 * @return bool True on success.
657 */
658 public function reset()
659 {
660 return $this->sendCommand('RSET', 'RSET', 250);
661 }
662 
663 /**
664 * Send a command to an SMTP server and check its return code.
665 * @param string $command The command name - not sent to the server
666 * @param string $commandstring The actual command to send
667 * @param int|array $expect One or more expected integer success codes
668 * @access protected
669 * @return bool True on success.
670 */
671 protected function sendCommand($command, $commandstring, $expect)
672 {
673 if (!$this->connected()) {
674 $this->error = array(
675 'error' => "Called $command without being connected"
676 );
677 return false;
678 }
679 $this->client_send($commandstring . self::CRLF);
680 
681 $reply = $this->get_lines();
682 $code = substr($reply, 0, 3);
683 
684 if ($this->do_debug >= 2) {
685 $this->edebug('SERVER -> CLIENT: ' . $reply);
686 }
687 
688 if (!in_array($code, (array)$expect)) {
689 $this->last_reply = null;
690 $this->error = array(
691 'error' => "$command command failed",
692 'smtp_code' => $code,
693 'detail' => substr($reply, 4)
694 );
695 if ($this->do_debug >= 1) {
696 $this->edebug(
697 'SMTP ERROR: ' . $this->error['error'] . ': ' . $reply
698 );
699 }
700 return false;
701 }
702 
703 $this->last_reply = $reply;
704 $this->error = null;
705 return true;
706 }
707 
708 /**
709 * Send an SMTP SAML command.
710 * Starts a mail transaction from the email address specified in $from.
711 * Returns true if successful or false otherwise. If True
712 * the mail transaction is started and then one or more recipient
713 * commands may be called followed by a data command. This command
714 * will send the message to the users terminal if they are logged
715 * in and send them an email.
716 * Implements rfc 821: SAML <SP> FROM:<reverse-path> <CRLF>
717 * @param string $from The address the message is from
718 * @access public
719 * @return bool
720 */
721 public function sendAndMail($from)
722 {
723 return $this->sendCommand('SAML', "SAML FROM:$from", 250);
724 }
725 
726 /**
727 * Send an SMTP VRFY command.
728 * @param string $name The name to verify
729 * @access public
730 * @return bool
731 */
732 public function verify($name)
733 {
734 return $this->sendCommand('VRFY', "VRFY $name", array(250, 251));
735 }
736 
737 /**
738 * Send an SMTP NOOP command.
739 * Used to keep keep-alives alive, doesn't actually do anything
740 * @access public
741 * @return bool
742 */
743 public function noop()
744 {
745 return $this->sendCommand('NOOP', 'NOOP', 250);
746 }
747 
748 /**
749 * Send an SMTP TURN command.
750 * This is an optional command for SMTP that this class does not support.
751 * This method is here to make the RFC821 Definition complete for this class
752 * and _may_ be implemented in future
753 * Implements from rfc 821: TURN <CRLF>
754 * @access public
755 * @return bool
756 */
757 public function turn()
758 {
759 $this->error = array(
760 'error' => 'The SMTP TURN command is not implemented'
761 );
762 if ($this->do_debug >= 1) {
763 $this->edebug('SMTP NOTICE: ' . $this->error['error']);
764 }
765 return false;
766 }
767 
768 /**
769 * Send raw data to the server.
770 * @param string $data The data to send
771 * @access public
772 * @return int|bool The number of bytes sent to the server or false on error
773 */
774 public function client_send($data)
775 {
776 if ($this->do_debug >= 1) {
777 $this->edebug("CLIENT -> SERVER: $data");
778 }
779 return fwrite($this->smtp_conn, $data);
780 }
781 
782 /**
783 * Get the latest error.
784 * @access public
785 * @return array
786 */
787 public function getError()
788 {
789 return $this->error;
790 }
791 
792 /**
793 * Get the last reply from the server.
794 * @access public
795 * @return string
796 */
797 public function getLastReply()
798 {
799 return $this->last_reply;
800 }
801 
802 /**
803 * Read the SMTP server's response.
804 * Either before eof or socket timeout occurs on the operation.
805 * With SMTP we can tell if we have more lines to read if the
806 * 4th character is '-' symbol. If it is a space then we don't
807 * need to read anything else.
808 * @access protected
809 * @return string
810 */
811 protected function get_lines()
812 {
813 // If the connection is bad, give up straight away
814 if (!is_resource($this->smtp_conn)) {
815 return '';
816 }
817 $data = '';
818 $endtime = 0;
819 stream_set_timeout($this->smtp_conn, $this->Timeout);
820 if ($this->Timelimit > 0) {
821 $endtime = time() + $this->Timelimit;
822 }
823 while (is_resource($this->smtp_conn) && !feof($this->smtp_conn)) {
824 $str = @fgets($this->smtp_conn, 515);
825 if ($this->do_debug >= 4) {
826 $this->edebug("SMTP -> get_lines(): \$data was \"$data\"");
827 $this->edebug("SMTP -> get_lines(): \$str is \"$str\"");
828 }
829 $data .= $str;
830 if ($this->do_debug >= 4) {
831 $this->edebug("SMTP -> get_lines(): \$data is \"$data\"");
832 }
833 // If 4th character is a space, we are done reading, break the loop, micro-optimisation over strlen
834 if ((isset($str[3]) and $str[3] == ' ')) {
835 break;
836 }
837 // Timed-out? Log and break
838 $info = stream_get_meta_data($this->smtp_conn);
839 if ($info['timed_out']) {
840 if ($this->do_debug >= 4) {
841 $this->edebug(
842 'SMTP -> get_lines(): timed-out (' . $this->Timeout . ' sec)'
843 );
844 }
845 break;
846 }
847 // Now check if reads took too long
848 if ($endtime and time() > $endtime) {
849 if ($this->do_debug >= 4) {
850 $this->edebug(
851 'SMTP -> get_lines(): timelimit reached ('.
852 $this->Timelimit . ' sec)'
853 );
854 }
855 break;
856 }
857 }
858 return $data;
859 }
860 
861 /**
862 * Enable or disable VERP address generation.
863 * @param bool $enabled
864 */
865 public function setVerp($enabled = false)
866 {
867 $this->do_verp = $enabled;
868 }
869 
870 /**
871 * Get VERP address generation mode.
872 * @return bool
873 */
874 public function getVerp()
875 {
876 return $this->do_verp;
877 }
878 
879 /**
880 * Set debug output method.
881 * @param string $method The function/method to use for debugging output.
882 */
883 public function setDebugOutput($method = 'echo')
884 {
885 $this->Debugoutput = $method;
886 }
887 
888 /**
889 * Get debug output method.
890 * @return string
891 */
892 public function getDebugOutput()
893 {
894 return $this->Debugoutput;
895 }
896 
897 /**
898 * Set debug output level.
899 * @param int $level
900 */
901 public function setDebugLevel($level = 0)
902 {
903 $this->do_debug = $level;
904 }
905 
906 /**
907 * Get debug output level.
908 * @return int
909 */
910 public function getDebugLevel()
911 {
912 return $this->do_debug;
913 }
914 
915 /**
916 * Set SMTP timeout.
917 * @param int $timeout
918 */
919 public function setTimeout($timeout = 0)
920 {
921 $this->Timeout = $timeout;
922 }
923 
924 /**
925 * Get SMTP timeout.
926 * @return int
927 */
928 public function getTimeout()
929 {
930 return $this->Timeout;
931 }
932}

Powered by WebSVN 2.2.1