wp/wp-admin/includes/class-wp-filesystem-ssh2.php
changeset 7 cf61fcea0001
parent 5 5e2f62d02dcd
child 9 177826044cd9
equal deleted inserted replaced
6:490d5cc509ed 7:cf61fcea0001
    33  * @package WordPress
    33  * @package WordPress
    34  * @subpackage Filesystem
    34  * @subpackage Filesystem
    35  */
    35  */
    36 class WP_Filesystem_SSH2 extends WP_Filesystem_Base {
    36 class WP_Filesystem_SSH2 extends WP_Filesystem_Base {
    37 
    37 
       
    38 	/**
       
    39 	 */
    38 	public $link = false;
    40 	public $link = false;
       
    41 
    39 	/**
    42 	/**
    40 	 * @var resource
    43 	 * @var resource
    41 	 */
    44 	 */
    42 	public $sftp_link;
    45 	public $sftp_link;
    43 	public $keys = false;
    46 	public $keys = false;
    44 
    47 
    45 	public function __construct($opt='') {
    48 	/**
       
    49 	 *
       
    50 	 * @param array $opt
       
    51 	 */
       
    52 	public function __construct( $opt = '' ) {
    46 		$this->method = 'ssh2';
    53 		$this->method = 'ssh2';
    47 		$this->errors = new WP_Error();
    54 		$this->errors = new WP_Error();
    48 
    55 
    49 		//Check if possible to use ssh2 functions.
    56 		//Check if possible to use ssh2 functions.
    50 		if ( ! extension_loaded('ssh2') ) {
    57 		if ( ! extension_loaded('ssh2') ) {
    51 			$this->errors->add('no_ssh2_ext', __('The ssh2 PHP extension is not available'));
    58 			$this->errors->add('no_ssh2_ext', __('The ssh2 PHP extension is not available'));
    52 			return;
    59 			return;
    53 		}
    60 		}
    54 		if ( !function_exists('stream_get_contents') ) {
    61 		if ( !function_exists('stream_get_contents') ) {
    55 			$this->errors->add('ssh2_php_requirement', __('The ssh2 PHP extension is available, however, we require the PHP5 function <code>stream_get_contents()</code>'));
    62 			$this->errors->add(
       
    63 				'ssh2_php_requirement',
       
    64 				sprintf(
       
    65 					/* translators: %s: stream_get_contents() */
       
    66 					__( 'The ssh2 PHP extension is available, however, we require the PHP5 function %s' ),
       
    67 					'<code>stream_get_contents()</code>'
       
    68 				)
       
    69 			);
    56 			return;
    70 			return;
    57 		}
    71 		}
    58 
    72 
    59 		// Set defaults:
    73 		// Set defaults:
    60 		if ( empty($opt['port']) )
    74 		if ( empty($opt['port']) )
    87 			if ( !$this->keys )
   101 			if ( !$this->keys )
    88 				$this->errors->add('empty_password', __('SSH2 password is required'));
   102 				$this->errors->add('empty_password', __('SSH2 password is required'));
    89 		} else {
   103 		} else {
    90 			$this->options['password'] = $opt['password'];
   104 			$this->options['password'] = $opt['password'];
    91 		}
   105 		}
    92 
   106 	}
    93 	}
   107 
    94 
   108 	/**
       
   109 	 *
       
   110 	 * @return bool
       
   111 	 */
    95 	public function connect() {
   112 	public function connect() {
    96 		if ( ! $this->keys ) {
   113 		if ( ! $this->keys ) {
    97 			$this->link = @ssh2_connect($this->options['hostname'], $this->options['port']);
   114 			$this->link = @ssh2_connect($this->options['hostname'], $this->options['port']);
    98 		} else {
   115 		} else {
    99 			$this->link = @ssh2_connect($this->options['hostname'], $this->options['port'], $this->options['hostkey']);
   116 			$this->link = @ssh2_connect($this->options['hostname'], $this->options['port'], $this->options['hostkey']);
   100 		}
   117 		}
   101 
   118 
   102 		if ( ! $this->link ) {
   119 		if ( ! $this->link ) {
   103 			$this->errors->add('connect', sprintf(__('Failed to connect to SSH2 Server %1$s:%2$s'), $this->options['hostname'], $this->options['port']));
   120 			$this->errors->add( 'connect',
       
   121 				/* translators: %s: hostname:port */
       
   122 				sprintf( __( 'Failed to connect to SSH2 Server %s' ),
       
   123 					$this->options['hostname'] . ':' . $this->options['port']
       
   124 				)
       
   125 			);
   104 			return false;
   126 			return false;
   105 		}
   127 		}
   106 
   128 
   107 		if ( !$this->keys ) {
   129 		if ( !$this->keys ) {
   108 			if ( ! @ssh2_auth_password($this->link, $this->options['username'], $this->options['password']) ) {
   130 			if ( ! @ssh2_auth_password($this->link, $this->options['username'], $this->options['password']) ) {
   109 				$this->errors->add('auth', sprintf(__('Username/Password incorrect for %s'), $this->options['username']));
   131 				$this->errors->add( 'auth',
       
   132 					/* translators: %s: username */
       
   133 					sprintf( __( 'Username/Password incorrect for %s' ),
       
   134 						$this->options['username']
       
   135 					)
       
   136 				);
   110 				return false;
   137 				return false;
   111 			}
   138 			}
   112 		} else {
   139 		} else {
   113 			if ( ! @ssh2_auth_pubkey_file($this->link, $this->options['username'], $this->options['public_key'], $this->options['private_key'], $this->options['password'] ) ) {
   140 			if ( ! @ssh2_auth_pubkey_file($this->link, $this->options['username'], $this->options['public_key'], $this->options['private_key'], $this->options['password'] ) ) {
   114 				$this->errors->add('auth', sprintf(__('Public and Private keys incorrect for %s'), $this->options['username']));
   141 				$this->errors->add( 'auth',
       
   142 					/* translators: %s: username */
       
   143 					sprintf( __( 'Public and Private keys incorrect for %s' ),
       
   144 						$this->options['username']
       
   145 					)
       
   146 				);
   115 				return false;
   147 				return false;
   116 			}
   148 			}
   117 		}
   149 		}
   118 
   150 
   119 		$this->sftp_link = ssh2_sftp($this->link);
   151 		$this->sftp_link = ssh2_sftp( $this->link );
       
   152 		if ( ! $this->sftp_link ) {
       
   153 			$this->errors->add( 'connect',
       
   154 				/* translators: %s: hostname:port */
       
   155 				sprintf( __( 'Failed to initialize a SFTP subsystem session with the SSH2 Server %s' ),
       
   156 					$this->options['hostname'] . ':' . $this->options['port']
       
   157 				)
       
   158 			);
       
   159 			return false;
       
   160 		}
   120 
   161 
   121 		return true;
   162 		return true;
   122 	}
   163 	}
   123 
   164 
   124 	/**
   165 	/**
       
   166 	 * Gets the ssh2.sftp PHP stream wrapper path to open for the given file.
       
   167 	 *
       
   168 	 * This method also works around a PHP bug where the root directory (/) cannot
       
   169 	 * be opened by PHP functions, causing a false failure. In order to work around
       
   170 	 * this, the path is converted to /./ which is semantically the same as /
       
   171 	 * See https://bugs.php.net/bug.php?id=64169 for more details.
       
   172 	 *
       
   173 	 *
       
   174 	 * @since 4.4.0
       
   175 	 *
       
   176 	 * @param string $path The File/Directory path on the remote server to return
       
   177 	 * @return string The ssh2.sftp:// wrapped path to use.
       
   178 	 */
       
   179 	public function sftp_path( $path ) {
       
   180 		if ( '/' === $path ) {
       
   181 			$path = '/./';
       
   182 		}
       
   183 		return 'ssh2.sftp://' . $this->sftp_link . '/' . ltrim( $path, '/' );
       
   184 	}
       
   185 
       
   186 	/**
       
   187 	 *
   125 	 * @param string $command
   188 	 * @param string $command
   126 	 * @param bool $returnbool
   189 	 * @param bool $returnbool
   127 	 * @return bool|string
   190 	 * @return bool|string True on success, false on failure. String if the command was executed, `$returnbool`
   128 	 */
   191 	 *                     is false (default), and data from the resulting stream was retrieved.
   129 	public function run_command( $command, $returnbool = false) {
   192 	 */
   130 
   193 	public function run_command( $command, $returnbool = false ) {
   131 		if ( ! $this->link )
   194 		if ( ! $this->link )
   132 			return false;
   195 			return false;
   133 
   196 
   134 		if ( ! ($stream = ssh2_exec($this->link, $command)) ) {
   197 		if ( ! ($stream = ssh2_exec($this->link, $command)) ) {
   135 			$this->errors->add('command', sprintf(__('Unable to perform command: %s'), $command));
   198 			$this->errors->add( 'command',
       
   199 				/* translators: %s: command */
       
   200 				sprintf( __( 'Unable to perform command: %s'),
       
   201 					$command
       
   202 				)
       
   203 			);
   136 		} else {
   204 		} else {
   137 			stream_set_blocking( $stream, true );
   205 			stream_set_blocking( $stream, true );
   138 			stream_set_timeout( $stream, FS_TIMEOUT );
   206 			stream_set_timeout( $stream, FS_TIMEOUT );
   139 			$data = stream_get_contents( $stream );
   207 			$data = stream_get_contents( $stream );
   140 			fclose( $stream );
   208 			fclose( $stream );
   146 		}
   214 		}
   147 		return false;
   215 		return false;
   148 	}
   216 	}
   149 
   217 
   150 	/**
   218 	/**
       
   219 	 *
   151 	 * @param string $file
   220 	 * @param string $file
   152 	 * @return string|false
   221 	 * @return string|false
   153 	 */
   222 	 */
   154 	public function get_contents( $file ) {
   223 	public function get_contents( $file ) {
   155 		$file = ltrim($file, '/');
   224 		return file_get_contents( $this->sftp_path( $file ) );
   156 		return file_get_contents('ssh2.sftp://' . $this->sftp_link . '/' . $file);
   225 	}
   157 	}
   226 
   158 
   227 	/**
   159 	/**
   228 	 *
   160 	 * @param string $file
   229 	 * @param string $file
   161 	 * @return array
   230 	 * @return array
   162 	 */
   231 	 */
   163 	public function get_contents_array($file) {
   232 	public function get_contents_array($file) {
   164 		$file = ltrim($file, '/');
   233 		return file( $this->sftp_path( $file ) );
   165 		return file('ssh2.sftp://' . $this->sftp_link . '/' . $file);
   234 	}
   166 	}
   235 
   167 
   236 	/**
   168 	/**
   237 	 *
   169 	 * @param string $file
   238 	 * @param string   $file
   170 	 * @param string $contents
   239 	 * @param string   $contents
   171 	 * @param bool|int $mode
   240 	 * @param bool|int $mode
   172 	 * @return bool
   241 	 * @return bool
   173 	 */
   242 	 */
   174 	public function put_contents($file, $contents, $mode = false ) {
   243 	public function put_contents($file, $contents, $mode = false ) {
   175 		$ret = file_put_contents( 'ssh2.sftp://' . $this->sftp_link . '/' . ltrim( $file, '/' ), $contents );
   244 		$ret = file_put_contents( $this->sftp_path( $file ), $contents );
   176 
   245 
   177 		if ( $ret !== strlen( $contents ) )
   246 		if ( $ret !== strlen( $contents ) )
   178 			return false;
   247 			return false;
   179 
   248 
   180 		$this->chmod($file, $mode);
   249 		$this->chmod($file, $mode);
   181 
   250 
   182 		return true;
   251 		return true;
   183 	}
   252 	}
   184 
   253 
       
   254 	/**
       
   255 	 *
       
   256 	 * @return bool
       
   257 	 */
   185 	public function cwd() {
   258 	public function cwd() {
   186 		$cwd = $this->run_command('pwd');
   259 		$cwd = ssh2_sftp_realpath( $this->sftp_link, '.' );
   187 		if ( $cwd ) {
   260 		if ( $cwd ) {
   188 			$cwd = trailingslashit( trim( $cwd ) );
   261 			$cwd = trailingslashit( trim( $cwd ) );
   189 		}
   262 		}
   190 		return $cwd;
   263 		return $cwd;
   191 	}
   264 	}
   192 
   265 
   193 	/**
   266 	/**
       
   267 	 *
   194 	 * @param string $dir
   268 	 * @param string $dir
   195 	 * @return bool|string
   269 	 * @return bool|string
   196 	 */
   270 	 */
   197 	public function chdir($dir) {
   271 	public function chdir($dir) {
   198 		return $this->run_command('cd ' . $dir, true);
   272 		return $this->run_command('cd ' . $dir, true);
   199 	}
   273 	}
   200 
   274 
   201 	/**
   275 	/**
       
   276 	 *
   202 	 * @param string $file
   277 	 * @param string $file
   203 	 * @param string $group
   278 	 * @param string $group
   204 	 * @param bool $recursive
   279 	 * @param bool   $recursive
       
   280 	 *
       
   281 	 * @return bool
   205 	 */
   282 	 */
   206 	public function chgrp($file, $group, $recursive = false ) {
   283 	public function chgrp($file, $group, $recursive = false ) {
   207 		if ( ! $this->exists($file) )
   284 		if ( ! $this->exists($file) )
   208 			return false;
   285 			return false;
   209 		if ( ! $recursive || ! $this->is_dir($file) )
   286 		if ( ! $recursive || ! $this->is_dir($file) )
   210 			return $this->run_command(sprintf('chgrp %s %s', escapeshellarg($group), escapeshellarg($file)), true);
   287 			return $this->run_command(sprintf('chgrp %s %s', escapeshellarg($group), escapeshellarg($file)), true);
   211 		return $this->run_command(sprintf('chgrp -R %s %s', escapeshellarg($group), escapeshellarg($file)), true);
   288 		return $this->run_command(sprintf('chgrp -R %s %s', escapeshellarg($group), escapeshellarg($file)), true);
   212 	}
   289 	}
   213 
   290 
   214 	/**
   291 	/**
   215 	 * @param string $file
   292 	 *
   216 	 * @param int $mode
   293 	 * @param string $file
   217 	 * @param bool $recursive
   294 	 * @param int    $mode
       
   295 	 * @param bool   $recursive
   218 	 * @return bool|string
   296 	 * @return bool|string
   219 	 */
   297 	 */
   220 	public function chmod($file, $mode = false, $recursive = false) {
   298 	public function chmod($file, $mode = false, $recursive = false) {
   221 		if ( ! $this->exists($file) )
   299 		if ( ! $this->exists($file) )
   222 			return false;
   300 			return false;
   236 	}
   314 	}
   237 
   315 
   238 	/**
   316 	/**
   239 	 * Change the ownership of a file / folder.
   317 	 * Change the ownership of a file / folder.
   240 	 *
   318 	 *
   241 	 * @since Unknown
   319 	 *
   242 	 *
   320 	 * @param string     $file      Path to the file.
   243 	 * @param string     $file    Path to the file.
   321 	 * @param string|int $owner     A user name or number.
   244 	 * @param string|int $owner   A user name or number.
   322 	 * @param bool       $recursive Optional. If set True changes file owner recursivly. Default False.
   245 	 * @param bool       $recursive Optional. If set True changes file owner recursivly. Defaults to False.
   323 	 * @return bool True on success or false on failure.
   246 	 * @return bool|string Returns true on success or false on failure.
       
   247 	 */
   324 	 */
   248 	public function chown( $file, $owner, $recursive = false ) {
   325 	public function chown( $file, $owner, $recursive = false ) {
   249 		if ( ! $this->exists($file) )
   326 		if ( ! $this->exists($file) )
   250 			return false;
   327 			return false;
   251 		if ( ! $recursive || ! $this->is_dir($file) )
   328 		if ( ! $recursive || ! $this->is_dir($file) )
   252 			return $this->run_command(sprintf('chown %s %s', escapeshellarg($owner), escapeshellarg($file)), true);
   329 			return $this->run_command(sprintf('chown %s %s', escapeshellarg($owner), escapeshellarg($file)), true);
   253 		return $this->run_command(sprintf('chown -R %s %s', escapeshellarg($owner), escapeshellarg($file)), true);
   330 		return $this->run_command(sprintf('chown -R %s %s', escapeshellarg($owner), escapeshellarg($file)), true);
   254 	}
   331 	}
   255 
   332 
   256 	/**
   333 	/**
       
   334 	 *
   257 	 * @param string $file
   335 	 * @param string $file
   258 	 * @return string|false
   336 	 * @return string|false
   259 	 */
   337 	 */
   260 	public function owner($file) {
   338 	public function owner($file) {
   261 		$owneruid = @fileowner('ssh2.sftp://' . $this->sftp_link . '/' . ltrim($file, '/'));
   339 		$owneruid = @fileowner( $this->sftp_path( $file ) );
   262 		if ( ! $owneruid )
   340 		if ( ! $owneruid )
   263 			return false;
   341 			return false;
   264 		if ( ! function_exists('posix_getpwuid') )
   342 		if ( ! function_exists('posix_getpwuid') )
   265 			return $owneruid;
   343 			return $owneruid;
   266 		$ownerarray = posix_getpwuid($owneruid);
   344 		$ownerarray = posix_getpwuid($owneruid);
   267 		return $ownerarray['name'];
   345 		return $ownerarray['name'];
   268 	}
   346 	}
   269 	/**
   347 
       
   348 	/**
       
   349 	 *
   270 	 * @param string $file
   350 	 * @param string $file
   271 	 * @return string
   351 	 * @return string
   272 	 */
   352 	 */
   273 	public function getchmod($file) {
   353 	public function getchmod($file) {
   274 		return substr( decoct( @fileperms( 'ssh2.sftp://' . $this->sftp_link . '/' . ltrim( $file, '/' ) ) ), -3 );
   354 		return substr( decoct( @fileperms( $this->sftp_path( $file ) ) ), -3 );
   275 	}
   355 	}
   276 
   356 
   277 	/**
   357 	/**
       
   358 	 *
   278 	 * @param string $file
   359 	 * @param string $file
   279 	 * @return string|false
   360 	 * @return string|false
   280 	 */
   361 	 */
   281 	public function group($file) {
   362 	public function group($file) {
   282 		$gid = @filegroup('ssh2.sftp://' . $this->sftp_link . '/' . ltrim($file, '/'));
   363 		$gid = @filegroup( $this->sftp_path( $file ) );
   283 		if ( ! $gid )
   364 		if ( ! $gid )
   284 			return false;
   365 			return false;
   285 		if ( ! function_exists('posix_getgrgid') )
   366 		if ( ! function_exists('posix_getgrgid') )
   286 			return $gid;
   367 			return $gid;
   287 		$grouparray = posix_getgrgid($gid);
   368 		$grouparray = posix_getgrgid($gid);
   288 		return $grouparray['name'];
   369 		return $grouparray['name'];
   289 	}
   370 	}
   290 
   371 
   291 	/**
   372 	/**
       
   373 	 *
       
   374 	 * @param string   $source
       
   375 	 * @param string   $destination
       
   376 	 * @param bool     $overwrite
       
   377 	 * @param int|bool $mode
       
   378 	 * @return bool
       
   379 	 */
       
   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 	 *
   292 	 * @param string $source
   391 	 * @param string $source
   293 	 * @param string $destination
   392 	 * @param string $destination
   294 	 * @param bool $overwrite
   393 	 * @param bool   $overwrite
   295 	 * @param int|bool $mode
       
   296 	 * @return bool
       
   297 	 */
       
   298 	public function copy($source, $destination, $overwrite = false, $mode = false) {
       
   299 		if ( ! $overwrite && $this->exists($destination) )
       
   300 			return false;
       
   301 		$content = $this->get_contents($source);
       
   302 		if ( false === $content)
       
   303 			return false;
       
   304 		return $this->put_contents($destination, $content, $mode);
       
   305 	}
       
   306 
       
   307 	/**
       
   308 	 * @param string $source
       
   309 	 * @param string $destination
       
   310 	 * @param bool $overwrite
       
   311 	 * @return bool
   394 	 * @return bool
   312 	 */
   395 	 */
   313 	public function move($source, $destination, $overwrite = false) {
   396 	public function move($source, $destination, $overwrite = false) {
   314 		return @ssh2_sftp_rename( $this->sftp_link, $source, $destination );
   397 		return @ssh2_sftp_rename( $this->sftp_link, $source, $destination );
   315 	}
   398 	}
   316 
   399 
   317 	/**
   400 	/**
   318 	 * @param string $file
   401 	 *
   319 	 * @param bool $recursive
   402 	 * @param string      $file
       
   403 	 * @param bool        $recursive
   320 	 * @param string|bool $type
   404 	 * @param string|bool $type
   321 	 * @return bool
   405 	 * @return bool
   322 	 */
   406 	 */
   323 	public function delete($file, $recursive = false, $type = false) {
   407 	public function delete($file, $recursive = false, $type = false) {
   324 		if ( 'f' == $type || $this->is_file($file) )
   408 		if ( 'f' == $type || $this->is_file($file) )
   333 		}
   417 		}
   334 		return ssh2_sftp_rmdir($this->sftp_link, $file);
   418 		return ssh2_sftp_rmdir($this->sftp_link, $file);
   335 	}
   419 	}
   336 
   420 
   337 	/**
   421 	/**
       
   422 	 *
   338 	 * @param string $file
   423 	 * @param string $file
   339 	 * @return bool
   424 	 * @return bool
   340 	 */
   425 	 */
   341 	public function exists($file) {
   426 	public function exists($file) {
   342 		$file = ltrim($file, '/');
   427 		return file_exists( $this->sftp_path( $file ) );
   343 		return file_exists('ssh2.sftp://' . $this->sftp_link . '/' . $file);
   428 	}
   344 	}
   429 
   345 	/**
   430 	/**
       
   431 	 *
   346 	 * @param string $file
   432 	 * @param string $file
   347 	 * @return bool
   433 	 * @return bool
   348 	 */
   434 	 */
   349 	public function is_file($file) {
   435 	public function is_file($file) {
   350 		$file = ltrim($file, '/');
   436 		return is_file( $this->sftp_path( $file ) );
   351 		return is_file('ssh2.sftp://' . $this->sftp_link . '/' . $file);
   437 	}
   352 	}
   438 
   353 	/**
   439 	/**
       
   440 	 *
   354 	 * @param string $path
   441 	 * @param string $path
   355 	 * @return bool
   442 	 * @return bool
   356 	 */
   443 	 */
   357 	public function is_dir($path) {
   444 	public function is_dir($path) {
   358 		$path = ltrim($path, '/');
   445 		return is_dir( $this->sftp_path( $path ) );
   359 		return is_dir('ssh2.sftp://' . $this->sftp_link . '/' . $path);
   446 	}
   360 	}
   447 
   361 	/**
   448 	/**
       
   449 	 *
   362 	 * @param string $file
   450 	 * @param string $file
   363 	 * @return bool
   451 	 * @return bool
   364 	 */
   452 	 */
   365 	public function is_readable($file) {
   453 	public function is_readable($file) {
   366 		$file = ltrim($file, '/');
   454 		return is_readable( $this->sftp_path( $file ) );
   367 		return is_readable('ssh2.sftp://' . $this->sftp_link . '/' . $file);
   455 	}
   368 	}
   456 
   369 	/**
   457 	/**
       
   458 	 *
   370 	 * @param string $file
   459 	 * @param string $file
   371 	 * @return bool
   460 	 * @return bool
   372 	 */
   461 	 */
   373 	public function is_writable($file) {
   462 	public function is_writable($file) {
   374 		$file = ltrim($file, '/');
   463 		// PHP will base it's writable checks on system_user === file_owner, not ssh_user === file_owner
   375 		return is_writable('ssh2.sftp://' . $this->sftp_link . '/' . $file);
   464 		return true;
   376 	}
   465 	}
   377 	/**
   466 
       
   467 	/**
       
   468 	 *
   378 	 * @param string $file
   469 	 * @param string $file
   379 	 * @return int
   470 	 * @return int
   380 	 */
   471 	 */
   381 	public function atime($file) {
   472 	public function atime($file) {
   382 		$file = ltrim($file, '/');
   473 		return fileatime( $this->sftp_path( $file ) );
   383 		return fileatime('ssh2.sftp://' . $this->sftp_link . '/' . $file);
   474 	}
   384 	}
   475 
   385 
   476 	/**
   386 	/**
   477 	 *
   387 	 * @param string $file
   478 	 * @param string $file
   388 	 * @return int
   479 	 * @return int
   389 	 */
   480 	 */
   390 	public function mtime($file) {
   481 	public function mtime($file) {
   391 		$file = ltrim($file, '/');
   482 		return filemtime( $this->sftp_path( $file ) );
   392 		return filemtime('ssh2.sftp://' . $this->sftp_link . '/' . $file);
   483 	}
   393 	}
   484 
   394 
   485 	/**
   395 	/**
   486 	 *
   396 	 * @param string $file
   487 	 * @param string $file
   397 	 * @return int
   488 	 * @return int
   398 	 */
   489 	 */
   399 	public function size($file) {
   490 	public function size($file) {
   400 		$file = ltrim($file, '/');
   491 		return filesize( $this->sftp_path( $file ) );
   401 		return filesize('ssh2.sftp://' . $this->sftp_link . '/' . $file);
   492 	}
   402 	}
   493 
   403 
   494 	/**
   404 	/**
   495 	 *
   405 	 * @param string $file
   496 	 * @param string $file
   406 	 * @param int $time
   497 	 * @param int    $time
   407 	 * @param int $atime
   498 	 * @param int    $atime
   408 	 */
   499 	 */
   409 	public function touch($file, $time = 0, $atime = 0) {
   500 	public function touch($file, $time = 0, $atime = 0) {
   410 		//Not implemented.
   501 		//Not implemented.
   411 	}
   502 	}
   412 
   503 
   413 	/**
   504 	/**
       
   505 	 *
   414 	 * @param string $path
   506 	 * @param string $path
   415 	 * @param mixed $chmod
   507 	 * @param mixed  $chmod
   416 	 * @param mixed $chown
   508 	 * @param mixed  $chown
   417 	 * @param mixed $chgrp
   509 	 * @param mixed  $chgrp
   418 	 * @return bool
   510 	 * @return bool
   419 	 */
   511 	 */
   420 	public function mkdir($path, $chmod = false, $chown = false, $chgrp = false) {
   512 	public function mkdir($path, $chmod = false, $chown = false, $chgrp = false) {
   421 		$path = untrailingslashit($path);
   513 		$path = untrailingslashit($path);
   422 		if ( empty($path) )
   514 		if ( empty($path) )
   432 			$this->chgrp($path, $chgrp);
   524 			$this->chgrp($path, $chgrp);
   433 		return true;
   525 		return true;
   434 	}
   526 	}
   435 
   527 
   436 	/**
   528 	/**
       
   529 	 *
   437 	 * @param string $path
   530 	 * @param string $path
   438 	 * @param bool $recursive
   531 	 * @param bool   $recursive
   439 	 * @return bool
   532 	 * @return bool
   440 	 */
   533 	 */
   441 	public function rmdir($path, $recursive = false) {
   534 	public function rmdir($path, $recursive = false) {
   442 		return $this->delete($path, $recursive);
   535 		return $this->delete($path, $recursive);
   443 	}
   536 	}
   444 
   537 
   445 	/**
   538 	/**
       
   539 	 *
   446 	 * @param string $path
   540 	 * @param string $path
   447 	 * @param bool $include_hidden
   541 	 * @param bool   $include_hidden
   448 	 * @param bool $recursive
   542 	 * @param bool   $recursive
   449 	 * @return bool|array
   543 	 * @return bool|array
   450 	 */
   544 	 */
   451 	public function dirlist($path, $include_hidden = true, $recursive = false) {
   545 	public function dirlist($path, $include_hidden = true, $recursive = false) {
   452 		if ( $this->is_file($path) ) {
   546 		if ( $this->is_file($path) ) {
   453 			$limit_file = basename($path);
   547 			$limit_file = basename($path);
   458 
   552 
   459 		if ( ! $this->is_dir($path) )
   553 		if ( ! $this->is_dir($path) )
   460 			return false;
   554 			return false;
   461 
   555 
   462 		$ret = array();
   556 		$ret = array();
   463 		$dir = @dir('ssh2.sftp://' . $this->sftp_link .'/' . ltrim($path, '/') );
   557 		$dir = @dir( $this->sftp_path( $path ) );
   464 
   558 
   465 		if ( ! $dir )
   559 		if ( ! $dir )
   466 			return false;
   560 			return false;
   467 
   561 
   468 		while (false !== ($entry = $dir->read()) ) {
   562 		while (false !== ($entry = $dir->read()) ) {