connect($host, $port); } } /** * * open connection to POP3 server * * @param host hostname of IP address of POP3 server * @param int port of POP3 server, default is 110 * @return bool connection succeeded or failed */ public function connect($host, $port = 110) { $this->_socket = fsockopen($host, $port); if(!$this->_socket) { return false; } $welcome = $this->readResponse(); strtok($welcome, '<'); $this->_timestamp = strtok('>'); if(!strpos($this->_timestamp, '@')) { $this->_timestamp = null; } else { $this->_timestamp = '<'.$this->_timestamp.'>'; } return $welcome; } /** * * send a request * * @param string your request without newline * @return bool socket write succeeded or failed */ public function sendRequest($request) { $result = fputs($this->_socket, $request."\n"); if(!$result) { return false; } return true; } /** * * read a response * * @param if response should be read as single of multiline response (ends with "\n.\n") * @return mixed null if socket error, false on server/client error, else response */ public function readResponse($multiline = false) { $result = fgets($this->_socket); if(!$result) { return null; } $result = trim($result); if(strpos($result, ' ')) { list($status, $message) = explode(' ', $result, 2); } else { $status = $result; $message = ''; } $this->_lastMessage = $message; if($status != '+OK') { return false; } if($multiline) { $message = ''; $line = fgets($this->_socket); while($line && trim($line) != '.') { $message. = $line; $line = fgets($this->_socket); }; } return $message; } /** * * send request and get resposne * * @param string request * @param bool multiline response * @return mixed result from readResponse() * @see sendRequest(), readResponse() * */ public function request($request, $multiline = false) { $result = $this->sendRequest($request); if(!$result) { return $result; } return $this->readResponse($multiline); } /** * * end communication with POP3 server (also closes socket) */ public function logout() { $this->request('QUIT'); fclose($this->_socket); $this->_socket = null; } /** * * get capabilities from POP3 server * * @return array list of capabilities * */ public function capa() { $result = $this->request('CAPA', true); if(!$result) { return false; } return explode("\n", $result); } /** * * Login to POP3 server. Can use APOP * * @param string username * @param string password * @param bool if APOP should be tried * @return bool success or failure */ public function login($user, $password, $try_apop = true) { if($try_apop && $this->_timestamp) { $result = $this->request("APOP $user ".md5($this->_timestamp.$password)); if($result) { return true; } } $result = $this->request("USER $user"); if(!$result) { return false; } $result = $this->request("PASS $password"); if(!$result) { return false; } return true; } /** * * make STAT call for message count and size sum * * @param int out parameter with count of messages * @param int out parameter with size in octects of messages * @return bool success or failure */ public function status(&$messages, &$octets) { $messages = 0; $octets = 0; $result = $this->request('STAT'); if(!$result) { return false; } list($messages, $octets) = explode(' ', $result); return true; } /** * * make LIST call for size of message[s] * * @param int number of message * @return int|array size of given message or list with array(num => size) */ public function getList($msgno = null) { if(!is_null($msgno)) { $result = $this->request("LIST $msgno"); if(!$result) { return false; } list(, $result) = explode(' ', $result); return $result; } $result = $this->request('LIST', true); if(!$result || !is_string($result)) { return false; } $messages = array(); foreach($result as $line) { list($no, $size) = explode(' ', $line); $messages[$no] = $size; } return $messages; } /** * * make UIDL call for getting a uniqueid * * @param int number of message * @return string|array uniqueid of message or list with array(num => uniqueid) */ public function uniqueid($msgno = null) { if(!is_null($msgno)) { $result = $this->request("UIDL $msgno"); if(!$result) { return false; } list(, $result) = explode(' ', $result); return $result; } $result = $this->request('UIDL', true); if(!$result || !is_string($result)) { return false; } $result = explode("\n", $result); $messages = array(); foreach($result as $line) { list($no, $id) = explode(' ', $line); $messages[$no] = $id; } return $messages; } /** * * make TOP call for getting headers and maybe some body lines * This method also sets hasTop - before it it's not known if top is supported * * The fallback makes normale RETR call, which retrieves the whole message. Additional * lines are not removed. * * @param int number of message * @param int number of wanted body lines (empty line is inserted after header lines) * @param bool fallback with full retrieve if top is not supported * @return bool|string false on error else message headers with wanted body lines */ public function top($msgno, $lines = 0, $failback = false) { if($this->hasTop === false) { if($failback) { return $this->retrive($msgno); } else { return false; } } $this->hasTop = true; if(!$lines || (int)$lines < 1) { $request = "TOP $msgno"; } else { $request = "TOP $msgno $lines"; } $result = $this->request($request, true); if(!$result || !is_string($result)) { $this->hasTop = false; if($failback) { return $this->retrive($msgno); } return false; } return $result; } /** * * make a RETR call for retrieving a full message with headers and body * * @param int message number * @return bool|string false on error or message */ public function retrive($msgno) { $result = $this->request("RETR $msgno", true); if(!$result) { return false; } return $result; } /** * * make a NOOP call, maybe needed for keeping the server happy * * @return bool success or failure */ public function noop() { return $this->request("NOOP") ? true : false; } /** * * make RSET call, which rollbacks delete requests * * @return success or failure */ public function undelete() { return $this->request("RSET") ? true : false; } } ?>