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