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