[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

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


Generated : Sat Dec 21 08:20:01 2024 Cross-referenced by PHPXref