1: <?php
2: /*~ class.pop3.php
3: .---------------------------------------------------------------------------.
4: | Software: PHPMailer - PHP email class |
5: | Version: 5.2.1 |
6: | Site: https://code.google.com/a/apache-extras.org/p/phpmailer/ |
7: | ------------------------------------------------------------------------- |
8: | Admin: Jim Jagielski (project admininistrator) |
9: | Authors: Andy Prevost (codeworxtech) codeworxtech@users.sourceforge.net |
10: | : Marcus Bointon (coolbru) coolbru@users.sourceforge.net |
11: | : Jim Jagielski (jimjag) jimjag@gmail.com |
12: | Founder: Brent R. Matzelle (original founder) |
13: | Copyright (c) 2010-2012, Jim Jagielski. All Rights Reserved. |
14: | Copyright (c) 2004-2009, Andy Prevost. All Rights Reserved. |
15: | Copyright (c) 2001-2003, Brent R. Matzelle |
16: | ------------------------------------------------------------------------- |
17: | License: Distributed under the Lesser General Public License (LGPL) |
18: | http://www.gnu.org/copyleft/lesser.html |
19: | This program is distributed in the hope that it will be useful - WITHOUT |
20: | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
21: | FITNESS FOR A PARTICULAR PURPOSE. |
22: '---------------------------------------------------------------------------'
23: */
24:
25: /**
26: * PHPMailer - PHP POP Before SMTP Authentication Class
27: * NOTE: Designed for use with PHP version 5 and up
28: * @package PHPMailer
29: * @author Andy Prevost
30: * @author Marcus Bointon
31: * @author Jim Jagielski
32: * @copyright 2010 - 2012 Jim Jagielski
33: * @copyright 2004 - 2009 Andy Prevost
34: * @license http://www.gnu.org/copyleft/lesser.html Distributed under the Lesser General Public License (LGPL)
35: * @version $Id: class.pop3.php 450 2010-06-23 16:46:33Z coolbru $
36: */
37:
38: /**
39: * POP Before SMTP Authentication Class
40: * Version 5.2.1
41: *
42: * Author: Richard Davey (rich@corephp.co.uk)
43: * Modifications: Andy Prevost
44: * License: LGPL, see PHPMailer License
45: *
46: * Specifically for PHPMailer to allow POP before SMTP authentication.
47: * Does not yet work with APOP - if you have an APOP account, contact Richard Davey
48: * and we can test changes to this script.
49: *
50: * This class is based on the structure of the SMTP class originally authored by Chris Ryan
51: *
52: * This class is rfc 1939 compliant and implements all the commands
53: * required for POP3 connection, authentication and disconnection.
54: *
55: * @package PHPMailer
56: * @author Richard Davey
57: */
58:
59: class Net_POP3 {
60: /**
61: * Default POP3 port
62: * @var int
63: */
64: public $POP3_PORT = 110;
65:
66: /**
67: * Default Timeout
68: * @var int
69: */
70: public $POP3_TIMEOUT = 30;
71:
72: /**
73: * POP3 Carriage Return + Line Feed
74: * @var string
75: */
76: public $CRLF = "\r\n";
77:
78: /**
79: * Displaying Debug warnings? (0 = now, 1+ = yes)
80: * @var int
81: */
82: public $do_debug = 2;
83:
84: /**
85: * POP3 Mail Server
86: * @var string
87: */
88: public $host;
89:
90: /**
91: * POP3 Port
92: * @var int
93: */
94: public $port;
95:
96: /**
97: * POP3 Timeout Value
98: * @var int
99: */
100: public $tval;
101:
102: /**
103: * POP3 Username
104: * @var string
105: */
106: public $username;
107:
108: /**
109: * POP3 Password
110: * @var string
111: */
112: public $password;
113:
114: /**
115: * Sets the POP3 PHPMailer Version number
116: * @var string
117: */
118: public $Version = '5.2.1';
119:
120: /////////////////////////////////////////////////
121: // PROPERTIES, PRIVATE AND PROTECTED
122: /////////////////////////////////////////////////
123:
124: private $pop_conn;
125: private $connected;
126: private $error; // Error log array
127:
128: /**
129: * Constructor, sets the initial values
130: * @access public
131: * @return POP3
132: */
133: public function __construct() {
134: $this->pop_conn = 0;
135: $this->connected = false;
136: $this->error = null;
137: }
138:
139: /**
140: * Combination of public events - connect, login, disconnect
141: * @access public
142: * @param string $host
143: * @param integer $port
144: * @param integer $tval
145: * @param string $username
146: * @param string $password
147: */
148: public function Authorise ($host, $port = false, $tval = false, $username, $password, $debug_level = 0) {
149: $this->host = $host;
150:
151: // If no port value is passed, retrieve it
152: if ($port == false) {
153: $this->port = $this->POP3_PORT;
154: } else {
155: $this->port = $port;
156: }
157:
158: // If no port value is passed, retrieve it
159: if ($tval == false) {
160: $this->tval = $this->POP3_TIMEOUT;
161: } else {
162: $this->tval = $tval;
163: }
164:
165: $this->do_debug = $debug_level;
166: $this->username = $username;
167: $this->password = $password;
168:
169: // Refresh the error log
170: $this->error = null;
171:
172: // Connect
173: $result = $this->Connect($this->host, $this->port, $this->tval);
174:
175: if ($result) {
176: $login_result = $this->Login($this->username, $this->password);
177:
178: if ($login_result) {
179: $this->Disconnect();
180:
181: return true;
182: }
183:
184: }
185:
186: // We need to disconnect regardless if the login succeeded
187: $this->Disconnect();
188:
189: return false;
190: }
191:
192: /**
193: * Connect to the POP3 server
194: * @access public
195: * @param string $host
196: * @param integer $port
197: * @param integer $tval
198: * @return boolean
199: */
200: public function Connect ($host, $port = false, $tval = 30) {
201: // Are we already connected?
202: if ($this->connected) {
203: return true;
204: }
205:
206: /*
207: On Windows this will raise a PHP Warning error if the hostname doesn't exist.
208: Rather than supress it with @fsockopen, let's capture it cleanly instead
209: */
210:
211: set_error_handler(array(&$this, 'catchWarning'));
212:
213: // Connect to the POP3 server
214: $this->pop_conn = fsockopen($host, // POP3 Host
215: $port, // Port #
216: $errno, // Error Number
217: $errstr, // Error Message
218: $tval); // Timeout (seconds)
219:
220: // Restore the error handler
221: restore_error_handler();
222:
223: // Does the Error Log now contain anything?
224: if ($this->error && $this->do_debug >= 1) {
225: $this->displayErrors();
226: }
227:
228: // Did we connect?
229: if ($this->pop_conn == false) {
230: // It would appear not...
231: $this->error = array(
232: 'error' => "Failed to connect to server $host on port $port",
233: 'errno' => $errno,
234: 'errstr' => $errstr
235: );
236:
237: if ($this->do_debug >= 1) {
238: $this->displayErrors();
239: }
240:
241: return false;
242: }
243:
244: // Increase the stream time-out
245:
246: // Check for PHP 4.3.0 or later
247: if (version_compare(phpversion(), '5.0.0', 'ge')) {
248: stream_set_timeout($this->pop_conn, $tval, 0);
249: } else {
250: // Does not work on Windows
251: if (substr(PHP_OS, 0, 3) !== 'WIN') {
252: socket_set_timeout($this->pop_conn, $tval, 0);
253: }
254: }
255:
256: // Get the POP3 server response
257: $pop3_response = $this->getResponse();
258:
259: // Check for the +OK
260: if ($this->checkResponse($pop3_response)) {
261: // The connection is established and the POP3 server is talking
262: $this->connected = true;
263: return true;
264: }
265:
266: }
267:
268: /**
269: * Login to the POP3 server (does not support APOP yet)
270: * @access public
271: * @param string $username
272: * @param string $password
273: * @return boolean
274: */
275: public function Login ($username = '', $password = '') {
276: if ($this->connected == false) {
277: $this->error = 'Not connected to POP3 server';
278:
279: if ($this->do_debug >= 1) {
280: $this->displayErrors();
281: }
282: }
283:
284: if (empty($username)) {
285: $username = $this->username;
286: }
287:
288: if (empty($password)) {
289: $password = $this->password;
290: }
291:
292: $pop_username = "USER $username" . $this->CRLF;
293: $pop_password = "PASS $password" . $this->CRLF;
294:
295: // Send the Username
296: $this->sendString($pop_username);
297: $pop3_response = $this->getResponse();
298:
299: if ($this->checkResponse($pop3_response)) {
300: // Send the Password
301: $this->sendString($pop_password);
302: $pop3_response = $this->getResponse();
303:
304: if ($this->checkResponse($pop3_response)) {
305: return true;
306: } else {
307: return false;
308: }
309: } else {
310: return false;
311: }
312: }
313:
314: /**
315: * Disconnect from the POP3 server
316: * @access public
317: */
318: public function Disconnect () {
319: $this->sendString('QUIT');
320:
321: fclose($this->pop_conn);
322: }
323:
324: /////////////////////////////////////////////////
325: // Private Methods
326: /////////////////////////////////////////////////
327:
328: /**
329: * Get the socket response back.
330: * $size is the maximum number of bytes to retrieve
331: * @access private
332: * @param integer $size
333: * @return string
334: */
335: private function getResponse ($size = 128) {
336: $pop3_response = fgets($this->pop_conn, $size);
337:
338: return $pop3_response;
339: }
340:
341: /**
342: * Send a string down the open socket connection to the POP3 server
343: * @access private
344: * @param string $string
345: * @return integer
346: */
347: private function sendString ($string) {
348: $bytes_sent = fwrite($this->pop_conn, $string, strlen($string));
349:
350: return $bytes_sent;
351: }
352:
353: /**
354: * Checks the POP3 server response for +OK or -ERR
355: * @access private
356: * @param string $string
357: * @return boolean
358: */
359: private function checkResponse ($string) {
360: if (substr($string, 0, 3) !== '+OK') {
361: $this->error = array(
362: 'error' => "Server reported an error: $string",
363: 'errno' => 0,
364: 'errstr' => ''
365: );
366:
367: if ($this->do_debug >= 1) {
368: $this->displayErrors();
369: }
370:
371: return false;
372: } else {
373: return true;
374: }
375:
376: }
377:
378: /**
379: * If debug is enabled, display the error message array
380: * @access private
381: */
382: private function displayErrors () {
383: echo '<pre>';
384:
385: foreach ($this->error as $single_error) {
386: print_r($single_error);
387: }
388:
389: echo '</pre>';
390: }
391:
392: /**
393: * Takes over from PHP for the socket warning handler
394: * @access private
395: * @param integer $errno
396: * @param string $errstr
397: * @param string $errfile
398: * @param integer $errline
399: */
400: private function catchWarning ($errno, $errstr, $errfile, $errline) {
401: $this->error[] = array(
402: 'error' => "Connecting to the POP3 server raised a PHP warning: ",
403: 'errno' => $errno,
404: 'errstr' => $errstr
405: );
406: }
407:
408: // End of class
409: }
410: ?>
411: