Version 4.0.13.1

This commit is contained in:
Neo committed 2025-12-19 04:57:54 -08:00
1 parent f9e857d255
commit c6a86f0d9b
7517 files changed
+597400 -668041

No files matched your search

View File
Whitespace-only changes.
File diff suppressed because it is too large. Load diff
+828
View File
@@ -0,0 +1,828 @@
<?php
/**
* POP3 Class
*
* This class provide access to a pop3 server through the pop3 protocol
*
* @need: >=php-5.2.x
* @author: j0inty.sL
* @email: bestmischmaker@web.de
* @version: 0.7.2-beta
*
* NOTES:
* - IPv6 support NEVER tested at time
*/
final class POP3_Exception extends Exception
{
/**
* @param string $strErrMessage
* @param integer $intErrCode
*
* @return POP3_Exception
*/
function __construct( $strErrMessage, $intErrCode )
{
switch( $intErrCode )
{
case POP3::ERR_NOT_IMPLEMENTS:
if( empty($strErrMessage) ) $strErrMessage = "This function isn't implements at time.";
break;
case POP3::ERR_SOCKETS:
$strErrMessage = "Sockets Error: (". socket_last_error() .") -- ". socket_strerror(socket_last_error());
break;
case POP3::ERR_STREAM:
case POP3::ERR_LOG:
$aError = error_get_last();
$strErrMessage = "Stream Error: (". $aError["type"] .") -- ". $aError["message"];
break;
}
parent::__construct($strErrMessage, $intErrCode);
}
/**
* Store the Exception string to a given file
*
* @param string $strLogFile logfile name with path
*/
public function saveToFile($strLogFile)
{
if( !$resFp = @fopen($strLogFile,"a+") )
{
return false;
}
$strMsg = date("Y-m-d H:i:s -- ") . $this;
if( !@fputs($resFp, $strMsg, strlen($strMsg)) )
{
return false;
}
@fclose($resFp);
}
/**
* @return string Exception with StackTrace as String
*/
public function __toString()
{
return __CLASS__ ." [". $this->getCode() ."] -- ". $this->getMessage() ." in file ". $this->getFile() ." at line ". $this->getLine(). PHP_EOL ."Trace: ". $this->getTraceAsString() .PHP_EOL;
}
}
class POP3
{
//const ERR_NONE = 0;
const ERR_LOG = 1;
const ERR_SOCKETS = 2;
const ERR_PARAMETER = 3;
const ERR_NOT_IMPLEMENTS = 4;
const ERR_INVALID_STATE = 5;
const ERR_STREAM = 6;
const ERR_SEND_CMD = 7;
const STATE_DISCONNECT = 100;
const STATE_AUTHORIZATION = 101;
const STATE_TRANSACTION = 102;
/*
const PROTOCOL_TCP = 1;
const PROTOCOL_TLS = 2;
const PROTOCOL_SSL = 3;
const PROTOCOL_SSLV2 = 4;
const PROTOCOL_SSLV3 = 5;
*/
const DEFAULT_BUFFER_SIZE = 4096;
private $bLogOpened = FALSE;
private $resLogFp = FALSE;
private $strLogFile = NULL;
private $bHideUsernameAtLog = TRUE;
private $bUseSockets;
private $strProtocol = NULL;
private $bSocketConnected = FALSE;
private $strHostname = NULL;
private $strIPAdress = NULL;
private $intPort = NULL;
private $intCurState = self::STATE_DISCONNECT;
private $strAPOPBanner = NULL;
private $bAPOPAutoDetect;
private $strVersion = "0.7.2-beta";
/*
* Constructor
*
* @param NULL|string $strLogFile Path to a log file or NULL for no log
* @param bool $bAPOPAutoDetect APOP Auto Dection on|off
* @param bool $bHideUsernameAtLog Does the Username should hide at the log file
* @param $strEncryption (tcp|ssl|sslv2|sslv3|tls) [depend on your PHP configuration]
* @param bool $bUseSockets Use the socket extension (default = TRUE) But it check is the extension_loaded, too
* !!! Only needed by them, who have the sockets extension loaded, but want use the stream functions !!!
*
* @throw POP3_Exception
*/
public function __construct( $strLogFile = NULL, $bAPOPAutoDetect = TRUE, $bHideUsernameAtLog = TRUE, $strEncryption = TRUE, $bUseSockets = TRUE )
{
if( !is_bool($bAPOPAutoDetect) )
{
throw new POP3_Exception("Invalid APOP auto detect parameter given.", self::ERR_PARAMETER);
}
if( !is_bool($bHideUsernameAtLog) )
{
throw new POP3_Exception("Invalid Hide Username at log file parameter given.", self::ERR_PARAMETER);
}
if( !preg_match("/^(tcp|ssl|sslv2|sslv3|tls)+$/", $strEncryption) )
{
throw new POP3_Exception("Invalid encryption parameter given. (tcp|ssl|sslv2|sslv3|tls) [depend on your PHP configuration]", self::ERR_PARAMETER);
}
else if( $bUseSockets && preg_match("/^(ssl|sslv2|sslv3|tls)+$/", $strEncryption))
{
throw new POP3_Exception("Encryption with Sockets Extension is not implemented now. Use \$UseSocket=false for that.",self::ERR_NOT_IMPLEMENTS );
}
// Activate logging if needed
if( !is_null($strLogFile) )
{
$this->strLogFile = $strLogFile;
$this->openlog();
}
// Check for sockets extension if needed
if( $bUseSockets && extension_loaded("sockets") )
{
$this->bUseSockets = TRUE;
}
else
{
if( $bUseSockets )
{
$this->log("You choose to use the socket extensions support but this isn't available.");
}
$this->bUseSockets = FALSE;
}
// Activate or Deactivate APOP Auto Detect mechanism
$this->bAPOPAutoDetect = $bAPOPAutoDetect;
$this->bHideUsernameAtLog = $bHideUsernameAtLog;
$this->strProtocol = $strEncryption;
}
/*
* Destructor
*
* @throw POP3_Exception
*/
public function __destruct()
{
$this->disconnect();
$this->closelog();
}
/*
* Connect to the pop3 server
*
* @param NULL|string $strHostname Hostname or ip adress of a pop3 server
* @param integer $intPort The port for the pop3 service (default is 110)
* @param array $arrConnectionTimeout array("sec" => "", "usec" => "")
* @param bool $bIPv6 IP Version 6 Protocol
*
* @throw POP3_Exception
*/
public function connect( &$strHostname , $intPort = 110, $arrConnectionTimeout = array("sec" => 10, "usec" => 0) ,$bIPv6 = FALSE )
{
$this->checkState(POP3::STATE_DISCONNECT);
/// Parameter checks ///
if( !is_string($strHostname) )
{
throw new POP3_Exception("Invalid host parameter given", self::ERR_PARAMETER);
}
if( !is_int($intPort) || $intPort < 1 || $intPort > 65535 )
{
throw new POP3_Exception("Invalid port parameter given", self::ERR_PARAMETER);
}
/* Deprecated: will do by the setSocketTimeout function
if( !is_array($arrConnectionTimeout) || !is_int($arrConnectionTimeout["sec"]) || !is_int($arrConnectionTimeout["usec"]) )
{
throw new POP3_Exception("Invalid connection timeout parameter given", self::ERR_PARAMETER);
}
*/
if( !is_bool($bIPv6) )
{
throw new POP3_Exception("Invalid IPv6 parameter given", self::ERR_PARAMETER);
}
$this->strHostname = $strHostname;
$this->intPort = $intPort;
/// Connecting ///
if( $this->bUseSockets )
{
if( !$this->resSocket = @socket_create( (($bIPv6) ? AF_INET6 : AF_INET), SOCK_STREAM, SOL_TCP ) )
{
throw new POP3_Exception("", self::ERR_SOCKETS);
}
$this->log( ($bIPv6) ? "AF_INET6" : "AF_INET" ."-TCP Socket created (using sockets extension)");
$this->setSockTimeout($arrConnectionTimeout);
if( !@socket_connect($this->resSocket, $this->strHostname, $this->intPort)
|| !@socket_getpeername($this->resSocket,$this->strIPAdress) )
{
throw new POP3_Exception("", self::ERR_SOCKETS);
}
}
else
{
$dTimeout = (double) implode(".",$arrConnectionTimeout);
if( !$this->resSocket = @fsockopen($this->strProtocol. "://" . $this->strHostname .":". $this->intPort, &$intErrno, &$strError, $dTimeout) )
{
throw new POP3_Exception( "[". $intErrno."] -- ". $strError, self::ERR_STREAM );
}
$this->setSockTimeout($arrConnectionTimeout);
$this->strIPAdress = @gethostbyname($this->strHostname);
}
$this->bSocketConnected = TRUE;
$this->log("Connected to ". $this->strProtocol . "://". $this->strIPAdress .":". $this->intPort ." [". $this->strHostname ."]");
// Get the first response with, if APOP support avalible, the apop banner.
$strBuffer = $this->recvString();
$this->log($strBuffer);
$this->parseBanner($strBuffer);
$this->intCurState = self::STATE_AUTHORIZATION;
}
/*
* Disconnect from the server.
* CAUTION:
* This function doesn't send the QUIT command to the server so all as delete marked emails won't delete.
*
* @return void
* @throw POP3_Exception
*/
public function disconnect()
{
if( $this->bSocketConnected )
{
if( $this->bUseSockets )
{
if( @socket_close($this->resSocket) === FALSE )
{
throw new POP3_Exception("", self::ERR_SOCKETS);
}
}
else
{
if( !@fclose($this->resSocket) )
{
throw new POP3_Exception("fclose(): Failed to close socket", self::ERR_STREAM);
}
}
$this->bSocketConnected = FALSE;
$this->log("Disconneted from ". $this->strIPAdress .":". $this->intPort ." [". $this->strHostname ."]" );
}
}
/**
* Authorize to the pop3 server with your login datas.
*
* @param string $strUser Username
* @param string $strPass Password
* @param boolean $bApop APOP Authorization Mechanism
*
* @return void
* @throw POP3_Exception
*/
public function login( $strUser, $strPass, $bAPOP = FALSE)
{
$this->checkState(self::STATE_AUTHORIZATION);
if( !is_string($strUser) || strlen($strUser) == 0 )
{
throw new POP3_Exception("Invalid username string given", self::ERR_PARAMETER);
}
if( !is_string($strPass) )
{
throw new POP3_Exception("Invalid password string given", self::ERR_PARAMETER);
}
if( !is_bool($bAPOP) )
{
throw new POP3_Exception("Invalid APOP variable given", self::ERR_PARAMETER);
}
if( $this->bAPOPAutoDetect && !is_null($this->strAPOPBanner) && !$bAPOP)
{
$bAPOP = TRUE;
}
if( $bAPOP )
{
// APOP Auth
$this->sendCmd("APOP ". $strUser ." ". hash("md5",$this->strAPOPBanner . $strPass, false), "APOP ". (($this->bHideUsernameAtLog) ? hash("sha256",$strUser . microtime(true),false) : $strUser) ." ". hash("md5",$this->strAPOPBanner . $strPass, false));
}
else
{
// POP3 Auth
$this->sendCmd( "USER ". $strUser, "USER ". (($this->bHideUsernameAtLog) ? hash("sha256",$strUser . microtime(true),false) : $strUser) );
$this->sendCmd( "PASS ". $strPass, "PASS ". hash("sha256",$strPass . microtime(true),false) );
}
$this->intCurState = self::STATE_TRANSACTION;
}
/**
* Send the quit command to the server.
* All as delete marked messages will remove from the mail drop.
*
* @return void
* @throw POP3_Exception
*/
public function quit()
{
try
{
$this->checkState(self::STATE_TRANSACTION);
}
catch( POP3_Exception $e )
{
$this->checkState(self::STATE_AUTHORIZATION);
}
$this->sendCmd("QUIT");
}
/**
* Get the stats from the pop3 server
* This is only a string with the count of mails and their size in your mail drop.
*
* @return string example: "+OK 2 3467"
* @throw POP3_Exception
*/
public function getStat()
{
$this->checkState(self::STATE_TRANSACTION);
return $this->sendCmd("STAT");
}
/**
* Recieve a raw message.
*
* @param int intMsgNum The message number on the pop3 server.
*
* @return string Complete message
* @throw POP3_Exception
*/
public function getMsg( $intMsgNum )
{
$this->checkState(self::STATE_TRANSACTION);
$this->checkMsgNum($intMsgNum);
$this->sendCmd("RETR ". $intMsgNum );
return $this->recvToPoint();
}
/**
* Get a list with message number and the size in bytes of a message.
*
* @return string A String with a list of all message number and size in your mail drop seperated by "\r\n"
* @throw POP3_Exception
*/
public function getList()
{
$this->checkState(self::STATE_TRANSACTION);
$this->sendCmd("LIST");
return $this->recvToPoint();
}
/**
* Get a list with message number and the unique id on the pop3 server.
*
* @return string Unique ID List
* @throw POP3_Exception
*/
public function getUidl()
{
$this->checkState(self::STATE_TRANSACTION);
$this->sendCmd("UIDL");
return $this->recvToPoint();
}
/**
* Get the message header and if you want x lines of the message body.
*
* @param int intMsgNum The message number on the pop3 server.
* @param int intLines The count of lines of the message body. (default is 0)
*
* @return string Message header
* @throw POP3_Exception
*/
public function getTop( $intMsgNum , $intLines = 0 )
{
$this->checkState(self::STATE_TRANSACTION);
$this->checkMsgNum($intMsgNum);
if( !is_int($intLines) ) throw new POP3_Exception("Invalid line number given", self::ERR_PARAMETER);
$this->sendCmd("TOP ". $intMsgNum ." ". $intLines);
return $this->recvToPoint();
}
/**
* Mark a message as delete
*
* @param int $intMsgNum Message Number on the pop3 server
*
* @throw POP3_Exception
*/
public function deleteMsg( $intMsgNum )
{
$this->checkState(self::STATE_TRANSACTION);
$this->checkMsgNum($intMsgNum);
$this->sendCmd("DELE ". $intMsgNum);
}
/**
*
* @param array $arrMsgNums Numeric array with the message numbers on the pop3 server
*
* @return array An array of messages stored under the message number
* @throw POP3_Exception
*/
public function getMails( $arrMsgNums )
{
$arrMsgs = array();
foreach( $arrMsgNums as $intMsgNum )
{
$arrMsgs[$intMsgNum] = $this->getMsg($intMsgNum);
}
return $arrMsgs;
}
/**
* Get the office status. That means that you will get an array
* with all needed informations about your mail drop.
* The array is build up like discribed here.
*
* $result = array( "count" => "Count of messages in your mail drop",
* "octets" => "Size of your mail drop in bytes",
*
* "msg_number" => array("uid" => "The unique id string of the message on the pop3 server",
* "octets" => "The size of the message in bytes"
* ),
* "and soon"
* );
*
* @return array
* @throw POP3_Exception
*/
public function getOfficeStatus()
{
$this->checkState(self::STATE_TRANSACTION);
$arrRes = array();
$strSTATs = $this->getStat();
$arrSTATs = explode(" ",trim($strSTATs));
$arrRes["count"] = (int) $arrSTATs[1];
$arrRes["octets"] = (int) $arrSTATs[2];
if( $arrRes["count"] > 0 )
{
$strUIDLs = $this->getUidl();
$strLISTs = $this->getList();
$arrUIDLs = explode("\r\n",trim($strUIDLs));
$arrLISTs = explode("\r\n",trim($strLISTs));
for($i=1; $i<=$arrRes["count"]; $i++)
{
list(,$intUIDL) = explode(" ", trim($arrUIDLs[$i-1]));
list(,$intLIST) = explode(" ", trim($arrLISTs[$i-1]));
$arrRes[$i]["uid"] = $intUIDL;
$arrRes[$i]["octets"] = (int) $intLIST;
}
}
return $arrRes;
}
public function saveToFile( $strPathToFile, &$strMail )
{
if( @is_file($strPathToFile) )
{
throw new POP3_Exception("File \"". $strPathToFile ."\" already exists", self::ERR_PARAMETER);
}
if( !$resFile = @fopen($strPathToFile,"w") )
{
throw new POP3_Exception("", self::ERR_STREAM);
}
if( !@fwrite($resFile,$strMail,strlen($strMail)) )
{
throw new POP3_Exception("", self::ERR_STREAM);
}
@fclose($resFile);
}
/*
* This function store a message under their message number.
* And that in the folder that was given by the path parameter.
*
* @param int $intMsgNum Message Number on the server @see getOfficeStatus(), list()
* @param string $strPathToDir Path to the directory where the mail should be store.
* @param string $strFileEnding The file ending for a email (default ".eml")
*
* @return void
* @throw POP3_Exception
*/
public function saveToFileFromServer( $intMsgNum, $strPathToDir = "./", $strFileEnding = ".eml" )
{
if( !@is_dir($strPathToDir) || !@is_writeable($strPathToDir) )
{
throw new POP3_Exception( $strPathToDir ." is not a directory or the directory is not writeable", self::ERR_PARAMETER);
}
$strPathToFile = $strPathToDir . $intMsgNum . $strFileEnding;
$this->saveToFile($strPathToFile, $this->getMsg($intMsgNum));
}
/**
*
*
*/
public function saveToSQL( &$strMail, &$resDBHandler, $strTable = "inbox" )
{
throw new POP3_Exception("",self::ERR_NOT_IMPLEMENTS);
}
public function saveToSQLFromServer( $intMsgNum, &$resDBHandler, $strTable = "inbox" )
{
throw new POP3_Exception("",self::ERR_NOT_IMPLEMENTS);
}
/**
* Return the version of the pop3.class.inc
*
* @return string $strVersion version string for this class
*/
public function getVersion()
{
return $this->strVersion;
}
/////////////////////////////////////////////////////////////////////////////
/////////////////////// Private functions ///////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
/**
* Compare the current state with the needed state.
*
* @param integer $intNeededState
*
* @throw POP3_Exception
*/
private function checkState( $intNeededState )
{
if ( $this->intCurState != $intNeededState)
throw new POP3_Exception("Invalid State !!! Please check your Code !!!", self::ERR_INVALID_STATE);
}
/**
* @param &integer $intMsgNum
*
* @throws POP3_Exception
*/
private function checkMsgNum( &$intMsgNum )
{
if( !is_int($intMsgNum) )
{
throw new POP3_Exception("Invalid message number given", self::ERR_PARAMETER);
}
}
/**
* Send a string to the server.
* Will append the network lineend "\r\n".
*
* @param string strCmd The string that should send to the pop3 server
*
* @return void
* @throws POP3_Exception
*/
private function send( $strCmd )
{
$strCmd .= "\r\n";
if( $this->bUseSockets )
{
if( @socket_send($this->resSocket, $strCmd, strlen($strCmd), 0) === FALSE )
{
throw new POP3_Exception("", self::ERR_SOCKETS);
}
}
else
{
if( !@fwrite($this->resSocket, $strCmd, strlen($strCmd)) )
{
throw new POP3_Exception("fwrite(): Failed to write string to socket",self::ERR_STREAM);
}
}
}
/**
* This function send the command to the server and will get the response
* If the command goes failed, the function will throw the POP3_Exception with the
* ERR_SEND_CMD error code and the response as error message.
*
* @param string $strCmd The string with the command for the pop3 server
* @param string $strLog Workaround for non clear passwords and usernames in log file
*
* @return string Server response if it was successfull
* @throws POP3_Exception
*/
private function sendCmd( $strCmd , $strLog = NULL )
{
( !is_null($strLog) ) ? $this->log($strLog) : $this->log($strCmd);
$this->send($strCmd);
$strRes = $this->recvString();
$this->log($strRes);
// 1. the check for the strlen of the result is a workaround for some server who don't send something after the quit command
// 2. should run with qmailer too...qmailer bug (pop3.class.inc) "." instead of "+OK" after RETR command
if( strlen($strRes) > 0 && $strRes{0} == '-' )
{
throw new POP3_Exception(trim($strRes), self::ERR_SEND_CMD);
}
return $strRes;
}
/**
* Return value:
* -----------------------------
a) on success returns number of bytes read
b) in case of no data on line, returns zero and $buf will be set to NULL.
c) on failure returns false, and $buf will be set to NULL.
To get the error code/message, call the appropriate socket functions.
d) in case of disconnect, the function returns either b) or c) which depends on how connection was closed from the other end.
It returns 0 if the connection was closed gracefully with FIN squence and false if it was reset.
*
* @param &string $strBuffer
* @param ineger $intBufferSize
*
* @return int number of recieved bytes
* @throws POP3_Exception
*/
private function recv( &$strBuffer, $intBufferSize = self::DEFAULT_BUFFER_SIZE )
{
$strBuffer = "";
if( $this->bUseSockets )
{
$intReadBytes = @socket_recv($this->resSocket, $strBuffer, $intBufferSize, 0);
if( $intReadBytes === FALSE )
{
throw new POP3_Exception("", POP3::ERR_SOCKETS);
}
}
else
{
if( !$strBuffer = @fread($this->resSocket, $intBufferSize) )
{
throw new POP3_Exception("fread(): Couldn't recieve from socket", self::ERR_STREAM);
}
}
return $intReadBytes;
}
/**
*
* @param integer $intBufferSize
*
* @return string $strBuffer Return the recieved String ended by "\r\n"
* @throw POP3_Exception
*/
private function recvString( $intBufferSize = self::DEFAULT_BUFFER_SIZE )
{
$strBuffer = "";
if( $this->bUseSockets )
{
if( ($strBuffer = @socket_read($this->resSocket, $intBufferSize , PHP_NORMAL_READ)) === FALSE )
{
throw new POP3_Exception("", self::ERR_SOCKETS);
}
// Workaround: The socket_read function with PHP_NORMAL_READ stops at "\r" but the network string ends with "\r\n"
// so we need to call the socket_read function again to get the "\n"
if( ($strBuffer2 = @socket_read($this->resSocket, 1 , PHP_NORMAL_READ)) === FALSE )
{
throw new POP3_Exception("", self::ERR_SOCKETS);
}
$strBuffer .= $strBuffer2;
}
else
{
if( !$strBuffer = @fgets($this->resSocket, $intBufferSize) )
{
throw new POP3_Exception("fgets(): Couldn't recieve the string from socket", self::ERR_STREAM);
}
}
return $strBuffer;
}
/**
* This function will get a complete list/message until the finally point was sended.
*
* @return string list/message
* @throw POP3_Exception
*/
private function recvToPoint()
{
$strRes = "";
while(true)
{
$strBuffer = $this->recvString();
$strRes .= $strBuffer;
if( strlen($strBuffer) == 3 && $strBuffer{0} == '.' )
{
break;
}
}
return $strRes;
}
/**
* Set the connection timeouts for a socket
*
* @param array $arrTimeout "sec" => seconds, "usec" => microseconds
*
* @return void
* @throw POP3_Exception
*/
private function setSockTimeout( $arrTimeout )
{
if( !is_array($arrTimeout) || !is_int($arrTimeout["sec"]) || !is_int($arrTimeout["usec"]) )
{
throw new POP3_Exception("Invalid Connection Timeout given", self::ERR_PARAMETER);
}
if( $this->bUseSockets )
{
if( !@socket_set_option($this->resSocket,SOL_SOCKET, SO_RCVTIMEO, $arrTimeout)
|| !@socket_set_option($this->resSocket,SOL_SOCKET, SO_SNDTIMEO, $arrTimeout) )
{
throw new POP3_Exception("", self::ERR_SOCKETS);
}
}
else
{
if( !@stream_set_timeout($this->resSocket, $arrTimeout["sec"], $arrTimeout["usec"]) )
{
throw new POP3_Exception("", self::ERR_STREAM);
}
}
$this->log("Set socket timeout to ". implode(".",$arrTimeout) ." secondes.");
}
/**
* Parse the needed apop banner if given
*
* @return void
*/
private function parseBanner( $strBuffer )
{
$intBufferLength = strlen($strBuffer);
$bOpenTag = FALSE;
for( $i=0; $i < $intBufferLength; $i++ )
{
if( $strBuffer{$i} == '>' )
{
break;
}
if( $bOpenTag )
{
$this->strAPOPBanner .= $strBuffer{$i};
continue;
}
if( $strBuffer{$i} == '<' )
{
$bOpenTag = TRUE;
}
}
}
/**
* // LOGGING FUNCTIONS
*/
private function openlog()
{
if( !$this->bLogOpened && is_writeable($this->strLogFile) )
{
echo $this->strLogFile;
if( !$this->resLogFp = fopen($this->strLogFile,"a+") )
{
throw new POP3_Exception("", self::ERR_LOG);
}
$this->bLogOpened = TRUE;
}
}
private function closelog()
{
if( $this->bLogOpened )
{
fclose($this->resLogFp);
$this->bLogOpened = FALSE;
}
}
private function log( $str )
{
if( $this->bLogOpened )
{
$str = date("Y-m-d H:i:s") .": ". trim($str) . PHP_EOL;
if( !fwrite( $this->resLogFp, $str, strlen($str) ) )
{
return new POP3_Exception("", self::ERR_LOG);
}
}
}
// }}}
}
// }}}
?>
+204
View File
@@ -0,0 +1,204 @@
<?php
/*
Sample File not more !!!
Author: Jointy <bestmischmaker@web.de>
Please read Readme.txt !!!
*/
require("pop3.class.inc");
// Constructor
// optional
$apop_detect = TRUE; // default = FALSE
$log = TRUE; // default = FALSE
$log_file = "pop3.class.log"; // must be set when $log = TRUE !!!
$qmailer = FALSE;
// func $pop3->connect()
$server = "pop.lycos.de";
// optional !!
// $port = "110";
// $conn_timeout = "25"; // Connection Timeout
// $sock_timeout = "10,500"; // Socket Timeout
// func $pop3->login()
$username = "";
$password = "";
// optional
//$apop = "0";
// MySQL Vars for connect to DB Server
$db["addr"] = "localhost";
$db["user"] = "";
$db["pass"] = "";
$db["link"] = FALSE;
$db["use"] = "mail";
// optional
$db["dir_table"] = "inbox"; // Table for header data
$db["msg_table"] = "messages"; // Table for complete Messages (/w header)...
// Your own free Vars
// Save to MySQL ??
$savetomysql = TRUE;
$savetofile = TRUE;
$delete = FALSE;
$pop3 = new POP3($log,$log_file,$apop_detect);
if($pop3->connect($server)){
if($pop3->login($username,$password)){
if(!$msg_list = $pop3->get_office_status()){
echo $pop3->error;
return;
}
}else{
echo $pop3->error;
return;
}
}else{
echo $pop3->error;
return;
}
$db["link"] = mysql_connect($db["addr"],$db["user"],$db["pass"]) or die(mysql_error());
mysql_select_db($db["use"],$db["link"]) or die(mysql_error());
$noob = TRUE;
for($i=1;$i<=$msg_list["count_mails"];$i++){
if(!$header = $pop3->get_top($i)){
echo $pop3->error;
}
// Get Message ID and set $unique_id for save2file()
$g = 0;
while(!ereg("</HEADER>",$header[$g])){
if(eregi("Message-ID",$header[$g])){
$unique_id = md5($header[$g]);
}
$g++;
}
unset($g);
$query = 'SELECT `unique_id` FROM `'.$msg_table.'` WHERE 1 AND `unique_id` = \''.$unique_id.'\' LIMIT 0, 1';
$result = mysql_query($query,$db["link"]) or die(mysql_error());
if($rows = mysql_fetch_array($result)){
$get_msg = FALSE;
$savetofile = FALSE;
$savetomysql = FALSE;
}
mysql_free_result($result);
unset($rows);
if($get_msg){
if(!$message = $pop3->get_mail($i, $qmailer)){
echo $pop3->error;
$savetofile = FALSE;
$savetomysql = FALSE;
$delete = FALSE;
}
}
// Save to File !!!
if($savetofile){
$filename = ".//mails//".$unique_id.".txt";
if(!is_file($filename)){
if(!$filesize = $pop3->save2file($message,$filename)){
echo $pop3->error;
return;
}else{
echo "File saved to ".$filename." (".$filesize." Bytes written) !! \r\n <br>";
}
}else{
echo "File <b>(".$filename.")</b> already exists. !! \r\n <br>";
}
}
// Save to MySQL
if($savetomysql){
if($count_bytes = $pop3->save2mysql($message,$db["link"],$db["dir_table"],$db["msg_table"])){
echo "File save to MySQL complete. (".$count_bytes." Bytes written) !! \r\n <br>";
}else{
echo $pop3->error;
return;
}
}
// Send Noob command !!
if($noop){
if(!$pop3->noop()){
echo $pop3->error;
$noob = FALSE;
}
}
// Delete MSG
if($delete){
if($pop3->delete_mail($i)){
echo "Nachricht als gelöscht markiert !!! \r\n <br>";
}else{
echo $pop3->error;
}
}
}
if($msg_list["count_mails"] == "0"){
echo "Keine neuen Nachrichten !!";
}
mysql_close($db["link"]);
$pop3->close();
?>
+83
View File
@@ -0,0 +1,83 @@
<?php
// vi: expandtab sw=4 ts=4 sts=4 nowrap nu:
/**
*
* @author: j0inty.sL
* @email: bestmischmaker@web.de
*/
error_reporting(E_ALL);
$strRootPath = dirname(__FILE__) . DIRECTORY_SEPARATOR;
require_once( $strRootPath ."pop3.class.php5.inc");
echo $strRootPath ."pop3.class.php5.inc";
// Socket Options
/**
* Remember that the encryption support doesn't work at time for the socket extension
* This will I implement later.
*
*/
$bUseSockets = FALSE;
$bUseTLS = TRUE;
$bIPv6 = FALSE;
$arrConnectionTimeout = array( "sec" => 10,
"usec" => 500 );
// POP3 Options
$strProtocol= "tls";
$strHost = "pop.gmail.com";
$intPort = 995;
$strUser = "test21";
$strPass = "test32";
$bAPopAutoDetect = TRUE;
$bHideUsernameAtLog = FALSE;
// Logging Options
$strLogFile = "php://stdout";//$strRootPath. "pop3.log";
// EMail store Sptions
$strPathToDir = $strRootPath."mails" .DIRECTORY_SEPARATOR;
$strFileEndings = ".eml";
try
{
// Instance the POP3 object
$objPOP3 = new POP3( $strLogFile, $bAPopAutoDetect, $bHideUsernameAtLog, $strProtocol, $bUseSockets );
// Connect to the POP3 server
$objPOP3->connect($strHost,$intPort,$arrConnectionTimeout,$bIPv6);
// Logging in
$objPOP3->login($strUser, $strPass);
// Get the office status
$arrOfficeStatus = $objPOP3->getOfficeStatus();
/**
* This for loop store the messages under their message number on the server
* and mark the message as delete on the server.
*/
for($intMsgNum = 1; $intMsgNum <= $arrOfficeStatus["count"]; $intMsgNum++ )
{
$objPOP3->saveToFileFromServer($intMsgNum, $strPathToDir, $strFileEndings);
// $objPOP3->deleteMsg($intMsgNum);
}
// Send the quit command and all as delete marked message will remove from the server.
// IMPORTANT:
// If you deleted many mails it could be that the +OK response will take some time.
$objPOP3->quit();
// Disconnect from the server
// !!! CAUTION !!!
// - this function does not send the QUIT command to the server
// so all as delete marked message will NOT delete
// To delete the mails from the server you have to send the quit command themself before disconnecting from the server
$objPOP3->disconnect();
}
catch( POP3_Exception $e )
{
die($e);
}
// Your next code
?>
+482
View File
@@ -0,0 +1,482 @@
--------------------------------------------------------------------------------
--------------------------pop3.class.inc---Version: 1.14------------------------
----------------------------------README----------------------------------------
--------------------------------------------------------------------------------
----------------------Created by Hemp "Jointy" Cluster -------------------------
-------------------------Email: BestMischMaker@web.de---------------------------
--------------------------------------------------------------------------------
----------------------------Readme Version: 0.11--------------------------------
-- Index --
Part: I - Description in german
Part: II - Documentation in german
Part: III - Documentation in english (written by Urb LeJeune <urb@e-government.com>)
-- Part: I --
Hallo !
Um nicht lange rum zuschwaffeln, werd ich mal gleich auf den Punkt kommen.
Also es handelt sich hier um eine Klasse für PHP4 ab Version 4.3.1.
Die "pop3.class.inc" ist geschrieben worden um mit POP3 Servern kommunizieren
zu können. Dabei wird der RFC1939 Standard voll unterstützt.
-- Part: II --
Fehlerverhalten
---------------
Sollte ein Fehler innerhalb der Klasse auftretten so wird immer die öffentliche Error
Variable mit der Fehlermeldung gesetzt...aber die Variable ist im normal Fall nicht
($pop3->error = FALSE)
z.B.
<?php
if(!$pop3->connect($server,$port,$conn_timeout,$sock_timeout){
echo $pop3->error;
return;
}
?>
Erwarten sie Werte koennen sie wie folgt auf Fehlerprüfen.
z.B.
<?php
if(!$message = $pop3->get_mail($msgnum)){
echo $pop3->error;
return;
}
?>
Zusatz:
!!! Sollte ein Fehler in einer Funktion auftretten die die Verbindung zum Server schliesst,
!!! heisst das nicht das das "QUIT" Commando gesendet wird, es wird nur der Socket geschlossen...
!!! somit bleiben alle als gelöscht markierten mails erhalten...
Constructor
---------------
// Hier wird nur festgelegt ob die POP Session geloggt werden soll, wenn ja
// auch wohin !!!
// Und seit neustem, ob die APOP Autodetection aktiv sein soll oder nicht...
// ( Ist nur dazu da wenn man sich nicht sicher ist ansonsten sollte APOP
// immer aktiv sein !! )
new POP3($log = FALSE, $log_file = "", $apop_detect = FALSE)
- $log wenn log aktiv sein soll $log = TRUE setzen.
- $log_file muss einen Dateinamen enthalten ( folgenes geht auch )
( win32 z.B. ".//log//pop3.class.log" wobei der Ordner "log" existieren muss !!! )
- $apop_detect sollte die var TRUE sein wird geprüft ob ein banner übergeben wurde
der für apop notwendig ist, wenn ja wird der "APOP" Command zum login verwendet.
Funktionen
---------------
--connect($server,$port = "110",$conn_timeout = "25",$sock_timeout = "15,000")
// Baut die Verbindung zum POP3 Server auf, und überprüft ob die erste Nachricht
// ein "+OK" ist...wenn nicht wird die Fehlervariable gesetzt und FALSE zurückgeben
// sowie die Verbindung wieder geschlossen.
- $server kann der DNS Name oder auch die IP Addresse sein !!!
- $port Welcher Port wird verwendet (default = "110")
- $conn_timeout Der Timeout in Sekunden für den Aufbau der Verbindung !!!
- $sock_timeout Der Socket Timeout für spätere Verbindungshandling !!!
(muss immer im folgenen Format angegeben werden !!
Z.B.: 10 Sekunden (,) 000 Milisekunden = 10 Sec...
$sock_timeout = "15,000"
--login($user,$pass,$apop)
// Logt sich über die ausgewählte Authorisierungsart beim Server ein.
// Tritt ein Fehler auf gibt die Funktion "FALSE" zurück und die Verbindung
// wird geschlossen.
- $user muss gesetzt werden.
- $pass muss gesetzt werden.
- $apop (default = "0") hier setzt man manuell APOP(TRUE("1") oder FALSE("0"))
--$msg_array = get_office_status()
// Diese Funktion holt sich den kompletten Status des Postfaches...
// Als Return erhalten sie ein mehrdimensionalles Array...wie dieses mal als Beispiel.
// In Fehlerfall "return = FALSE" und Verbindung wird geschlossen.
Array
(
[count_mails] => 3
[octets] => 3257477
[1] => Array
(
[size] => 832
[uid] => 617999468
)
[2] => Array
(
[size] => 3253781
[uid] => 617999616
)
[3] => Array
(
[size] => 2864
[uid] => 617999782
)
)
$msg_array["count_mails"] die Anzahl der sich im Postfach befindenen Mails
$msg_array["octets"] die Grösse aller Mails in Octets (Bytes) !!
$msg_array["msgnum"] Nummer der Nachricht im Postfach !!!
$msg_array["msgnum"]["uid"] unique-id (Eindeutige ID auf den POP3 Server)
$msg_array["msgnum"]["size"] Grösse der Nachricht in Octets !!
--$message = get_mail($msgnum, $qmailer = FALSE)
// Holt die Nachricht vom Server ab !!!
// Jede vom Server übertragene Zeile wird in einen extra Key gelegt...
// das Array ist immer nummerisch !!!
// Message und Header sind eindeutig durch (<header></header> und <message></message>)
// getrennt.
// PS: Im Fehlerfall wird der Socket nicht geschlossen !!!
$msgnum Nachrichtennummer die abgeholt werden soll.
$qmailer Sollte sie mit einem QMail Server aggieren, dann hier bitte TRUE
setzten
--$header = get_top($msgnum,$lines="0")
// Diese Funktion kann benutzt werden um nur die Header Info's einer E-Mail
// zu bekommen. Durch die Angabe von $lines werden weitere body lines mit ausgegeben.
// PS: Im Fehlerfall wird der Socket nicht geschlossen !!!
$msgnum Nummer der Nachricht im Postfach !!!
$lines wieviele zeilen sollen von body mit ausgegeben werden.
(default = "0")
z.B
$header = get_top($msgnum);
$header_w_lines = get_top($msgnum,"5");
--$uid = uidl($msgnum)
// Holt sich die Unique-ID (Eindeutige-ID) für die angegeben Nachricht im Postfach !!!
// Ist $msgnum = "0" oder $uid_list = uidl(); dann wird die komplette uid liste für alle
// sich im Postfach befindenen Mails geholt
// PS: Im Fehlerfall wird der Socket nicht geschlossen !!!
$msgnum Nummer der Nachricht (default = "0")
--noop()
// Sendet ein "NOOP" Command...prüft ob server noch lebt !!!
// PS: Im Fehlerfall wird der Socket nicht geschlossen !!!
--delete_mail($msgnum)
// Markiert die angegeben Nachricht als gelöscht.
// Die als gelöscht markierten Nachrichten werden erst nachdem "QUIT" Command gelöscht !!!
// PS: Im Fehlerfall wird der Socket nicht geschlossen !!!
$msgnum Nummer der Nachricht im Postfach !
--reset()
// Sendet das "RSET" Command...alle als gelöscht markierten Nachrichten werden wieder
// deselectiert.
// PS: Im Fehlerfall wird der Socket nicht geschlossen !!!
--close()
// Sendet das "QUIT" Command zum Server !!!
// Alle als gelöscht markierten Nachrichten werden nun endgültig gelöscht und
// die Verbindung geschlossen...
--save2file($msgnum,$filename)
// Schreibt die Email in die angegebene Datei, die Nachricht muss als Numerisches
// Array übergeben werden.
// Diese Funktion ist passent zur get_mail() geschrieben worden.
$msgnum Nachrichtennummer im Postfach !!
$filename Dateiname wo die Mail abgespeichert werden soll.
( es geht auch )
( win32 "//mails//filename" wobei der Ordner "mails" existieren muss. )
-- save2mysql($message, $mysql_socket, $dir_table = "inbox", $msg_table = "messages", $read = "0")
// Diese Funktion ist passent zur get_mail() geschrieben worden.
// Speichert die Message folgener Maßen in ein MySQL Datenbank !!!
//
// ?? Was muss ich tun ???
// - MySQL Verbindung öffenen und die DB selektieren.
//
// Die beiden notwendigen Tabellen werden, wenn nicht schon vorhanden, von der Funktion selbst erstellt !!!
// Die beiden Tabellen haben zu einem die Funktion nur die Wichtigen Header Daten zuspeichern
// sowie die komplette Nachricht.
$dir_table - Tabelle wo die Headerdaten gespeichert werden !!!
$msg_table hier kommen alle Nachrichten im vollen Umfang rein
$mysql_socket der göffnete Socket zum MySQL Server mit Zugriff auf eine selektierte Datenbank !!!
$read soll die gelesen variable spielen !! 0 = nicht gelesen , 1 = gelesen !!! :)
$message Numerisches Array wobei jeder key = zeile ist !!!
// Wichtige Tabellenstrukturen
// In "$msg_table" gibt es ein Feld Namens "unique_id", den wert bildet
// der MD5 Fingerprint von $dir_table["msg_id"]
// z.B. md5("Message-ID: <1052913281007071@lycos-europe.com>");
// !!!! Das ist wichtig um die Nachrichten später zu ordnen zukönnen !!!!
// für das feld "received" in tabelle "$dir_table" gilt,
// mehrere Received Strings werden durch ein "<next>" getrennt !!!
// z.B.
// $dir_table["received"] = Received: from ns10493a.cobalthosting.net by mx02.web.de with smtp <next> Received: (from httpd@localhost)
////////////////////////////////////////////////////////////////////////////////
Part: III
(written by Urb LeJeune <urb@e-government.com>)
!!! Thanks a Lot !!!
////////////////////////////////////////////////////////////////////////////////
////////////////////////////// //////////////////////////////////////////////////
Public Functions
// Constructor
Your POP3 session can be logged by passing two variables when you instantiate
the pop3 class as in the following example.
$PerformLogging = TRUE;
$LogFileName = "pop3.class.log";
$pop3 = new POP3($PerformLogging,$LogFileName);
- Only the POP3 commands and server responses are save in the log file.
- Error messages are displayed on your browser.
APOP (Authenticated Post Office Protocol)
Every mail server connection you make sends your username and password across
the network in clear text. This is a popular way for hackers to see your
password using a "sniffer" program. With APOP, your password is encrypted
while being transmitted over the network.
Before establishing a connection set:
$apop_detect = TRUE or FALSE
Now all mailservers support ASOP.
// Functions
The follow class methods are available.
//////////
connect($server, $port = "110", $timeout = "25", $sock_timeout = "10,500")
// Vars:
- $server ( Server IP or DNS )
- $port ( Server port default is "110" )
- $timeout ( Connection timeout for connect to server )
- $sock_timeout ( Socket timeout for all actions (10 sec 500 msec) = (10,500))
If connection is established the method returns TRUE. If the connection is not
successfully established FALSE is returned and $this->error = msg is displayed.
//////////
login($user,$pass,$apop = "0")
// Vars:
- $apop ( 1 = true and 0 = false) (default = 0)
//////////
get_office_status()
- If an error Connection will closed.
- A successful Connection will return an associated array such as the following:
Array
(
[count_mails] => 3
[octets] => 3257477
[1] => Array
(
[size] => 832
[uid] => 617999468
)
[2] => Array
(
[size] => 3253781
[uid] => 617999616
)
[3] => Array
(
[size] => 2864
[uid] => 617999782
)
)
/////////
get_mail($msg_number)
- If the command fails the connection is not closed and FALSE is returned.
- If get_mail() succeeds, an array is returned where every line of the
mail message, including the header, is an element of the array. Such as:
Array(
[0] => "line1"
[1] => "line2"
....
)
//////////////////////////////////////////////////////////////////////////
// IMPORTANT //
// If your mail count is high or your connection time is slow, or both, //
// you may exceed the default execution time of 30 seconds. In that //
// case set the execution time to more than 30 seconds. //
//////////////////////////////////////////////////////////////////////////
/////////
delete_mail($msg_number)
- Mark an email as delete
- You must executed the close() method for the mail to be deleted.
- If program terminates without executing a close() method the
command, connection will not closed.
- Execute reset() to unmark messages previously marked as deleted.
- If the command fails the connection is not closed and FALSE is returned.
/////////
save2file($message,$filename)
- $message must be a numeric array with each line terminated with a "CRLF".
- If the command fails the connection is not closed and FALSE is returned.
Array(
[0] => "line1"
[1] => "line2"
....
)
$filename
- The default file name is base64_encode(uid).".txt"
- To check if you have download this mail
base64_encode(uid).".txt" == $filename
// Example directories and file name
win32 .//mails// or c://ownfiles//etc...
linux ./mails/ or /dev/hda1/ownfiles/etc...
/////////
save2mysql($message,$mysql_socket,$dir_table = "inbox", $msg_table = "messages",$read = "0")
// If the command fails the connection is not closed and FALSE is returned.
// If mail already in $msg_table exists the method return false.
// If there is a mysql error the method returns false and
// mysql_errno() ." -- ". mysql error is set on $pop3-error
// like this: "1054 -- Unknown column '' in 'field list'"
//
// The method checks toe establish if mail exists or not.
// When mail exists the method returns false and an errormsg is sent on $pop3->error
//
// !!!!!!!!!!!!!!!!!!!!!!! IMPORTANT !!!!!!!!!!!!!!!!!!!!!!!!!!
// In $msg_table give a field named "unique_id", the value
// is a md5 fingerprint from $dir_table field "msg_id"
//
// If the "received" field in $dir_table spans more than one Server the Received
// Strings are split with a "<next>"
// As an example: $dir_table["received"] =
// Received: from ns10493a.cobalthosting.net by mx02.web.de with smtp
// <next> Received: (from httpd@localhost)
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
/////////
noop()
- Send the "NOOP" command to server
- If the command fails, the connection will not closed !!
/////////
get_top($msg_number,$lines="0")
- If you only want header information use get_top().
- The format is get_top($msg_number,"number-of-lines")
- The "number-of-lines" parameter determines the number of lines to be read.
- If "number-of-lines" exceeds the line count, the entire mail message is returned.
- If the command fails the connection is not closed and FALSE is returned.
/////////
reset()
- All mail previously marked as deleted will be marked as undeleted.
- If the command fails the connection is not closed and FALSE is returned.
/////////
uidl($msg_number) (default = "0")
- If $msg_number is set to FALSE (0 or null) the entire uid list is returned.
- If $msg_number is set to a valid message number, the uid for the designed
mail is returned..
- If the command fails the connection is not closed and FALSE is returned.
////////////////////////////////////////////////////////////////////////////////
Private Functions
/////////
_putline($string)
- Put a command to server socket.
- $string should not be terminated with "CRLF".
/////////
_getnextstring()
- optional: $buffer_size (default = "512")
- get the next String from server socket.
/////////
_logging($string)
- $string is written to the log_file as established in the class constructor.
- $string should not be terminated with "CRLF".
/////////
_checkstate($string)
- Check the pop3 server connection state.
- $string is set to method (function) function name.
/////////
_parse_banner($server_text)
- $server_text = first response after connect.
- Returns the server banner for APOP Login command.
/////////
_cleanup()
- unset some vars
- close log_file
- close server socket
/////////
_stats()
- Get maildrop stats
- If successful return an associative array containing:
["count_mails"]
["octets"]
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
--------------------------------------------------------------------------------
----------------------------------END-------------------------------------------
--------------------------------------------------------------------------------