| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662 | <?php/** * mail_fetch/setup.php * * Copyright (c) 1999-2011 CDI (cdi@thewebmasters.net) All Rights Reserved * Modified by Philippe Mingo 2001-2009 mingo@rotedic.com * An RFC 1939 compliant wrapper class for the POP3 protocol. * * Licensed under the GNU GPL. For full terms see the file COPYING. * * POP3 class * * @copyright 1999-2011 The SquirrelMail Project Team * @license http://opensource.org/licenses/gpl-license.php GNU Public License * @package plugins * @subpackage mail_fetch */class POP3 {    var $ERROR      = '';       //  Error string.    var $TIMEOUT    = 60;       //  Default timeout before giving up on a                                //  network operation.    var $COUNT      = -1;       //  Mailbox msg count    var $BUFFER     = 512;      //  Socket buffer for socket fgets() calls.                                //  Per RFC 1939 the returned line a POP3                                //  server can send is 512 bytes.    var $FP         = '';       //  The connection to the server's                                //  file descriptor    var $MAILSERVER = '';       // Set this to hard code the server name    var $DEBUG      = FALSE;    // set to true to echo pop3                                // commands and responses to error_log                                // this WILL log passwords!    var $BANNER     = '';       //  Holds the banner returned by the                                //  pop server - used for apop()    var $ALLOWAPOP  = FALSE;    //  Allow or disallow apop()                                //  This must be set to true                                //  manually	/**	 * PHP5 constructor.	 */    function __construct ( $server = '', $timeout = '' ) {        settype($this->BUFFER,"integer");        if( !empty($server) ) {            // Do not allow programs to alter MAILSERVER            // if it is already specified. They can get around            // this if they -really- want to, so don't count on it.            if(empty($this->MAILSERVER))                $this->MAILSERVER = $server;        }        if(!empty($timeout)) {            settype($timeout,"integer");            $this->TIMEOUT = $timeout;            if (!ini_get('safe_mode'))                set_time_limit($timeout);        }        return true;    }	/**	 * PHP4 constructor.	 */	public function POP3( $server = '', $timeout = '' ) {		self::__construct( $server, $timeout );	}    function update_timer () {        if (!ini_get('safe_mode'))            set_time_limit($this->TIMEOUT);        return true;    }    function connect ($server, $port = 110)  {        //  Opens a socket to the specified server. Unless overridden,        //  port defaults to 110. Returns true on success, false on fail        // If MAILSERVER is set, override $server with its value.    if (!isset($port) || !$port) {$port = 110;}        if(!empty($this->MAILSERVER))            $server = $this->MAILSERVER;        if(empty($server)){            $this->ERROR = "POP3 connect: " . _("No server specified");            unset($this->FP);            return false;        }        $fp = @fsockopen("$server", $port, $errno, $errstr);        if(!$fp) {            $this->ERROR = "POP3 connect: " . _("Error ") . "[$errno] [$errstr]";            unset($this->FP);            return false;        }        socket_set_blocking($fp,-1);        $this->update_timer();        $reply = fgets($fp,$this->BUFFER);        $reply = $this->strip_clf($reply);        if($this->DEBUG)            error_log("POP3 SEND [connect: $server] GOT [$reply]",0);        if(!$this->is_ok($reply)) {            $this->ERROR = "POP3 connect: " . _("Error ") . "[$reply]";            unset($this->FP);            return false;        }        $this->FP = $fp;        $this->BANNER = $this->parse_banner($reply);        return true;    }    function user ($user = "") {        // Sends the USER command, returns true or false        if( empty($user) ) {            $this->ERROR = "POP3 user: " . _("no login ID submitted");            return false;        } elseif(!isset($this->FP)) {            $this->ERROR = "POP3 user: " . _("connection not established");            return false;        } else {            $reply = $this->send_cmd("USER $user");            if(!$this->is_ok($reply)) {                $this->ERROR = "POP3 user: " . _("Error ") . "[$reply]";                return false;            } else                return true;        }    }    function pass ($pass = "")     {        // Sends the PASS command, returns # of msgs in mailbox,        // returns false (undef) on Auth failure        if(empty($pass)) {            $this->ERROR = "POP3 pass: " . _("No password submitted");            return false;        } elseif(!isset($this->FP)) {            $this->ERROR = "POP3 pass: " . _("connection not established");            return false;        } else {            $reply = $this->send_cmd("PASS $pass");            if(!$this->is_ok($reply)) {                $this->ERROR = "POP3 pass: " . _("Authentication failed") . " [$reply]";                $this->quit();                return false;            } else {                //  Auth successful.                $count = $this->last("count");                $this->COUNT = $count;                return $count;            }        }    }    function apop ($login,$pass) {        //  Attempts an APOP login. If this fails, it'll        //  try a standard login. YOUR SERVER MUST SUPPORT        //  THE USE OF THE APOP COMMAND!        //  (apop is optional per rfc1939)        if(!isset($this->FP)) {            $this->ERROR = "POP3 apop: " . _("No connection to server");            return false;        } elseif(!$this->ALLOWAPOP) {            $retVal = $this->login($login,$pass);            return $retVal;        } elseif(empty($login)) {            $this->ERROR = "POP3 apop: " . _("No login ID submitted");            return false;        } elseif(empty($pass)) {            $this->ERROR = "POP3 apop: " . _("No password submitted");            return false;        } else {            $banner = $this->BANNER;            if( (!$banner) or (empty($banner)) ) {                $this->ERROR = "POP3 apop: " . _("No server banner") . ' - ' . _("abort");                $retVal = $this->login($login,$pass);                return $retVal;            } else {                $AuthString = $banner;                $AuthString .= $pass;                $APOPString = md5($AuthString);                $cmd = "APOP $login $APOPString";                $reply = $this->send_cmd($cmd);                if(!$this->is_ok($reply)) {                    $this->ERROR = "POP3 apop: " . _("apop authentication failed") . ' - ' . _("abort");                    $retVal = $this->login($login,$pass);                    return $retVal;                } else {                    //  Auth successful.                    $count = $this->last("count");                    $this->COUNT = $count;                    return $count;                }            }        }    }    function login ($login = "", $pass = "") {        // Sends both user and pass. Returns # of msgs in mailbox or        // false on failure (or -1, if the error occurs while getting        // the number of messages.)        if( !isset($this->FP) ) {            $this->ERROR = "POP3 login: " . _("No connection to server");            return false;        } else {            $fp = $this->FP;            if( !$this->user( $login ) ) {                //  Preserve the error generated by user()                return false;            } else {                $count = $this->pass($pass);                if( (!$count) || ($count == -1) ) {                    //  Preserve the error generated by last() and pass()                    return false;                } else                    return $count;            }        }    }    function top ($msgNum, $numLines = "0") {        //  Gets the header and first $numLines of the msg body        //  returns data in an array with each returned line being        //  an array element. If $numLines is empty, returns        //  only the header information, and none of the body.        if(!isset($this->FP)) {            $this->ERROR = "POP3 top: " . _("No connection to server");            return false;        }        $this->update_timer();        $fp = $this->FP;        $buffer = $this->BUFFER;        $cmd = "TOP $msgNum $numLines";        fwrite($fp, "TOP $msgNum $numLines\r\n");        $reply = fgets($fp, $buffer);        $reply = $this->strip_clf($reply);        if($this->DEBUG) {            @error_log("POP3 SEND [$cmd] GOT [$reply]",0);        }        if(!$this->is_ok($reply))        {            $this->ERROR = "POP3 top: " . _("Error ") . "[$reply]";            return false;        }        $count = 0;        $MsgArray = array();        $line = fgets($fp,$buffer);        while ( !preg_match('/^\.\r\n/',$line))        {            $MsgArray[$count] = $line;            $count++;            $line = fgets($fp,$buffer);            if(empty($line))    { break; }        }        return $MsgArray;    }    function pop_list ($msgNum = "") {        //  If called with an argument, returns that msgs' size in octets        //  No argument returns an associative array of undeleted        //  msg numbers and their sizes in octets        if(!isset($this->FP))        {            $this->ERROR = "POP3 pop_list: " . _("No connection to server");            return false;        }        $fp = $this->FP;        $Total = $this->COUNT;        if( (!$Total) or ($Total == -1) )        {            return false;        }        if($Total == 0)        {            return array("0","0");            // return -1;   // mailbox empty        }        $this->update_timer();        if(!empty($msgNum))        {            $cmd = "LIST $msgNum";            fwrite($fp,"$cmd\r\n");            $reply = fgets($fp,$this->BUFFER);            $reply = $this->strip_clf($reply);            if($this->DEBUG) {                @error_log("POP3 SEND [$cmd] GOT [$reply]",0);            }            if(!$this->is_ok($reply))            {                $this->ERROR = "POP3 pop_list: " . _("Error ") . "[$reply]";                return false;            }            list($junk,$num,$size) = preg_split('/\s+/',$reply);            return $size;        }        $cmd = "LIST";        $reply = $this->send_cmd($cmd);        if(!$this->is_ok($reply))        {            $reply = $this->strip_clf($reply);            $this->ERROR = "POP3 pop_list: " . _("Error ") .  "[$reply]";            return false;        }        $MsgArray = array();        $MsgArray[0] = $Total;        for($msgC=1;$msgC <= $Total; $msgC++)        {            if($msgC > $Total) { break; }            $line = fgets($fp,$this->BUFFER);            $line = $this->strip_clf($line);            if(strpos($line, '.') === 0)            {                $this->ERROR = "POP3 pop_list: " . _("Premature end of list");                return false;            }            list($thisMsg,$msgSize) = preg_split('/\s+/',$line);            settype($thisMsg,"integer");            if($thisMsg != $msgC)            {                $MsgArray[$msgC] = "deleted";            }            else            {                $MsgArray[$msgC] = $msgSize;            }        }        return $MsgArray;    }    function get ($msgNum) {        //  Retrieve the specified msg number. Returns an array        //  where each line of the msg is an array element.        if(!isset($this->FP))        {            $this->ERROR = "POP3 get: " . _("No connection to server");            return false;        }        $this->update_timer();        $fp = $this->FP;        $buffer = $this->BUFFER;        $cmd = "RETR $msgNum";        $reply = $this->send_cmd($cmd);        if(!$this->is_ok($reply))        {            $this->ERROR = "POP3 get: " . _("Error ") . "[$reply]";            return false;        }        $count = 0;        $MsgArray = array();        $line = fgets($fp,$buffer);        while ( !preg_match('/^\.\r\n/',$line))        {            if ( $line[0] == '.' ) { $line = substr($line,1); }            $MsgArray[$count] = $line;            $count++;            $line = fgets($fp,$buffer);            if(empty($line))    { break; }        }        return $MsgArray;    }    function last ( $type = "count" ) {        //  Returns the highest msg number in the mailbox.        //  returns -1 on error, 0+ on success, if type != count        //  results in a popstat() call (2 element array returned)        $last = -1;        if(!isset($this->FP))        {            $this->ERROR = "POP3 last: " . _("No connection to server");            return $last;        }        $reply = $this->send_cmd("STAT");        if(!$this->is_ok($reply))        {            $this->ERROR = "POP3 last: " . _("Error ") . "[$reply]";            return $last;        }        $Vars = preg_split('/\s+/',$reply);        $count = $Vars[1];        $size = $Vars[2];        settype($count,"integer");        settype($size,"integer");        if($type != "count")        {            return array($count,$size);        }        return $count;    }    function reset () {        //  Resets the status of the remote server. This includes        //  resetting the status of ALL msgs to not be deleted.        //  This method automatically closes the connection to the server.        if(!isset($this->FP))        {            $this->ERROR = "POP3 reset: " . _("No connection to server");            return false;        }        $reply = $this->send_cmd("RSET");        if(!$this->is_ok($reply))        {            //  The POP3 RSET command -never- gives a -ERR            //  response - if it ever does, something truly            //  wild is going on.            $this->ERROR = "POP3 reset: " . _("Error ") . "[$reply]";            @error_log("POP3 reset: ERROR [$reply]",0);        }        $this->quit();        return true;    }    function send_cmd ( $cmd = "" )    {        //  Sends a user defined command string to the        //  POP server and returns the results. Useful for        //  non-compliant or custom POP servers.        //  Do NOT includ the \r\n as part of your command        //  string - it will be appended automatically.        //  The return value is a standard fgets() call, which        //  will read up to $this->BUFFER bytes of data, until it        //  encounters a new line, or EOF, whichever happens first.        //  This method works best if $cmd responds with only        //  one line of data.        if(!isset($this->FP))        {            $this->ERROR = "POP3 send_cmd: " . _("No connection to server");            return false;        }        if(empty($cmd))        {            $this->ERROR = "POP3 send_cmd: " . _("Empty command string");            return "";        }        $fp = $this->FP;        $buffer = $this->BUFFER;        $this->update_timer();        fwrite($fp,"$cmd\r\n");        $reply = fgets($fp,$buffer);        $reply = $this->strip_clf($reply);        if($this->DEBUG) { @error_log("POP3 SEND [$cmd] GOT [$reply]",0); }        return $reply;    }    function quit() {        //  Closes the connection to the POP3 server, deleting        //  any msgs marked as deleted.        if(!isset($this->FP))        {            $this->ERROR = "POP3 quit: " . _("connection does not exist");            return false;        }        $fp = $this->FP;        $cmd = "QUIT";        fwrite($fp,"$cmd\r\n");        $reply = fgets($fp,$this->BUFFER);        $reply = $this->strip_clf($reply);        if($this->DEBUG) { @error_log("POP3 SEND [$cmd] GOT [$reply]",0); }        fclose($fp);        unset($this->FP);        return true;    }    function popstat () {        //  Returns an array of 2 elements. The number of undeleted        //  msgs in the mailbox, and the size of the mbox in octets.        $PopArray = $this->last("array");        if($PopArray == -1) { return false; }        if( (!$PopArray) or (empty($PopArray)) )        {            return false;        }        return $PopArray;    }    function uidl ($msgNum = "")    {        //  Returns the UIDL of the msg specified. If called with        //  no arguments, returns an associative array where each        //  undeleted msg num is a key, and the msg's uidl is the element        //  Array element 0 will contain the total number of msgs        if(!isset($this->FP)) {            $this->ERROR = "POP3 uidl: " . _("No connection to server");            return false;        }        $fp = $this->FP;        $buffer = $this->BUFFER;        if(!empty($msgNum)) {            $cmd = "UIDL $msgNum";            $reply = $this->send_cmd($cmd);            if(!$this->is_ok($reply))            {                $this->ERROR = "POP3 uidl: " . _("Error ") . "[$reply]";                return false;            }            list ($ok,$num,$myUidl) = preg_split('/\s+/',$reply);            return $myUidl;        } else {            $this->update_timer();            $UIDLArray = array();            $Total = $this->COUNT;            $UIDLArray[0] = $Total;            if ($Total < 1)            {                return $UIDLArray;            }            $cmd = "UIDL";            fwrite($fp, "UIDL\r\n");            $reply = fgets($fp, $buffer);            $reply = $this->strip_clf($reply);            if($this->DEBUG) { @error_log("POP3 SEND [$cmd] GOT [$reply]",0); }            if(!$this->is_ok($reply))            {                $this->ERROR = "POP3 uidl: " . _("Error ") . "[$reply]";                return false;            }            $line = "";            $count = 1;            $line = fgets($fp,$buffer);            while ( !preg_match('/^\.\r\n/',$line)) {                list ($msg,$msgUidl) = preg_split('/\s+/',$line);                $msgUidl = $this->strip_clf($msgUidl);                if($count == $msg) {                    $UIDLArray[$msg] = $msgUidl;                }                else                {                    $UIDLArray[$count] = 'deleted';                }                $count++;                $line = fgets($fp,$buffer);            }        }        return $UIDLArray;    }    function delete ($msgNum = "") {        //  Flags a specified msg as deleted. The msg will not        //  be deleted until a quit() method is called.        if(!isset($this->FP))        {            $this->ERROR = "POP3 delete: " . _("No connection to server");            return false;        }        if(empty($msgNum))        {            $this->ERROR = "POP3 delete: " . _("No msg number submitted");            return false;        }        $reply = $this->send_cmd("DELE $msgNum");        if(!$this->is_ok($reply))        {            $this->ERROR = "POP3 delete: " . _("Command failed ") . "[$reply]";            return false;        }        return true;    }    //  *********************************************************    //  The following methods are internal to the class.    function is_ok ($cmd = "") {        //  Return true or false on +OK or -ERR        if( empty($cmd) )            return false;        else            return( stripos($cmd, '+OK') !== false );    }    function strip_clf ($text = "") {        // Strips \r\n from server responses        if(empty($text))            return $text;        else {            $stripped = str_replace(array("\r","\n"),'',$text);            return $stripped;        }    }    function parse_banner ( $server_text ) {        $outside = true;        $banner = "";        $length = strlen($server_text);        for($count =0; $count < $length; $count++)        {            $digit = substr($server_text,$count,1);            if(!empty($digit))             {                if( (!$outside) && ($digit != '<') && ($digit != '>') )                {                    $banner .= $digit;                }                if ($digit == '<')                {                    $outside = false;                }                if($digit == '>')                {                    $outside = true;                }            }        }        $banner = $this->strip_clf($banner);    // Just in case        return "<$banner>";    }}   // End class// For php4 compatibilityif (!function_exists("stripos")) {    function stripos($haystack, $needle){        return strpos($haystack, stristr( $haystack, $needle ));    }}
 |