[ Index ]

PHP Cross Reference of Wordpress 2.9.1

title

Body

[close]

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

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


Generated: Fri Jan 8 00:19:48 2010 Cross-referenced by PHPXref 0.7