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