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