[ 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 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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated : Thu Nov 21 08:20:01 2024 | Cross-referenced by PHPXref |