- Timestamp:
- 11/30/2017 11:09:33 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-admin/includes/class-wp-filesystem-ssh2.php
r42228 r42343 47 47 48 48 /** 49 *50 49 * @param array $opt 51 50 */ … … 55 54 56 55 //Check if possible to use ssh2 functions. 57 if ( ! extension_loaded( 'ssh2') ) {58 $this->errors->add( 'no_ssh2_ext', __('The ssh2 PHP extension is not available'));56 if ( ! extension_loaded( 'ssh2' ) ) { 57 $this->errors->add( 'no_ssh2_ext', __( 'The ssh2 PHP extension is not available' ) ); 59 58 return; 60 59 } 61 if ( ! function_exists('stream_get_contents') ) {60 if ( ! function_exists( 'stream_get_contents' ) ) { 62 61 $this->errors->add( 63 62 'ssh2_php_requirement', … … 72 71 73 72 // Set defaults: 74 if ( empty( $opt['port']) )73 if ( empty( $opt['port'] ) ) { 75 74 $this->options['port'] = 22; 76 else75 } else { 77 76 $this->options['port'] = $opt['port']; 78 79 if ( empty($opt['hostname']) ) 80 $this->errors->add('empty_hostname', __('SSH2 hostname is required')); 81 else 77 } 78 79 if ( empty( $opt['hostname'] ) ) { 80 $this->errors->add( 'empty_hostname', __( 'SSH2 hostname is required' ) ); 81 } else { 82 82 $this->options['hostname'] = $opt['hostname']; 83 } 83 84 84 85 // Check if the options provided are OK. 85 if ( ! empty ($opt['public_key']) && !empty ($opt['private_key']) ) {86 $this->options['public_key'] = $opt['public_key'];86 if ( ! empty( $opt['public_key'] ) && ! empty( $opt['private_key'] ) ) { 87 $this->options['public_key'] = $opt['public_key']; 87 88 $this->options['private_key'] = $opt['private_key']; 88 89 89 $this->options['hostkey'] = array( 'hostkey' => 'ssh-rsa');90 $this->options['hostkey'] = array( 'hostkey' => 'ssh-rsa' ); 90 91 91 92 $this->keys = true; 92 } elseif ( empty ($opt['username']) ) {93 $this->errors->add( 'empty_username', __('SSH2 username is required'));94 } 95 96 if ( ! empty($opt['username']) )93 } elseif ( empty( $opt['username'] ) ) { 94 $this->errors->add( 'empty_username', __( 'SSH2 username is required' ) ); 95 } 96 97 if ( ! empty( $opt['username'] ) ) { 97 98 $this->options['username'] = $opt['username']; 98 99 if ( empty ($opt['password']) ) { 99 } 100 101 if ( empty( $opt['password'] ) ) { 100 102 // Password can be blank if we are using keys. 101 if ( !$this->keys ) 102 $this->errors->add('empty_password', __('SSH2 password is required')); 103 if ( ! $this->keys ) { 104 $this->errors->add( 'empty_password', __( 'SSH2 password is required' ) ); 105 } 103 106 } else { 104 107 $this->options['password'] = $opt['password']; … … 107 110 108 111 /** 109 *110 112 * @return bool 111 113 */ 112 114 public function connect() { 113 115 if ( ! $this->keys ) { 114 $this->link = @ssh2_connect( $this->options['hostname'], $this->options['port']);116 $this->link = @ssh2_connect( $this->options['hostname'], $this->options['port'] ); 115 117 } else { 116 $this->link = @ssh2_connect( $this->options['hostname'], $this->options['port'], $this->options['hostkey']);118 $this->link = @ssh2_connect( $this->options['hostname'], $this->options['port'], $this->options['hostkey'] ); 117 119 } 118 120 119 121 if ( ! $this->link ) { 120 $this->errors->add( 'connect', 122 $this->errors->add( 123 'connect', 121 124 /* translators: %s: hostname:port */ 122 sprintf( __( 'Failed to connect to SSH2 Server %s' ), 125 sprintf( 126 __( 'Failed to connect to SSH2 Server %s' ), 123 127 $this->options['hostname'] . ':' . $this->options['port'] 124 128 ) … … 127 131 } 128 132 129 if ( !$this->keys ) { 130 if ( ! @ssh2_auth_password($this->link, $this->options['username'], $this->options['password']) ) { 131 $this->errors->add( 'auth', 133 if ( ! $this->keys ) { 134 if ( ! @ssh2_auth_password( $this->link, $this->options['username'], $this->options['password'] ) ) { 135 $this->errors->add( 136 'auth', 132 137 /* translators: %s: username */ 133 sprintf( __( 'Username/Password incorrect for %s' ), 138 sprintf( 139 __( 'Username/Password incorrect for %s' ), 134 140 $this->options['username'] 135 141 ) … … 138 144 } 139 145 } else { 140 if ( ! @ssh2_auth_pubkey_file($this->link, $this->options['username'], $this->options['public_key'], $this->options['private_key'], $this->options['password'] ) ) { 141 $this->errors->add( 'auth', 146 if ( ! @ssh2_auth_pubkey_file( $this->link, $this->options['username'], $this->options['public_key'], $this->options['private_key'], $this->options['password'] ) ) { 147 $this->errors->add( 148 'auth', 142 149 /* translators: %s: username */ 143 sprintf( __( 'Public and Private keys incorrect for %s' ), 150 sprintf( 151 __( 'Public and Private keys incorrect for %s' ), 144 152 $this->options['username'] 145 153 ) … … 151 159 $this->sftp_link = ssh2_sftp( $this->link ); 152 160 if ( ! $this->sftp_link ) { 153 $this->errors->add( 'connect', 161 $this->errors->add( 162 'connect', 154 163 /* translators: %s: hostname:port */ 155 sprintf( __( 'Failed to initialize a SFTP subsystem session with the SSH2 Server %s' ), 164 sprintf( 165 __( 'Failed to initialize a SFTP subsystem session with the SSH2 Server %s' ), 156 166 $this->options['hostname'] . ':' . $this->options['port'] 157 167 ) … … 171 181 * See https://bugs.php.net/bug.php?id=64169 for more details. 172 182 * 173 *174 183 * @since 4.4.0 175 184 * … … 185 194 186 195 /** 187 *188 196 * @param string $command 189 197 * @param bool $returnbool … … 192 200 */ 193 201 public function run_command( $command, $returnbool = false ) { 194 if ( ! $this->link ) 195 return false; 196 197 if ( ! ($stream = ssh2_exec($this->link, $command)) ) { 198 $this->errors->add( 'command', 202 if ( ! $this->link ) { 203 return false; 204 } 205 206 if ( ! ( $stream = ssh2_exec( $this->link, $command ) ) ) { 207 $this->errors->add( 208 'command', 199 209 /* translators: %s: command */ 200 sprintf( __( 'Unable to perform command: %s'), 210 sprintf( 211 __( 'Unable to perform command: %s' ), 201 212 $command 202 213 ) … … 208 219 fclose( $stream ); 209 220 210 if ( $returnbool ) 211 return ( $data === false ) ? false : '' != trim( $data);212 else221 if ( $returnbool ) { 222 return ( $data === false ) ? false : '' != trim( $data ); 223 } else { 213 224 return $data; 225 } 214 226 } 215 227 return false; … … 217 229 218 230 /** 219 *220 231 * @param string $file 221 232 * @return string|false … … 226 237 227 238 /** 228 *229 239 * @param string $file 230 240 * @return array 231 241 */ 232 public function get_contents_array( $file) {242 public function get_contents_array( $file ) { 233 243 return file( $this->sftp_path( $file ) ); 234 244 } 235 245 236 246 /** 237 *238 247 * @param string $file 239 248 * @param string $contents … … 241 250 * @return bool 242 251 */ 243 public function put_contents( $file, $contents, $mode = false ) {252 public function put_contents( $file, $contents, $mode = false ) { 244 253 $ret = file_put_contents( $this->sftp_path( $file ), $contents ); 245 254 246 if ( $ret !== strlen( $contents ) ) 247 return false; 248 249 $this->chmod($file, $mode); 255 if ( $ret !== strlen( $contents ) ) { 256 return false; 257 } 258 259 $this->chmod( $file, $mode ); 250 260 251 261 return true; … … 253 263 254 264 /** 255 *256 265 * @return bool 257 266 */ … … 265 274 266 275 /** 267 *268 276 * @param string $dir 269 277 * @return bool|string 270 278 */ 271 public function chdir($dir) { 272 return $this->run_command('cd ' . $dir, true); 273 } 274 275 /** 276 * 279 public function chdir( $dir ) { 280 return $this->run_command( 'cd ' . $dir, true ); 281 } 282 283 /** 277 284 * @param string $file 278 285 * @param string $group … … 281 288 * @return bool 282 289 */ 283 public function chgrp($file, $group, $recursive = false ) { 284 if ( ! $this->exists($file) ) 285 return false; 286 if ( ! $recursive || ! $this->is_dir($file) ) 287 return $this->run_command(sprintf('chgrp %s %s', escapeshellarg($group), escapeshellarg($file)), true); 288 return $this->run_command(sprintf('chgrp -R %s %s', escapeshellarg($group), escapeshellarg($file)), true); 289 } 290 291 /** 292 * 290 public function chgrp( $file, $group, $recursive = false ) { 291 if ( ! $this->exists( $file ) ) { 292 return false; 293 } 294 if ( ! $recursive || ! $this->is_dir( $file ) ) { 295 return $this->run_command( sprintf( 'chgrp %s %s', escapeshellarg( $group ), escapeshellarg( $file ) ), true ); 296 } 297 return $this->run_command( sprintf( 'chgrp -R %s %s', escapeshellarg( $group ), escapeshellarg( $file ) ), true ); 298 } 299 300 /** 293 301 * @param string $file 294 302 * @param int $mode … … 296 304 * @return bool|string 297 305 */ 298 public function chmod($file, $mode = false, $recursive = false) { 299 if ( ! $this->exists($file) ) 300 return false; 306 public function chmod( $file, $mode = false, $recursive = false ) { 307 if ( ! $this->exists( $file ) ) { 308 return false; 309 } 301 310 302 311 if ( ! $mode ) { 303 if ( $this->is_file( $file) )312 if ( $this->is_file( $file ) ) { 304 313 $mode = FS_CHMOD_FILE; 305 elseif ( $this->is_dir($file) )314 } elseif ( $this->is_dir( $file ) ) { 306 315 $mode = FS_CHMOD_DIR; 307 else316 } else { 308 317 return false; 309 } 310 311 if ( ! $recursive || ! $this->is_dir($file) ) 312 return $this->run_command(sprintf('chmod %o %s', $mode, escapeshellarg($file)), true); 313 return $this->run_command(sprintf('chmod -R %o %s', $mode, escapeshellarg($file)), true); 318 } 319 } 320 321 if ( ! $recursive || ! $this->is_dir( $file ) ) { 322 return $this->run_command( sprintf( 'chmod %o %s', $mode, escapeshellarg( $file ) ), true ); 323 } 324 return $this->run_command( sprintf( 'chmod -R %o %s', $mode, escapeshellarg( $file ) ), true ); 314 325 } 315 326 316 327 /** 317 328 * Change the ownership of a file / folder. 318 *319 329 * 320 330 * @param string $file Path to the file. … … 324 334 */ 325 335 public function chown( $file, $owner, $recursive = false ) { 326 if ( ! $this->exists($file) ) 327 return false; 328 if ( ! $recursive || ! $this->is_dir($file) ) 329 return $this->run_command(sprintf('chown %s %s', escapeshellarg($owner), escapeshellarg($file)), true); 330 return $this->run_command(sprintf('chown -R %s %s', escapeshellarg($owner), escapeshellarg($file)), true); 331 } 332 333 /** 334 * 336 if ( ! $this->exists( $file ) ) { 337 return false; 338 } 339 if ( ! $recursive || ! $this->is_dir( $file ) ) { 340 return $this->run_command( sprintf( 'chown %s %s', escapeshellarg( $owner ), escapeshellarg( $file ) ), true ); 341 } 342 return $this->run_command( sprintf( 'chown -R %s %s', escapeshellarg( $owner ), escapeshellarg( $file ) ), true ); 343 } 344 345 /** 335 346 * @param string $file 336 347 * @return string|false 337 348 */ 338 public function owner( $file) {349 public function owner( $file ) { 339 350 $owneruid = @fileowner( $this->sftp_path( $file ) ); 340 if ( ! $owneruid ) 341 return false; 342 if ( ! function_exists('posix_getpwuid') ) 351 if ( ! $owneruid ) { 352 return false; 353 } 354 if ( ! function_exists( 'posix_getpwuid' ) ) { 343 355 return $owneruid; 344 $ownerarray = posix_getpwuid($owneruid); 356 } 357 $ownerarray = posix_getpwuid( $owneruid ); 345 358 return $ownerarray['name']; 346 359 } 347 360 348 361 /** 349 *350 362 * @param string $file 351 363 * @return string 352 364 */ 353 public function getchmod( $file) {365 public function getchmod( $file ) { 354 366 return substr( decoct( @fileperms( $this->sftp_path( $file ) ) ), -3 ); 355 367 } 356 368 357 369 /** 358 *359 370 * @param string $file 360 371 * @return string|false 361 372 */ 362 public function group( $file) {373 public function group( $file ) { 363 374 $gid = @filegroup( $this->sftp_path( $file ) ); 364 if ( ! $gid ) 365 return false; 366 if ( ! function_exists('posix_getgrgid') ) 375 if ( ! $gid ) { 376 return false; 377 } 378 if ( ! function_exists( 'posix_getgrgid' ) ) { 367 379 return $gid; 368 $grouparray = posix_getgrgid($gid); 380 } 381 $grouparray = posix_getgrgid( $gid ); 369 382 return $grouparray['name']; 370 383 } 371 384 372 385 /** 373 *374 386 * @param string $source 375 387 * @param string $destination … … 378 390 * @return bool 379 391 */ 380 public function copy($source, $destination, $overwrite = false, $mode = false) { 381 if ( ! $overwrite && $this->exists($destination) ) 382 return false; 383 $content = $this->get_contents($source); 384 if ( false === $content) 385 return false; 386 return $this->put_contents($destination, $content, $mode); 387 } 388 389 /** 390 * 392 public function copy( $source, $destination, $overwrite = false, $mode = false ) { 393 if ( ! $overwrite && $this->exists( $destination ) ) { 394 return false; 395 } 396 $content = $this->get_contents( $source ); 397 if ( false === $content ) { 398 return false; 399 } 400 return $this->put_contents( $destination, $content, $mode ); 401 } 402 403 /** 391 404 * @param string $source 392 405 * @param string $destination … … 394 407 * @return bool 395 408 */ 396 public function move( $source, $destination, $overwrite = false) {409 public function move( $source, $destination, $overwrite = false ) { 397 410 return @ssh2_sftp_rename( $this->sftp_link, $source, $destination ); 398 411 } 399 412 400 413 /** 401 *402 414 * @param string $file 403 415 * @param bool $recursive … … 405 417 * @return bool 406 418 */ 407 public function delete($file, $recursive = false, $type = false) { 408 if ( 'f' == $type || $this->is_file($file) ) 409 return ssh2_sftp_unlink($this->sftp_link, $file); 410 if ( ! $recursive ) 411 return ssh2_sftp_rmdir($this->sftp_link, $file); 412 $filelist = $this->dirlist($file); 413 if ( is_array($filelist) ) { 414 foreach ( $filelist as $filename => $fileinfo) { 415 $this->delete($file . '/' . $filename, $recursive, $fileinfo['type']); 416 } 417 } 418 return ssh2_sftp_rmdir($this->sftp_link, $file); 419 } 420 421 /** 422 * 423 * @param string $file 424 * @return bool 425 */ 426 public function exists($file) { 419 public function delete( $file, $recursive = false, $type = false ) { 420 if ( 'f' == $type || $this->is_file( $file ) ) { 421 return ssh2_sftp_unlink( $this->sftp_link, $file ); 422 } 423 if ( ! $recursive ) { 424 return ssh2_sftp_rmdir( $this->sftp_link, $file ); 425 } 426 $filelist = $this->dirlist( $file ); 427 if ( is_array( $filelist ) ) { 428 foreach ( $filelist as $filename => $fileinfo ) { 429 $this->delete( $file . '/' . $filename, $recursive, $fileinfo['type'] ); 430 } 431 } 432 return ssh2_sftp_rmdir( $this->sftp_link, $file ); 433 } 434 435 /** 436 * @param string $file 437 * @return bool 438 */ 439 public function exists( $file ) { 427 440 return file_exists( $this->sftp_path( $file ) ); 428 441 } 429 442 430 443 /** 431 * 432 * @param string $file 433 * @return bool 434 */ 435 public function is_file($file) { 444 * @param string $file 445 * @return bool 446 */ 447 public function is_file( $file ) { 436 448 return is_file( $this->sftp_path( $file ) ); 437 449 } 438 450 439 451 /** 440 *441 452 * @param string $path 442 453 * @return bool 443 454 */ 444 public function is_dir( $path) {455 public function is_dir( $path ) { 445 456 return is_dir( $this->sftp_path( $path ) ); 446 457 } 447 458 448 459 /** 449 * 450 * @param string $file 451 * @return bool 452 */ 453 public function is_readable($file) { 460 * @param string $file 461 * @return bool 462 */ 463 public function is_readable( $file ) { 454 464 return is_readable( $this->sftp_path( $file ) ); 455 465 } 456 466 457 467 /** 458 * 459 * @param string $file 460 * @return bool 461 */ 462 public function is_writable($file) { 468 * @param string $file 469 * @return bool 470 */ 471 public function is_writable( $file ) { 463 472 // PHP will base it's writable checks on system_user === file_owner, not ssh_user === file_owner 464 473 return true; … … 466 475 467 476 /** 468 *469 477 * @param string $file 470 478 * @return int 471 479 */ 472 public function atime( $file) {480 public function atime( $file ) { 473 481 return fileatime( $this->sftp_path( $file ) ); 474 482 } 475 483 476 484 /** 477 *478 485 * @param string $file 479 486 * @return int 480 487 */ 481 public function mtime( $file) {488 public function mtime( $file ) { 482 489 return filemtime( $this->sftp_path( $file ) ); 483 490 } 484 491 485 492 /** 486 *487 493 * @param string $file 488 494 * @return int 489 495 */ 490 public function size( $file) {496 public function size( $file ) { 491 497 return filesize( $this->sftp_path( $file ) ); 492 498 } 493 499 494 500 /** 495 *496 501 * @param string $file 497 502 * @param int $time 498 503 * @param int $atime 499 504 */ 500 public function touch( $file, $time = 0, $atime = 0) {505 public function touch( $file, $time = 0, $atime = 0 ) { 501 506 //Not implemented. 502 507 } 503 508 504 509 /** 505 *506 510 * @param string $path 507 511 * @param mixed $chmod … … 510 514 * @return bool 511 515 */ 512 public function mkdir($path, $chmod = false, $chown = false, $chgrp = false) { 513 $path = untrailingslashit($path); 514 if ( empty($path) ) 515 return false; 516 517 if ( ! $chmod ) 516 public function mkdir( $path, $chmod = false, $chown = false, $chgrp = false ) { 517 $path = untrailingslashit( $path ); 518 if ( empty( $path ) ) { 519 return false; 520 } 521 522 if ( ! $chmod ) { 518 523 $chmod = FS_CHMOD_DIR; 519 if ( ! ssh2_sftp_mkdir($this->sftp_link, $path, $chmod, true) ) 520 return false; 521 if ( $chown ) 522 $this->chown($path, $chown); 523 if ( $chgrp ) 524 $this->chgrp($path, $chgrp); 524 } 525 if ( ! ssh2_sftp_mkdir( $this->sftp_link, $path, $chmod, true ) ) { 526 return false; 527 } 528 if ( $chown ) { 529 $this->chown( $path, $chown ); 530 } 531 if ( $chgrp ) { 532 $this->chgrp( $path, $chgrp ); 533 } 525 534 return true; 526 535 } 527 536 528 537 /** 529 *530 538 * @param string $path 531 539 * @param bool $recursive 532 540 * @return bool 533 541 */ 534 public function rmdir($path, $recursive = false) { 535 return $this->delete($path, $recursive); 536 } 537 538 /** 539 * 542 public function rmdir( $path, $recursive = false ) { 543 return $this->delete( $path, $recursive ); 544 } 545 546 /** 540 547 * @param string $path 541 548 * @param bool $include_hidden … … 543 550 * @return bool|array 544 551 */ 545 public function dirlist( $path, $include_hidden = true, $recursive = false) {546 if ( $this->is_file( $path) ) {547 $limit_file = basename( $path);548 $path = dirname($path);552 public function dirlist( $path, $include_hidden = true, $recursive = false ) { 553 if ( $this->is_file( $path ) ) { 554 $limit_file = basename( $path ); 555 $path = dirname( $path ); 549 556 } else { 550 557 $limit_file = false; 551 558 } 552 559 553 if ( ! $this->is_dir($path) ) 554 return false; 560 if ( ! $this->is_dir( $path ) ) { 561 return false; 562 } 555 563 556 564 $ret = array(); 557 565 $dir = @dir( $this->sftp_path( $path ) ); 558 566 559 if ( ! $dir ) 560 return false; 561 562 while (false !== ($entry = $dir->read()) ) { 563 $struc = array(); 567 if ( ! $dir ) { 568 return false; 569 } 570 571 while ( false !== ( $entry = $dir->read() ) ) { 572 $struc = array(); 564 573 $struc['name'] = $entry; 565 574 566 if ( '.' == $struc['name'] || '..' == $struc['name'] ) 575 if ( '.' == $struc['name'] || '..' == $struc['name'] ) { 567 576 continue; //Do not care about these folders. 568 569 if ( ! $include_hidden && '.' == $struc['name'][0] ) 577 } 578 579 if ( ! $include_hidden && '.' == $struc['name'][0] ) { 570 580 continue; 571 572 if ( $limit_file && $struc['name'] != $limit_file ) 581 } 582 583 if ( $limit_file && $struc['name'] != $limit_file ) { 573 584 continue; 574 575 $struc['perms'] = $this->gethchmod($path.'/'.$entry); 576 $struc['permsn'] = $this->getnumchmodfromh($struc['perms']); 577 $struc['number'] = false; 578 $struc['owner'] = $this->owner($path.'/'.$entry); 579 $struc['group'] = $this->group($path.'/'.$entry); 580 $struc['size'] = $this->size($path.'/'.$entry); 581 $struc['lastmodunix']= $this->mtime($path.'/'.$entry); 582 $struc['lastmod'] = date('M j',$struc['lastmodunix']); 583 $struc['time'] = date('h:i:s',$struc['lastmodunix']); 584 $struc['type'] = $this->is_dir($path.'/'.$entry) ? 'd' : 'f'; 585 } 586 587 $struc['perms'] = $this->gethchmod( $path . '/' . $entry ); 588 $struc['permsn'] = $this->getnumchmodfromh( $struc['perms'] ); 589 $struc['number'] = false; 590 $struc['owner'] = $this->owner( $path . '/' . $entry ); 591 $struc['group'] = $this->group( $path . '/' . $entry ); 592 $struc['size'] = $this->size( $path . '/' . $entry ); 593 $struc['lastmodunix'] = $this->mtime( $path . '/' . $entry ); 594 $struc['lastmod'] = date( 'M j', $struc['lastmodunix'] ); 595 $struc['time'] = date( 'h:i:s', $struc['lastmodunix'] ); 596 $struc['type'] = $this->is_dir( $path . '/' . $entry ) ? 'd' : 'f'; 585 597 586 598 if ( 'd' == $struc['type'] ) { 587 if ( $recursive ) 588 $struc['files'] = $this->dirlist( $path . '/' . $struc['name'], $include_hidden, $recursive);589 else599 if ( $recursive ) { 600 $struc['files'] = $this->dirlist( $path . '/' . $struc['name'], $include_hidden, $recursive ); 601 } else { 590 602 $struc['files'] = array(); 603 } 591 604 } 592 605 … … 594 607 } 595 608 $dir->close(); 596 unset( $dir);609 unset( $dir ); 597 610 return $ret; 598 611 }
Note: See TracChangeset
for help on using the changeset viewer.