Warning, file /webapps/ocs-webserver/library/Zend/Mail/Protocol/Pop3.php was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 <?php
0002 /**
0003  * Zend Framework
0004  *
0005  * LICENSE
0006  *
0007  * This source file is subject to the new BSD license that is bundled
0008  * with this package in the file LICENSE.txt.
0009  * It is also available through the world-wide-web at this URL:
0010  * http://framework.zend.com/license/new-bsd
0011  * If you did not receive a copy of the license and are unable to
0012  * obtain it through the world-wide-web, please send an email
0013  * to license@zend.com so we can send you a copy immediately.
0014  *
0015  * @category   Zend
0016  * @package    Zend_Mail
0017  * @subpackage Protocol
0018  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0019  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0020  * @version    $Id$
0021  */
0022 
0023 
0024 /**
0025  * @category   Zend
0026  * @package    Zend_Mail
0027  * @subpackage Protocol
0028  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0029  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0030  */
0031 class Zend_Mail_Protocol_Pop3
0032 {
0033     /**
0034      * Default timeout in seconds for initiating session
0035      */
0036     const TIMEOUT_CONNECTION = 30;
0037 
0038     /**
0039      * saves if server supports top
0040      * @var null|bool
0041      */
0042     public $hasTop = null;
0043 
0044     /**
0045      * socket to pop3
0046      * @var null|resource
0047      */
0048     protected $_socket;
0049 
0050     /**
0051      * greeting timestamp for apop
0052      * @var null|string
0053      */
0054     protected $_timestamp;
0055 
0056 
0057     /**
0058      * Public constructor
0059      *
0060      * @param  string      $host  hostname or IP address of POP3 server, if given connect() is called
0061      * @param  int|null    $port  port of POP3 server, null for default (110 or 995 for ssl)
0062      * @param  bool|string $ssl   use ssl? 'SSL', 'TLS' or false
0063      * @throws Zend_Mail_Protocol_Exception
0064      */
0065     public function __construct($host = '', $port = null, $ssl = false)
0066     {
0067         if ($host) {
0068             $this->connect($host, $port, $ssl);
0069         }
0070     }
0071 
0072 
0073     /**
0074      * Public destructor
0075      */
0076     public function __destruct()
0077     {
0078         $this->logout();
0079     }
0080 
0081 
0082     /**
0083      * Open connection to POP3 server
0084      *
0085      * @param  string      $host  hostname or IP address of POP3 server
0086      * @param  int|null    $port  of POP3 server, default is 110 (995 for ssl)
0087      * @param  string|bool $ssl   use 'SSL', 'TLS' or false
0088      * @return string welcome message
0089      * @throws Zend_Mail_Protocol_Exception
0090      */
0091     public function connect($host, $port = null, $ssl = false)
0092     {
0093         if ($ssl == 'SSL') {
0094             $host = 'ssl://' . $host;
0095         }
0096 
0097         if ($port === null) {
0098             $port = $ssl == 'SSL' ? 995 : 110;
0099         }
0100 
0101         $errno  =  0;
0102         $errstr = '';
0103         $this->_socket = @fsockopen($host, $port, $errno, $errstr, self::TIMEOUT_CONNECTION);
0104         if (!$this->_socket) {
0105             /**
0106              * @see Zend_Mail_Protocol_Exception
0107              */
0108             // require_once 'Zend/Mail/Protocol/Exception.php';
0109             throw new Zend_Mail_Protocol_Exception('cannot connect to host; error = ' . $errstr .
0110                                                    ' (errno = ' . $errno . ' )');
0111         }
0112 
0113         $welcome = $this->readResponse();
0114 
0115         strtok($welcome, '<');
0116         $this->_timestamp = strtok('>');
0117         if (!strpos($this->_timestamp, '@')) {
0118             $this->_timestamp = null;
0119         } else {
0120             $this->_timestamp = '<' . $this->_timestamp . '>';
0121         }
0122 
0123         if ($ssl === 'TLS') {
0124             $this->request('STLS');
0125             $result = stream_socket_enable_crypto($this->_socket, true, STREAM_CRYPTO_METHOD_TLS_CLIENT);
0126             if (!$result) {
0127                 /**
0128                  * @see Zend_Mail_Protocol_Exception
0129                  */
0130                 // require_once 'Zend/Mail/Protocol/Exception.php';
0131                 throw new Zend_Mail_Protocol_Exception('cannot enable TLS');
0132             }
0133         }
0134 
0135         return $welcome;
0136     }
0137 
0138 
0139     /**
0140      * Send a request
0141      *
0142      * @param string $request your request without newline
0143      * @return null
0144      * @throws Zend_Mail_Protocol_Exception
0145      */
0146     public function sendRequest($request)
0147     {
0148         $result = @fputs($this->_socket, $request . "\r\n");
0149         if (!$result) {
0150             /**
0151              * @see Zend_Mail_Protocol_Exception
0152              */
0153             // require_once 'Zend/Mail/Protocol/Exception.php';
0154             throw new Zend_Mail_Protocol_Exception('send failed - connection closed?');
0155         }
0156     }
0157 
0158 
0159     /**
0160      * read a response
0161      *
0162      * @param  boolean $multiline response has multiple lines and should be read until "<nl>.<nl>"
0163      * @return string response
0164      * @throws Zend_Mail_Protocol_Exception
0165      */
0166     public function readResponse($multiline = false)
0167     {
0168         $result = @fgets($this->_socket);
0169         if (!is_string($result)) {
0170             /**
0171              * @see Zend_Mail_Protocol_Exception
0172              */
0173             // require_once 'Zend/Mail/Protocol/Exception.php';
0174             throw new Zend_Mail_Protocol_Exception('read failed - connection closed?');
0175         }
0176 
0177         $result = trim($result);
0178         if (strpos($result, ' ')) {
0179             list($status, $message) = explode(' ', $result, 2);
0180         } else {
0181             $status = $result;
0182             $message = '';
0183         }
0184 
0185         if ($status != '+OK') {
0186             /**
0187              * @see Zend_Mail_Protocol_Exception
0188              */
0189             // require_once 'Zend/Mail/Protocol/Exception.php';
0190             throw new Zend_Mail_Protocol_Exception('last request failed');
0191         }
0192 
0193         if ($multiline) {
0194             $message = '';
0195             $line = fgets($this->_socket);
0196             while ($line && rtrim($line, "\r\n") != '.') {
0197                 if ($line[0] == '.') {
0198                     $line = substr($line, 1);
0199                 }
0200                 $message .= $line;
0201                 $line = fgets($this->_socket);
0202             };
0203         }
0204 
0205         return $message;
0206     }
0207 
0208 
0209     /**
0210      * Send request and get resposne
0211      *
0212      * @see sendRequest(), readResponse()
0213      *
0214      * @param  string $request    request
0215      * @param  bool   $multiline  multiline response?
0216      * @return string             result from readResponse()
0217      * @throws Zend_Mail_Protocol_Exception
0218      */
0219     public function request($request, $multiline = false)
0220     {
0221         $this->sendRequest($request);
0222         return $this->readResponse($multiline);
0223     }
0224 
0225 
0226     /**
0227      * End communication with POP3 server (also closes socket)
0228      *
0229      * @return null
0230      */
0231     public function logout()
0232     {
0233         if (!$this->_socket) {
0234             return;
0235         }
0236 
0237         try {
0238             $this->request('QUIT');
0239         } catch (Zend_Mail_Protocol_Exception $e) {
0240             // ignore error - we're closing the socket anyway
0241         }
0242 
0243         fclose($this->_socket);
0244         $this->_socket = null;
0245     }
0246 
0247 
0248     /**
0249      * Get capabilities from POP3 server
0250      *
0251      * @return array list of capabilities
0252      * @throws Zend_Mail_Protocol_Exception
0253      */
0254     public function capa()
0255     {
0256         $result = $this->request('CAPA', true);
0257         return explode("\n", $result);
0258     }
0259 
0260 
0261     /**
0262      * Login to POP3 server. Can use APOP
0263      *
0264      * @param  string $user      username
0265      * @param  string $password  password
0266      * @param  bool   $try_apop  should APOP be tried?
0267      * @return void
0268      * @throws Zend_Mail_Protocol_Exception
0269      */
0270     public function login($user, $password, $tryApop = true)
0271     {
0272         if ($tryApop && $this->_timestamp) {
0273             try {
0274                 $this->request("APOP $user " . md5($this->_timestamp . $password));
0275                 return;
0276             } catch (Zend_Mail_Protocol_Exception $e) {
0277                 // ignore
0278             }
0279         }
0280 
0281         $result = $this->request("USER $user");
0282         $result = $this->request("PASS $password");
0283     }
0284 
0285 
0286     /**
0287      * Make STAT call for message count and size sum
0288      *
0289      * @param  int $messages  out parameter with count of messages
0290      * @param  int $octets    out parameter with size in octects of messages
0291      * @return void
0292      * @throws Zend_Mail_Protocol_Exception
0293      */
0294     public function status(&$messages, &$octets)
0295     {
0296         $messages = 0;
0297         $octets = 0;
0298         $result = $this->request('STAT');
0299 
0300         list($messages, $octets) = explode(' ', $result);
0301     }
0302 
0303 
0304     /**
0305      * Make LIST call for size of message(s)
0306      *
0307      * @param  int|null $msgno number of message, null for all
0308      * @return int|array size of given message or list with array(num => size)
0309      * @throws Zend_Mail_Protocol_Exception
0310      */
0311     public function getList($msgno = null)
0312     {
0313         if ($msgno !== null) {
0314             $result = $this->request("LIST $msgno");
0315 
0316             list(, $result) = explode(' ', $result);
0317             return (int)$result;
0318         }
0319 
0320         $result = $this->request('LIST', true);
0321         $messages = array();
0322         $line = strtok($result, "\n");
0323         while ($line) {
0324             list($no, $size) = explode(' ', trim($line));
0325             $messages[(int)$no] = (int)$size;
0326             $line = strtok("\n");
0327         }
0328 
0329         return $messages;
0330     }
0331 
0332 
0333     /**
0334      * Make UIDL call for getting a uniqueid
0335      *
0336      * @param  int|null $msgno number of message, null for all
0337      * @return string|array uniqueid of message or list with array(num => uniqueid)
0338      * @throws Zend_Mail_Protocol_Exception
0339      */
0340     public function uniqueid($msgno = null)
0341     {
0342         if ($msgno !== null) {
0343             $result = $this->request("UIDL $msgno");
0344 
0345             list(, $result) = explode(' ', $result);
0346             return $result;
0347         }
0348 
0349         $result = $this->request('UIDL', true);
0350 
0351         $result = explode("\n", $result);
0352         $messages = array();
0353         foreach ($result as $line) {
0354             if (!$line) {
0355                 continue;
0356             }
0357             list($no, $id) = explode(' ', trim($line), 2);
0358             $messages[(int)$no] = $id;
0359         }
0360 
0361         return $messages;
0362 
0363     }
0364 
0365 
0366     /**
0367      * Make TOP call for getting headers and maybe some body lines
0368      * This method also sets hasTop - before it it's not known if top is supported
0369      *
0370      * The fallback makes normale RETR call, which retrieves the whole message. Additional
0371      * lines are not removed.
0372      *
0373      * @param  int  $msgno    number of message
0374      * @param  int  $lines    number of wanted body lines (empty line is inserted after header lines)
0375      * @param  bool $fallback fallback with full retrieve if top is not supported
0376      * @return string message headers with wanted body lines
0377      * @throws Zend_Mail_Protocol_Exception
0378      */
0379     public function top($msgno, $lines = 0, $fallback = false)
0380     {
0381         if ($this->hasTop === false) {
0382             if ($fallback) {
0383                 return $this->retrieve($msgno);
0384             } else {
0385                 /**
0386                  * @see Zend_Mail_Protocol_Exception
0387                  */
0388                 // require_once 'Zend/Mail/Protocol/Exception.php';
0389                 throw new Zend_Mail_Protocol_Exception('top not supported and no fallback wanted');
0390             }
0391         }
0392         $this->hasTop = true;
0393 
0394         $lines = (!$lines || $lines < 1) ? 0 : (int)$lines;
0395 
0396         try {
0397             $result = $this->request("TOP $msgno $lines", true);
0398         } catch (Zend_Mail_Protocol_Exception $e) {
0399             $this->hasTop = false;
0400             if ($fallback) {
0401                 $result = $this->retrieve($msgno);
0402             } else {
0403                 throw $e;
0404             }
0405         }
0406 
0407         return $result;
0408     }
0409 
0410 
0411     /**
0412      * Make a RETR call for retrieving a full message with headers and body
0413      *
0414      * @deprecated since 1.1.0; this method has a typo - please use retrieve()
0415      * @param  int $msgno  message number
0416      * @return string message
0417      * @throws Zend_Mail_Protocol_Exception
0418      */
0419     public function retrive($msgno)
0420     {
0421         return $this->retrieve($msgno);
0422     }
0423 
0424 
0425     /**
0426      * Make a RETR call for retrieving a full message with headers and body
0427      *
0428      * @param  int $msgno  message number
0429      * @return string message
0430      * @throws Zend_Mail_Protocol_Exception
0431      */
0432     public function retrieve($msgno)
0433     {
0434         $result = $this->request("RETR $msgno", true);
0435         return $result;
0436     }
0437 
0438     /**
0439      * Make a NOOP call, maybe needed for keeping the server happy
0440      *
0441      * @return null
0442      * @throws Zend_Mail_Protocol_Exception
0443      */
0444     public function noop()
0445     {
0446         $this->request('NOOP');
0447     }
0448 
0449 
0450     /**
0451      * Make a DELE count to remove a message
0452      *
0453      * @return null
0454      * @throws Zend_Mail_Protocol_Exception
0455      */
0456     public function delete($msgno)
0457     {
0458         $this->request("DELE $msgno");
0459     }
0460 
0461 
0462     /**
0463      * Make RSET call, which rollbacks delete requests
0464      *
0465      * @return null
0466      * @throws Zend_Mail_Protocol_Exception
0467      */
0468     public function undelete()
0469     {
0470         $this->request('RSET');
0471     }
0472 }