[ Index ] |
PHP Cross Reference of phpBB 3.0 Beta 3 |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * 4 * @package phpBB3 5 * @version $Id: functions_transfer.php,v 1.12 2006/10/07 17:40:06 acydburn Exp $ 6 * @copyright (c) 2005 phpBB Group 7 * @license http://opensource.org/licenses/gpl-license.php GNU Public License 8 * 9 */ 10 11 /** 12 * Transfer class, wrapper for ftp/sftp/ssh 13 * @package phpBB3 14 */ 15 class transfer 16 { 17 var $connection; 18 var $host; 19 var $port; 20 var $username; 21 var $password; 22 var $timeout; 23 var $root_path; 24 var $tmp_path; 25 var $file_perms; 26 var $dir_perms; 27 28 /** 29 * Constructor - init some basic values 30 */ 31 function transfer() 32 { 33 global $phpbb_root_path; 34 35 $this->file_perms = 644; 36 $this->dir_perms = 777; 37 38 // We use the store directory as temporary path to circumvent open basedir restrictions 39 $this->tmp_path = $phpbb_root_path . 'store/'; 40 } 41 42 /** 43 * Write file to location 44 */ 45 function write_file($destination_file = '', $contents = '') 46 { 47 global $phpbb_root_path; 48 49 $destination_file = $this->root_path . str_replace($phpbb_root_path, '', $destination_file); 50 51 // need to create a temp file and then move that temp file. 52 // ftp functions can only move files around and can't create. 53 // This means that the users will need to have access to write 54 // temporary files or have write access on a folder within phpBB 55 // like the cache folder. If the user can't do either, then 56 // he/she needs to use the fsock ftp method 57 $temp_name = tempnam($this->tmp_path, 'transfer_'); 58 @unlink($temp_name); 59 60 $fp = @fopen($temp_name, 'w'); 61 62 if (!$fp) 63 { 64 trigger_error('Unable to create temporary file ' . $temp_name, E_USER_ERROR); 65 } 66 67 @fwrite($fp, $contents); 68 @fclose($fp); 69 70 $result = $this->overwrite_file($temp_name, $destination_file); 71 72 // remove temporary file now 73 @unlink($temp_name); 74 75 return $result; 76 } 77 78 /** 79 * Moving file into location. If the destination file already exists it gets overwritten 80 */ 81 function overwrite_file($source_file, $destination_file) 82 { 83 /** 84 * @todo generally think about overwriting files in another way, by creating a temporary file and then renaming it 85 * @todo check for the destination file existance too 86 */ 87 $this->_delete($destination_file); 88 $result = $this->_put($source_file, $destination_file); 89 $this->_chmod($destination_file, $this->file_perms); 90 91 return $result; 92 } 93 94 /** 95 * Create directory structure 96 */ 97 function make_dir($dir) 98 { 99 global $phpbb_root_path; 100 101 $dir = str_replace($phpbb_root_path, '', $dir); 102 $dir = explode('/', $dir); 103 $dirs = ''; 104 105 for ($i = 0, $total = sizeof($dir); $i < $total; $i++) 106 { 107 $result = true; 108 109 if (strpos($dir[$i], '.') === 0) 110 { 111 continue; 112 } 113 $cur_dir = $dir[$i] . '/'; 114 115 if (!file_exists($phpbb_root_path . $dirs . $cur_dir)) 116 { 117 // create the directory 118 $result = $this->_mkdir($dir[$i]); 119 $this->_chmod($dir[$i], $this->dir_perms); 120 } 121 122 $this->_chdir($this->root_path . $dirs . $dir[$i]); 123 $dirs .= $cur_dir; 124 } 125 126 $this->_chdir($this->root_path); 127 128 /** 129 * @todo stack result into array to make sure every path creation has been taken care of 130 */ 131 return $result; 132 } 133 134 /** 135 * Copy file from source location to destination location 136 */ 137 function copy_file($from_loc, $to_loc) 138 { 139 global $phpbb_root_path; 140 141 $from_loc = ((strpos($from_loc, $phpbb_root_path) !== 0) ? $phpbb_root_path : '') . $from_loc; 142 $to_loc = $this->root_path . str_replace($phpbb_root_path, '', $to_loc); 143 144 if (!file_exists($from_loc)) 145 { 146 return false; 147 } 148 149 $result = $this->overwrite_file($from_loc, $to_loc); 150 151 return $result; 152 } 153 154 /** 155 * Remove file 156 */ 157 function delete_file($file) 158 { 159 global $phpbb_root_path; 160 161 $file = $this->root_path . str_replace($phpbb_root_path, '', $file); 162 163 return $this->_delete($file); 164 } 165 166 /** 167 * Remove directory 168 * @todo remove child directories? 169 */ 170 function remove_dir($dir) 171 { 172 global $phpbb_root_path; 173 174 $dir = $this->root_path . str_replace($phpbb_root_path, '', $dir); 175 176 return $this->_rmdir($dir); 177 } 178 179 /** 180 * Rename a file or folder 181 */ 182 function rename($old_handle, $new_handle) 183 { 184 global $phpbb_root_path; 185 186 $old_handle = $this->root_path . str_replace($phpbb_root_path, '', $old_handle); 187 188 return $this->_rename($old_handle, $new_handle); 189 } 190 191 /** 192 * Check if a specified file exist... 193 */ 194 function file_exists($directory, $filename) 195 { 196 global $phpbb_root_path; 197 198 $directory = $this->root_path . str_replace($phpbb_root_path, '', $directory); 199 $result = $this->_ls($directory); 200 201 if ($result !== false && is_array($result)) 202 { 203 return (in_array($filename, $result)) ? true : false; 204 } 205 206 return false; 207 } 208 209 /** 210 * Open session 211 */ 212 function open_session() 213 { 214 return $this->_init(); 215 } 216 217 /** 218 * Close current session 219 */ 220 function close_session() 221 { 222 return $this->_close(); 223 } 224 225 /** 226 * Determine methods able to be used 227 */ 228 function methods() 229 { 230 $methods = array(); 231 $disabled_functions = explode(',', @ini_get('disable_functions')); 232 233 if (@extension_loaded('ftp')) 234 { 235 $methods[] = 'ftp'; 236 } 237 238 if (!in_array('fsockopen', $disabled_functions)) 239 { 240 $methods[] = 'ftp_fsock'; 241 } 242 243 return $methods; 244 } 245 } 246 247 /** 248 * FTP transfer class 249 * @package phpBB3 250 */ 251 class ftp extends transfer 252 { 253 /** 254 * Standard parameters for FTP session 255 */ 256 function ftp($host, $username, $password, $root_path, $port = 21, $timeout = 10) 257 { 258 $this->host = $host; 259 $this->port = $port; 260 $this->username = $username; 261 $this->password = $password; 262 $this->timeout = $timeout; 263 264 // Make sure $this->root_path is layed out the same way as the $user->page['root_script_path'] value (/ at the end) 265 $this->root_path = str_replace('\\', '/', $this->root_path); 266 $this->root_path = (($root_path[0] != '/' ) ? '/' : '') . $root_path . ((substr($root_path, -1, 1) == '/') ? '' : '/'); 267 268 // Init some needed values 269 transfer::transfer(); 270 271 return; 272 } 273 274 /** 275 * Requests data 276 */ 277 function data() 278 { 279 global $user; 280 281 return array( 282 'host' => 'localhost', 283 'username' => 'anonymous', 284 'password' => '', 285 'root_path' => $user->page['root_script_path'], 286 'port' => 21, 287 'timeout' => 10 288 ); 289 } 290 291 /** 292 * Init FTP Session 293 * @access private 294 */ 295 function _init() 296 { 297 // connect to the server 298 $this->connection = @ftp_connect($this->host, $this->port, $this->timeout); 299 300 if (!$this->connection) 301 { 302 return 'ERR_CONNECTING_SERVER'; 303 } 304 305 // attempt to turn pasv mode on 306 @ftp_pasv($this->connection, true); 307 308 // login to the server 309 if (!@ftp_login($this->connection, $this->username, $this->password)) 310 { 311 return 'ERR_UNABLE_TO_LOGIN'; 312 } 313 314 // change to the root directory 315 if (!$this->_chdir($this->root_path)) 316 { 317 return 'ERR_CHANGING_DIRECTORY'; 318 } 319 320 return true; 321 } 322 323 /** 324 * Create Directory (MKDIR) 325 * @access private 326 */ 327 function _mkdir($dir) 328 { 329 return @ftp_mkdir($this->connection, $dir); 330 } 331 332 /** 333 * Remove directory (RMDIR) 334 * @access private 335 */ 336 function _rmdir($dir) 337 { 338 return @ftp_rmdir($this->connection, $dir); 339 } 340 341 /** 342 * Rename file 343 * @access private 344 */ 345 function _rename($old_handle, $new_handle) 346 { 347 return @ftp_rename($this->connection, $old_handle, $new_handle); 348 } 349 350 /** 351 * Change current working directory (CHDIR) 352 * @access private 353 */ 354 function _chdir($dir = '') 355 { 356 if (substr($dir, -1, 1) == '/') 357 { 358 $dir = substr($dir, 0, -1); 359 } 360 361 return @ftp_chdir($this->connection, $dir); 362 } 363 364 /** 365 * change file permissions (CHMOD) 366 * @access private 367 */ 368 function _chmod($file, $perms) 369 { 370 if (function_exists('ftp_chmod')) 371 { 372 $err = @ftp_chmod($this->connection, $perms, $file); 373 } 374 else 375 { 376 $chmod_cmd = 'CHMOD 0' . $perms . ' ' . $file; 377 $err = $this->_site($chmod_cmd); 378 } 379 380 return $err; 381 } 382 383 /** 384 * Upload file to location (PUT) 385 * @access private 386 */ 387 function _put($from_file, $to_file) 388 { 389 // get the file extension 390 $file_extension = strtolower(substr(strrchr($to_file, '.'), 1)); 391 392 // We only use the BINARY file mode to cicumvent rewrite actions from ftp server (mostly linefeeds being replaced) 393 $mode = FTP_BINARY; 394 395 $to_dir = dirname($to_file); 396 $to_file = basename($to_file); 397 $this->_chdir($to_dir); 398 399 $result = @ftp_put($this->connection, $to_file, $from_file, $mode); 400 $this->_chdir($this->root_path); 401 402 return $result; 403 } 404 405 /** 406 * Delete file (DELETE) 407 * @access private 408 */ 409 function _delete($file) 410 { 411 return @ftp_delete($this->connection, $file); 412 } 413 414 /** 415 * Close ftp session (CLOSE) 416 * @access private 417 */ 418 function _close() 419 { 420 if (!$this->connection) 421 { 422 return false; 423 } 424 425 return @ftp_quit($this->connection); 426 } 427 428 /** 429 * Return current working directory (CWD) 430 * At the moment not used by parent class 431 * @access private 432 */ 433 function _cwd() 434 { 435 return @ftp_pwd($this->connection); 436 } 437 438 /** 439 * Return list of files in a given directory (LS) 440 * @access private 441 */ 442 function _ls($dir = './') 443 { 444 return @ftp_nlist($this->connection, $dir); 445 } 446 447 /** 448 * FTP SITE command (ftp-only function) 449 * @access private 450 */ 451 function _site($command) 452 { 453 return @ftp_site($this->connection, $command); 454 } 455 } 456 457 /** 458 * FTP fsock transfer class 459 * 460 * @author wGEric 461 * @package phpBB3 462 */ 463 class ftp_fsock extends transfer 464 { 465 var $data_connection; 466 467 /** 468 * Standard parameters for FTP session 469 */ 470 function ftp_fsock($host, $username, $password, $root_path, $port = 21, $timeout = 10) 471 { 472 $this->host = $host; 473 $this->port = $port; 474 $this->username = $username; 475 $this->password = $password; 476 $this->timeout = $timeout; 477 478 // Make sure $this->root_path is layed out the same way as the $user->page['root_script_path'] value (/ at the end) 479 $this->root_path = str_replace('\\', '/', $this->root_path); 480 $this->root_path = (($root_path[0] != '/' ) ? '/' : '') . $root_path . ((substr($root_path, -1, 1) == '/') ? '' : '/'); 481 482 // Init some needed values 483 transfer::transfer(); 484 485 return; 486 } 487 488 /** 489 * Requests data 490 */ 491 function data() 492 { 493 global $user; 494 495 return array( 496 'host' => 'localhost', 497 'username' => 'anonymous', 498 'password' => '', 499 'root_path' => $user->page['root_script_path'], 500 'port' => 21, 501 'timeout' => 10 502 ); 503 } 504 505 /** 506 * Init FTP Session 507 * @access private 508 */ 509 function _init() 510 { 511 $errno = 0; 512 $errstr = ''; 513 514 // connect to the server 515 $this->connection = @fsockopen($this->host, $this->port, $errno, $errstr, $this->timeout); 516 517 if (!$this->connection || !$this->_check_command()) 518 { 519 return 'ERR_CONNECTING_SERVER'; 520 } 521 522 @stream_set_timeout($this->connection, $this->timeout); 523 524 // login 525 if (!$this->_send_command('USER', $this->username)) 526 { 527 return 'ERR_UNABLE_TO_LOGIN'; 528 } 529 530 if (!$this->_send_command('PASS', $this->password)) 531 { 532 return 'ERR_UNABLE_TO_LOGIN'; 533 } 534 535 // change to the root directory 536 if (!$this->_chdir($this->root_path)) 537 { 538 return 'ERR_CHANGING_DIRECTORY'; 539 } 540 541 return true; 542 } 543 544 /** 545 * Create Directory (MKDIR) 546 * @access private 547 */ 548 function _mkdir($dir) 549 { 550 return $this->_send_command('MKD', $dir); 551 } 552 553 /** 554 * Remove directory (RMDIR) 555 * @access private 556 */ 557 function _rmdir($dir) 558 { 559 return $this->_send_command('RMD', $dir); 560 } 561 562 /** 563 * Rename File 564 * @access private 565 */ 566 function _rename($old_handle, $new_handle) 567 { 568 $this->_send_command('RNFR', $old_handle); 569 return $this->_send_command('RNTO', $new_handle); 570 } 571 572 /** 573 * Change current working directory (CHDIR) 574 * @access private 575 */ 576 function _chdir($dir = '') 577 { 578 if (substr($dir, -1, 1) == '/') 579 { 580 $dir = substr($dir, 0, -1); 581 } 582 583 return $this->_send_command('CWD', $dir); 584 } 585 586 /** 587 * change file permissions (CHMOD) 588 * @access private 589 */ 590 function _chmod($file, $perms) 591 { 592 return $this->_send_command('SITE CHMOD', $perms . ' ' . $file); 593 } 594 595 /** 596 * Upload file to location (PUT) 597 * @access private 598 */ 599 function _put($from_file, $to_file) 600 { 601 // We only use the BINARY file mode to cicumvent rewrite actions from ftp server (mostly linefeeds being replaced) 602 // 'I' == BINARY 603 // 'A' == ASCII 604 if (!$this->_send_command('TYPE', 'I')) 605 { 606 return false; 607 } 608 609 // open the connection to send file over 610 if (!$this->_open_data_connection()) 611 { 612 return false; 613 } 614 615 $this->_send_command('STOR', $to_file, false); 616 617 // send the file 618 $fp = @fopen($from_file, 'rb'); 619 while (!@feof($fp)) 620 { 621 @fwrite($this->data_connection, @fread($fp, 4096)); 622 } 623 @fclose($fp); 624 625 // close connection 626 $this->_close_data_connection(); 627 628 return $this->_check_command(); 629 } 630 631 /** 632 * Delete file (DELETE) 633 * @access private 634 */ 635 function _delete($file) 636 { 637 return $this->_send_command('DELE', $file); 638 } 639 640 /** 641 * Close ftp session (CLOSE) 642 * @access private 643 */ 644 function _close() 645 { 646 if (!$this->connection) 647 { 648 return false; 649 } 650 651 return $this->_send_command('QUIT'); 652 } 653 654 /** 655 * Return current working directory (CWD) 656 * At the moment not used by parent class 657 * @access private 658 */ 659 function _cwd() 660 { 661 $this->_send_command('PWD', '', false); 662 return preg_replace('#^[0-9]{3} "(.+)" .+\r\n#', '\\1', $this->_check_command(true)); 663 } 664 665 /** 666 * Return list of files in a given directory (LS) 667 * @access private 668 */ 669 function _ls($dir = './') 670 { 671 if (!$this->_open_data_connection()) 672 { 673 return false; 674 } 675 676 $this->_send_command('NLST', $dir); 677 678 $list = array(); 679 while (!@feof($this->data_connection)) 680 { 681 $list[] = preg_replace('#[\r\n]#', '', @fgets($this->data_connection, 512)); 682 } 683 $this->_close_data_connection(); 684 685 return $list; 686 } 687 688 /** 689 * Send a command to server (FTP fsock only function) 690 * @access private 691 */ 692 function _send_command($command, $args = '', $check = true) 693 { 694 if (!empty($args)) 695 { 696 $command = "$command $args"; 697 } 698 699 fwrite($this->connection, $command . "\r\n"); 700 701 if ($check === true && !$this->_check_command()) 702 { 703 return false; 704 } 705 706 return true; 707 } 708 709 /** 710 * Opens a connection to send data (FTP fosck only function) 711 * @access private 712 */ 713 function _open_data_connection() 714 { 715 $this->_send_command('PASV', '', false); 716 717 if (!$ip_port = $this->_check_command(true)) 718 { 719 return false; 720 } 721 722 // open the connection to start sending the file 723 if (!preg_match('#[0-9]{1,3},[0-9]{1,3},[0-9]{1,3},[0-9]{1,3},[0-9]+,[0-9]+#', $ip_port, $temp)) 724 { 725 // bad ip and port 726 return false; 727 } 728 729 $temp = explode(',', $temp[0]); 730 $server_ip = $temp[0] . '.' . $temp[1] . '.' . $temp[2] . '.' . $temp[3]; 731 $server_port = $temp[4] * 256 + $temp[5]; 732 $errno = 0; 733 $errstr = ''; 734 735 if (!$this->data_connection = @fsockopen($server_ip, $server_port, $errno, $errstr, $this->timeout)) 736 { 737 return false; 738 } 739 @stream_set_timeout($this->data_connection, $this->timeout); 740 741 return true; 742 } 743 744 /** 745 * Closes a connection used to send data 746 * @access private 747 */ 748 function _close_data_connection() 749 { 750 return @fclose($this->data_connection); 751 } 752 753 /** 754 * Check to make sure command was successful (FTP fsock only function) 755 * @access private 756 */ 757 function _check_command($return = false) 758 { 759 $response = ''; 760 761 do 762 { 763 $result = @fgets($this->connection, 512); 764 $response .= $result; 765 } 766 while (substr($response, 3, 1) != ' '); 767 768 if (!preg_match('#^[123]#', $response)) 769 { 770 return false; 771 } 772 773 return ($return) ? $response : true; 774 } 775 } 776 777 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Nov 22 00:35:05 2006 | Cross-referenced by PHPXref 0.6 |