[ Index ]

PHP Cross Reference of WordPress

title

Body

[close]

/wp-includes/ -> class-pop3.php (source)

   1  <?php
   2  /**
   3   * mail_fetch/setup.php
   4   *
   5   * Copyright (c) 1999-2011 CDI (cdi@thewebmasters.net) All Rights Reserved
   6   * Modified by Philippe Mingo 2001-2009 mingo@rotedic.com
   7   * An RFC 1939 compliant wrapper class for the POP3 protocol.
   8   *
   9   * Licensed under the GNU GPL. For full terms see the file COPYING.
  10   *
  11   * POP3 class
  12   *
  13   * @copyright 1999-2011 The SquirrelMail Project Team
  14   * @license http://opensource.org/licenses/gpl-license.php GNU Public License
  15   * @package plugins
  16   * @subpackage mail_fetch
  17   */
  18  
  19  class POP3 {
  20      var $ERROR      = '';       //  Error string.
  21  
  22      var $TIMEOUT    = 60;       //  Default timeout before giving up on a
  23                                  //  network operation.
  24  
  25      var $COUNT      = -1;       //  Mailbox msg count
  26  
  27      var $BUFFER     = 512;      //  Socket buffer for socket fgets() calls.
  28                                  //  Per RFC 1939 the returned line a POP3
  29                                  //  server can send is 512 bytes.
  30  
  31      var $FP         = '';       //  The connection to the server's
  32                                  //  file descriptor
  33  
  34      var $MAILSERVER = '';       // Set this to hard code the server name
  35  
  36      var $DEBUG      = FALSE;    // set to true to echo pop3
  37                                  // commands and responses to error_log
  38                                  // this WILL log passwords!
  39  
  40      var $BANNER     = '';       //  Holds the banner returned by the
  41                                  //  pop server - used for apop()
  42  
  43      var $ALLOWAPOP  = FALSE;    //  Allow or disallow apop()
  44                                  //  This must be set to true
  45                                  //  manually
  46  
  47      /**
  48       * PHP5 constructor.
  49       */
  50      function __construct ( $server = '', $timeout = '' ) {
  51          settype($this->BUFFER,"integer");
  52          if( !empty($server) ) {
  53              // Do not allow programs to alter MAILSERVER
  54              // if it is already specified. They can get around
  55              // this if they -really- want to, so don't count on it.
  56              if(empty($this->MAILSERVER))
  57                  $this->MAILSERVER = $server;
  58          }
  59          if(!empty($timeout)) {
  60              settype($timeout,"integer");
  61              $this->TIMEOUT = $timeout;
  62              if (!ini_get('safe_mode'))
  63                  set_time_limit($timeout);
  64          }
  65          return true;
  66      }
  67  
  68      /**
  69       * PHP4 constructor.
  70       */
  71  	public function POP3( $server = '', $timeout = '' ) {
  72          self::__construct( $server, $timeout );
  73      }
  74  
  75      function update_timer () {
  76          if (!ini_get('safe_mode'))
  77              set_time_limit($this->TIMEOUT);
  78          return true;
  79      }
  80  
  81      function connect ($server, $port = 110)  {
  82          //  Opens a socket to the specified server. Unless overridden,
  83          //  port defaults to 110. Returns true on success, false on fail
  84  
  85          // If MAILSERVER is set, override $server with its value.
  86  
  87      if (!isset($port) || !$port) {$port = 110;}
  88          if(!empty($this->MAILSERVER))
  89              $server = $this->MAILSERVER;
  90  
  91          if(empty($server)){
  92              $this->ERROR = "POP3 connect: " . _("No server specified");
  93              unset($this->FP);
  94              return false;
  95          }
  96  
  97          $fp = @fsockopen("$server", $port, $errno, $errstr);
  98  
  99          if(!$fp) {
 100              $this->ERROR = "POP3 connect: " . _("Error ") . "[$errno] [$errstr]";
 101              unset($this->FP);
 102              return false;
 103          }
 104  
 105          socket_set_blocking($fp,-1);
 106          $this->update_timer();
 107          $reply = fgets($fp,$this->BUFFER);
 108          $reply = $this->strip_clf($reply);
 109          if($this->DEBUG)
 110              error_log("POP3 SEND [connect: $server] GOT [$reply]",0);
 111          if(!$this->is_ok($reply)) {
 112              $this->ERROR = "POP3 connect: " . _("Error ") . "[$reply]";
 113              unset($this->FP);
 114              return false;
 115          }
 116          $this->FP = $fp;
 117          $this->BANNER = $this->parse_banner($reply);
 118          return true;
 119      }
 120  
 121      function user ($user = "") {
 122          // Sends the USER command, returns true or false
 123  
 124          if( empty($user) ) {
 125              $this->ERROR = "POP3 user: " . _("no login ID submitted");
 126              return false;
 127          } elseif(!isset($this->FP)) {
 128              $this->ERROR = "POP3 user: " . _("connection not established");
 129              return false;
 130          } else {
 131              $reply = $this->send_cmd("USER $user");
 132              if(!$this->is_ok($reply)) {
 133                  $this->ERROR = "POP3 user: " . _("Error ") . "[$reply]";
 134                  return false;
 135              } else
 136                  return true;
 137          }
 138      }
 139  
 140      function pass ($pass = "")     {
 141          // Sends the PASS command, returns # of msgs in mailbox,
 142          // returns false (undef) on Auth failure
 143  
 144          if(empty($pass)) {
 145              $this->ERROR = "POP3 pass: " . _("No password submitted");
 146              return false;
 147          } elseif(!isset($this->FP)) {
 148              $this->ERROR = "POP3 pass: " . _("connection not established");
 149              return false;
 150          } else {
 151              $reply = $this->send_cmd("PASS $pass");
 152              if(!$this->is_ok($reply)) {
 153                  $this->ERROR = "POP3 pass: " . _("Authentication failed") . " [$reply]";
 154                  $this->quit();
 155                  return false;
 156              } else {
 157                  //  Auth successful.
 158                  $count = $this->last("count");
 159                  $this->COUNT = $count;
 160                  return $count;
 161              }
 162          }
 163      }
 164  
 165      function apop ($login,$pass) {
 166          //  Attempts an APOP login. If this fails, it'll
 167          //  try a standard login. YOUR SERVER MUST SUPPORT
 168          //  THE USE OF THE APOP COMMAND!
 169          //  (apop is optional per rfc1939)
 170  
 171          if(!isset($this->FP)) {
 172              $this->ERROR = "POP3 apop: " . _("No connection to server");
 173              return false;
 174          } elseif(!$this->ALLOWAPOP) {
 175              $retVal = $this->login($login,$pass);
 176              return $retVal;
 177          } elseif(empty($login)) {
 178              $this->ERROR = "POP3 apop: " . _("No login ID submitted");
 179              return false;
 180          } elseif(empty($pass)) {
 181              $this->ERROR = "POP3 apop: " . _("No password submitted");
 182              return false;
 183          } else {
 184              $banner = $this->BANNER;
 185              if( (!$banner) or (empty($banner)) ) {
 186                  $this->ERROR = "POP3 apop: " . _("No server banner") . ' - ' . _("abort");
 187                  $retVal = $this->login($login,$pass);
 188                  return $retVal;
 189              } else {
 190                  $AuthString = $banner;
 191                  $AuthString .= $pass;
 192                  $APOPString = md5($AuthString);
 193                  $cmd = "APOP $login $APOPString";
 194                  $reply = $this->send_cmd($cmd);
 195                  if(!$this->is_ok($reply)) {
 196                      $this->ERROR = "POP3 apop: " . _("apop authentication failed") . ' - ' . _("abort");
 197                      $retVal = $this->login($login,$pass);
 198                      return $retVal;
 199                  } else {
 200                      //  Auth successful.
 201                      $count = $this->last("count");
 202                      $this->COUNT = $count;
 203                      return $count;
 204                  }
 205              }
 206          }
 207      }
 208  
 209      function login ($login = "", $pass = "") {
 210          // Sends both user and pass. Returns # of msgs in mailbox or
 211          // false on failure (or -1, if the error occurs while getting
 212          // the number of messages.)
 213  
 214          if( !isset($this->FP) ) {
 215              $this->ERROR = "POP3 login: " . _("No connection to server");
 216              return false;
 217          } else {
 218              $fp = $this->FP;
 219              if( !$this->user( $login ) ) {
 220                  //  Preserve the error generated by user()
 221                  return false;
 222              } else {
 223                  $count = $this->pass($pass);
 224                  if( (!$count) || ($count == -1) ) {
 225                      //  Preserve the error generated by last() and pass()
 226                      return false;
 227                  } else
 228                      return $count;
 229              }
 230          }
 231      }
 232  
 233      function top ($msgNum, $numLines = "0") {
 234          //  Gets the header and first $numLines of the msg body
 235          //  returns data in an array with each returned line being
 236          //  an array element. If $numLines is empty, returns
 237          //  only the header information, and none of the body.
 238  
 239          if(!isset($this->FP)) {
 240              $this->ERROR = "POP3 top: " . _("No connection to server");
 241              return false;
 242          }
 243          $this->update_timer();
 244  
 245          $fp = $this->FP;
 246          $buffer = $this->BUFFER;
 247          $cmd = "TOP $msgNum $numLines";
 248          fwrite($fp, "TOP $msgNum $numLines\r\n");
 249          $reply = fgets($fp, $buffer);
 250          $reply = $this->strip_clf($reply);
 251          if($this->DEBUG) {
 252              @error_log("POP3 SEND [$cmd] GOT [$reply]",0);
 253          }
 254          if(!$this->is_ok($reply))
 255          {
 256              $this->ERROR = "POP3 top: " . _("Error ") . "[$reply]";
 257              return false;
 258          }
 259  
 260          $count = 0;
 261          $MsgArray = array();
 262  
 263          $line = fgets($fp,$buffer);
 264          while ( !preg_match('/^\.\r\n/',$line))
 265          {
 266              $MsgArray[$count] = $line;
 267              $count++;
 268              $line = fgets($fp,$buffer);
 269              if(empty($line))    { break; }
 270          }
 271  
 272          return $MsgArray;
 273      }
 274  
 275      function pop_list ($msgNum = "") {
 276          //  If called with an argument, returns that msgs' size in octets
 277          //  No argument returns an associative array of undeleted
 278          //  msg numbers and their sizes in octets
 279  
 280          if(!isset($this->FP))
 281          {
 282              $this->ERROR = "POP3 pop_list: " . _("No connection to server");
 283              return false;
 284          }
 285          $fp = $this->FP;
 286          $Total = $this->COUNT;
 287          if( (!$Total) or ($Total == -1) )
 288          {
 289              return false;
 290          }
 291          if($Total == 0)
 292          {
 293              return array("0","0");
 294              // return -1;   // mailbox empty
 295          }
 296  
 297          $this->update_timer();
 298  
 299          if(!empty($msgNum))
 300          {
 301              $cmd = "LIST $msgNum";
 302              fwrite($fp,"$cmd\r\n");
 303              $reply = fgets($fp,$this->BUFFER);
 304              $reply = $this->strip_clf($reply);
 305              if($this->DEBUG) {
 306                  @error_log("POP3 SEND [$cmd] GOT [$reply]",0);
 307              }
 308              if(!$this->is_ok($reply))
 309              {
 310                  $this->ERROR = "POP3 pop_list: " . _("Error ") . "[$reply]";
 311                  return false;
 312              }
 313              list($junk,$num,$size) = preg_split('/\s+/',$reply);
 314              return $size;
 315          }
 316          $cmd = "LIST";
 317          $reply = $this->send_cmd($cmd);
 318          if(!$this->is_ok($reply))
 319          {
 320              $reply = $this->strip_clf($reply);
 321              $this->ERROR = "POP3 pop_list: " . _("Error ") .  "[$reply]";
 322              return false;
 323          }
 324          $MsgArray = array();
 325          $MsgArray[0] = $Total;
 326          for($msgC=1;$msgC <= $Total; $msgC++)
 327          {
 328              if($msgC > $Total) { break; }
 329              $line = fgets($fp,$this->BUFFER);
 330              $line = $this->strip_clf($line);
 331              if(strpos($line, '.') === 0)
 332              {
 333                  $this->ERROR = "POP3 pop_list: " . _("Premature end of list");
 334                  return false;
 335              }
 336              list($thisMsg,$msgSize) = preg_split('/\s+/',$line);
 337              settype($thisMsg,"integer");
 338              if($thisMsg != $msgC)
 339              {
 340                  $MsgArray[$msgC] = "deleted";
 341              }
 342              else
 343              {
 344                  $MsgArray[$msgC] = $msgSize;
 345              }
 346          }
 347          return $MsgArray;
 348      }
 349  
 350      function get ($msgNum) {
 351          //  Retrieve the specified msg number. Returns an array
 352          //  where each line of the msg is an array element.
 353  
 354          if(!isset($this->FP))
 355          {
 356              $this->ERROR = "POP3 get: " . _("No connection to server");
 357              return false;
 358          }
 359  
 360          $this->update_timer();
 361  
 362          $fp = $this->FP;
 363          $buffer = $this->BUFFER;
 364          $cmd = "RETR $msgNum";
 365          $reply = $this->send_cmd($cmd);
 366  
 367          if(!$this->is_ok($reply))
 368          {
 369              $this->ERROR = "POP3 get: " . _("Error ") . "[$reply]";
 370              return false;
 371          }
 372  
 373          $count = 0;
 374          $MsgArray = array();
 375  
 376          $line = fgets($fp,$buffer);
 377          while ( !preg_match('/^\.\r\n/',$line))
 378          {
 379              if ( $line[0] == '.' ) { $line = substr($line,1); }
 380              $MsgArray[$count] = $line;
 381              $count++;
 382              $line = fgets($fp,$buffer);
 383              if(empty($line))    { break; }
 384          }
 385          return $MsgArray;
 386      }
 387  
 388      function last ( $type = "count" ) {
 389          //  Returns the highest msg number in the mailbox.
 390          //  returns -1 on error, 0+ on success, if type != count
 391          //  results in a popstat() call (2 element array returned)
 392  
 393          $last = -1;
 394          if(!isset($this->FP))
 395          {
 396              $this->ERROR = "POP3 last: " . _("No connection to server");
 397              return $last;
 398          }
 399  
 400          $reply = $this->send_cmd("STAT");
 401          if(!$this->is_ok($reply))
 402          {
 403              $this->ERROR = "POP3 last: " . _("Error ") . "[$reply]";
 404              return $last;
 405          }
 406  
 407          $Vars = preg_split('/\s+/',$reply);
 408          $count = $Vars[1];
 409          $size = $Vars[2];
 410          settype($count,"integer");
 411          settype($size,"integer");
 412          if($type != "count")
 413          {
 414              return array($count,$size);
 415          }
 416          return $count;
 417      }
 418  
 419      function reset () {
 420          //  Resets the status of the remote server. This includes
 421          //  resetting the status of ALL msgs to not be deleted.
 422          //  This method automatically closes the connection to the server.
 423  
 424          if(!isset($this->FP))
 425          {
 426              $this->ERROR = "POP3 reset: " . _("No connection to server");
 427              return false;
 428          }
 429          $reply = $this->send_cmd("RSET");
 430          if(!$this->is_ok($reply))
 431          {
 432              //  The POP3 RSET command -never- gives a -ERR
 433              //  response - if it ever does, something truly
 434              //  wild is going on.
 435  
 436              $this->ERROR = "POP3 reset: " . _("Error ") . "[$reply]";
 437              @error_log("POP3 reset: ERROR [$reply]",0);
 438          }
 439          $this->quit();
 440          return true;
 441      }
 442  
 443      function send_cmd ( $cmd = "" )
 444      {
 445          //  Sends a user defined command string to the
 446          //  POP server and returns the results. Useful for
 447          //  non-compliant or custom POP servers.
 448          //  Do NOT includ the \r\n as part of your command
 449          //  string - it will be appended automatically.
 450  
 451          //  The return value is a standard fgets() call, which
 452          //  will read up to $this->BUFFER bytes of data, until it
 453          //  encounters a new line, or EOF, whichever happens first.
 454  
 455          //  This method works best if $cmd responds with only
 456          //  one line of data.
 457  
 458          if(!isset($this->FP))
 459          {
 460              $this->ERROR = "POP3 send_cmd: " . _("No connection to server");
 461              return false;
 462          }
 463  
 464          if(empty($cmd))
 465          {
 466              $this->ERROR = "POP3 send_cmd: " . _("Empty command string");
 467              return "";
 468          }
 469  
 470          $fp = $this->FP;
 471          $buffer = $this->BUFFER;
 472          $this->update_timer();
 473          fwrite($fp,"$cmd\r\n");
 474          $reply = fgets($fp,$buffer);
 475          $reply = $this->strip_clf($reply);
 476          if($this->DEBUG) { @error_log("POP3 SEND [$cmd] GOT [$reply]",0); }
 477          return $reply;
 478      }
 479  
 480      function quit() {
 481          //  Closes the connection to the POP3 server, deleting
 482          //  any msgs marked as deleted.
 483  
 484          if(!isset($this->FP))
 485          {
 486              $this->ERROR = "POP3 quit: " . _("connection does not exist");
 487              return false;
 488          }
 489          $fp = $this->FP;
 490          $cmd = "QUIT";
 491          fwrite($fp,"$cmd\r\n");
 492          $reply = fgets($fp,$this->BUFFER);
 493          $reply = $this->strip_clf($reply);
 494          if($this->DEBUG) { @error_log("POP3 SEND [$cmd] GOT [$reply]",0); }
 495          fclose($fp);
 496          unset($this->FP);
 497          return true;
 498      }
 499  
 500      function popstat () {
 501          //  Returns an array of 2 elements. The number of undeleted
 502          //  msgs in the mailbox, and the size of the mbox in octets.
 503  
 504          $PopArray = $this->last("array");
 505  
 506          if($PopArray == -1) { return false; }
 507  
 508          if( (!$PopArray) or (empty($PopArray)) )
 509          {
 510              return false;
 511          }
 512          return $PopArray;
 513      }
 514  
 515      function uidl ($msgNum = "")
 516      {
 517          //  Returns the UIDL of the msg specified. If called with
 518          //  no arguments, returns an associative array where each
 519          //  undeleted msg num is a key, and the msg's uidl is the element
 520          //  Array element 0 will contain the total number of msgs
 521  
 522          if(!isset($this->FP)) {
 523              $this->ERROR = "POP3 uidl: " . _("No connection to server");
 524              return false;
 525          }
 526  
 527          $fp = $this->FP;
 528          $buffer = $this->BUFFER;
 529  
 530          if(!empty($msgNum)) {
 531              $cmd = "UIDL $msgNum";
 532              $reply = $this->send_cmd($cmd);
 533              if(!$this->is_ok($reply))
 534              {
 535                  $this->ERROR = "POP3 uidl: " . _("Error ") . "[$reply]";
 536                  return false;
 537              }
 538              list ($ok,$num,$myUidl) = preg_split('/\s+/',$reply);
 539              return $myUidl;
 540          } else {
 541              $this->update_timer();
 542  
 543              $UIDLArray = array();
 544              $Total = $this->COUNT;
 545              $UIDLArray[0] = $Total;
 546  
 547              if ($Total < 1)
 548              {
 549                  return $UIDLArray;
 550              }
 551              $cmd = "UIDL";
 552              fwrite($fp, "UIDL\r\n");
 553              $reply = fgets($fp, $buffer);
 554              $reply = $this->strip_clf($reply);
 555              if($this->DEBUG) { @error_log("POP3 SEND [$cmd] GOT [$reply]",0); }
 556              if(!$this->is_ok($reply))
 557              {
 558                  $this->ERROR = "POP3 uidl: " . _("Error ") . "[$reply]";
 559                  return false;
 560              }
 561  
 562              $line = "";
 563              $count = 1;
 564              $line = fgets($fp,$buffer);
 565              while ( !preg_match('/^\.\r\n/',$line)) {
 566                  list ($msg,$msgUidl) = preg_split('/\s+/',$line);
 567                  $msgUidl = $this->strip_clf($msgUidl);
 568                  if($count == $msg) {
 569                      $UIDLArray[$msg] = $msgUidl;
 570                  }
 571                  else
 572                  {
 573                      $UIDLArray[$count] = 'deleted';
 574                  }
 575                  $count++;
 576                  $line = fgets($fp,$buffer);
 577              }
 578          }
 579          return $UIDLArray;
 580      }
 581  
 582      function delete ($msgNum = "") {
 583          //  Flags a specified msg as deleted. The msg will not
 584          //  be deleted until a quit() method is called.
 585  
 586          if(!isset($this->FP))
 587          {
 588              $this->ERROR = "POP3 delete: " . _("No connection to server");
 589              return false;
 590          }
 591          if(empty($msgNum))
 592          {
 593              $this->ERROR = "POP3 delete: " . _("No msg number submitted");
 594              return false;
 595          }
 596          $reply = $this->send_cmd("DELE $msgNum");
 597          if(!$this->is_ok($reply))
 598          {
 599              $this->ERROR = "POP3 delete: " . _("Command failed ") . "[$reply]";
 600              return false;
 601          }
 602          return true;
 603      }
 604  
 605      //  *********************************************************
 606  
 607      //  The following methods are internal to the class.
 608  
 609      function is_ok ($cmd = "") {
 610          //  Return true or false on +OK or -ERR
 611  
 612          if( empty($cmd) )
 613              return false;
 614          else
 615              return( stripos($cmd, '+OK') !== false );
 616      }
 617  
 618      function strip_clf ($text = "") {
 619          // Strips \r\n from server responses
 620  
 621          if(empty($text))
 622              return $text;
 623          else {
 624              $stripped = str_replace(array("\r","\n"),'',$text);
 625              return $stripped;
 626          }
 627      }
 628  
 629      function parse_banner ( $server_text ) {
 630          $outside = true;
 631          $banner = "";
 632          $length = strlen($server_text);
 633          for($count =0; $count < $length; $count++)
 634          {
 635              $digit = substr($server_text,$count,1);
 636              if(!empty($digit))             {
 637                  if( (!$outside) && ($digit != '<') && ($digit != '>') )
 638                  {
 639                      $banner .= $digit;
 640                  }
 641                  if ($digit == '<')
 642                  {
 643                      $outside = false;
 644                  }
 645                  if($digit == '>')
 646                  {
 647                      $outside = true;
 648                  }
 649              }
 650          }
 651          $banner = $this->strip_clf($banner);    // Just in case
 652          return "<$banner>";
 653      }
 654  
 655  }   // End class
 656  
 657  // For php4 compatibility
 658  if (!function_exists("stripos")) {
 659      function stripos($haystack, $needle){
 660          return strpos($haystack, stristr( $haystack, $needle ));
 661      }
 662  }


Generated: Tue Sep 17 01:00:03 2019 Cross-referenced by PHPXref 0.7.1