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 var $link = false; |
38 public $link = false; |
39 var $sftp_link = false; |
39 /** |
40 var $keys = false; |
40 * @var resource |
41 var $errors = array(); |
41 */ |
42 var $options = array(); |
42 public $sftp_link; |
43 |
43 public $keys = false; |
44 function __construct($opt='') { |
44 |
|
45 public function __construct($opt='') { |
45 $this->method = 'ssh2'; |
46 $this->method = 'ssh2'; |
46 $this->errors = new WP_Error(); |
47 $this->errors = new WP_Error(); |
47 |
48 |
48 //Check if possible to use ssh2 functions. |
49 //Check if possible to use ssh2 functions. |
49 if ( ! extension_loaded('ssh2') ) { |
50 if ( ! extension_loaded('ssh2') ) { |
50 $this->errors->add('no_ssh2_ext', __('The ssh2 PHP extension is not available')); |
51 $this->errors->add('no_ssh2_ext', __('The ssh2 PHP extension is not available')); |
51 return false; |
52 return; |
52 } |
53 } |
53 if ( !function_exists('stream_get_contents') ) { |
54 if ( !function_exists('stream_get_contents') ) { |
54 $this->errors->add('ssh2_php_requirement', __('The ssh2 PHP extension is available, however, we require the PHP5 function <code>stream_get_contents()</code>')); |
55 $this->errors->add('ssh2_php_requirement', __('The ssh2 PHP extension is available, however, we require the PHP5 function <code>stream_get_contents()</code>')); |
55 return false; |
56 return; |
56 } |
57 } |
57 |
58 |
58 // Set defaults: |
59 // Set defaults: |
59 if ( empty($opt['port']) ) |
60 if ( empty($opt['port']) ) |
60 $this->options['port'] = 22; |
61 $this->options['port'] = 22; |
83 |
81 |
84 if ( !empty($opt['username']) ) |
82 if ( !empty($opt['username']) ) |
85 $this->options['username'] = $opt['username']; |
83 $this->options['username'] = $opt['username']; |
86 |
84 |
87 if ( empty ($opt['password']) ) { |
85 if ( empty ($opt['password']) ) { |
88 if ( !$this->keys ) //password can be blank if we are using keys |
86 // Password can be blank if we are using keys. |
|
87 if ( !$this->keys ) |
89 $this->errors->add('empty_password', __('SSH2 password is required')); |
88 $this->errors->add('empty_password', __('SSH2 password is required')); |
90 } else { |
89 } else { |
91 $this->options['password'] = $opt['password']; |
90 $this->options['password'] = $opt['password']; |
92 } |
91 } |
93 |
92 |
94 } |
93 } |
95 |
94 |
96 function connect() { |
95 public function connect() { |
97 if ( ! $this->keys ) { |
96 if ( ! $this->keys ) { |
98 $this->link = @ssh2_connect($this->options['hostname'], $this->options['port']); |
97 $this->link = @ssh2_connect($this->options['hostname'], $this->options['port']); |
99 } else { |
98 } else { |
100 $this->link = @ssh2_connect($this->options['hostname'], $this->options['port'], $this->options['hostkey']); |
99 $this->link = @ssh2_connect($this->options['hostname'], $this->options['port'], $this->options['hostkey']); |
101 } |
100 } |
141 return $data; |
145 return $data; |
142 } |
146 } |
143 return false; |
147 return false; |
144 } |
148 } |
145 |
149 |
146 function get_contents( $file ) { |
150 /** |
|
151 * @param string $file |
|
152 * @return string|false |
|
153 */ |
|
154 public function get_contents( $file ) { |
147 $file = ltrim($file, '/'); |
155 $file = ltrim($file, '/'); |
148 return file_get_contents('ssh2.sftp://' . $this->sftp_link . '/' . $file); |
156 return file_get_contents('ssh2.sftp://' . $this->sftp_link . '/' . $file); |
149 } |
157 } |
150 |
158 |
151 function get_contents_array($file) { |
159 /** |
|
160 * @param string $file |
|
161 * @return array |
|
162 */ |
|
163 public function get_contents_array($file) { |
152 $file = ltrim($file, '/'); |
164 $file = ltrim($file, '/'); |
153 return file('ssh2.sftp://' . $this->sftp_link . '/' . $file); |
165 return file('ssh2.sftp://' . $this->sftp_link . '/' . $file); |
154 } |
166 } |
155 |
167 |
156 function put_contents($file, $contents, $mode = false ) { |
168 /** |
|
169 * @param string $file |
|
170 * @param string $contents |
|
171 * @param bool|int $mode |
|
172 * @return bool |
|
173 */ |
|
174 public function put_contents($file, $contents, $mode = false ) { |
157 $ret = file_put_contents( 'ssh2.sftp://' . $this->sftp_link . '/' . ltrim( $file, '/' ), $contents ); |
175 $ret = file_put_contents( 'ssh2.sftp://' . $this->sftp_link . '/' . ltrim( $file, '/' ), $contents ); |
158 |
176 |
159 if ( $ret !== strlen( $contents ) ) |
177 if ( $ret !== strlen( $contents ) ) |
160 return false; |
178 return false; |
161 |
179 |
162 $this->chmod($file, $mode); |
180 $this->chmod($file, $mode); |
163 |
181 |
164 return true; |
182 return true; |
165 } |
183 } |
166 |
184 |
167 function cwd() { |
185 public function cwd() { |
168 $cwd = $this->run_command('pwd'); |
186 $cwd = $this->run_command('pwd'); |
169 if ( $cwd ) |
187 if ( $cwd ) { |
170 $cwd = trailingslashit($cwd); |
188 $cwd = trailingslashit( trim( $cwd ) ); |
|
189 } |
171 return $cwd; |
190 return $cwd; |
172 } |
191 } |
173 |
192 |
174 function chdir($dir) { |
193 /** |
|
194 * @param string $dir |
|
195 * @return bool|string |
|
196 */ |
|
197 public function chdir($dir) { |
175 return $this->run_command('cd ' . $dir, true); |
198 return $this->run_command('cd ' . $dir, true); |
176 } |
199 } |
177 |
200 |
178 function chgrp($file, $group, $recursive = false ) { |
201 /** |
|
202 * @param string $file |
|
203 * @param string $group |
|
204 * @param bool $recursive |
|
205 */ |
|
206 public function chgrp($file, $group, $recursive = false ) { |
179 if ( ! $this->exists($file) ) |
207 if ( ! $this->exists($file) ) |
180 return false; |
208 return false; |
181 if ( ! $recursive || ! $this->is_dir($file) ) |
209 if ( ! $recursive || ! $this->is_dir($file) ) |
182 return $this->run_command(sprintf('chgrp %s %s', escapeshellarg($group), escapeshellarg($file)), true); |
210 return $this->run_command(sprintf('chgrp %s %s', escapeshellarg($group), escapeshellarg($file)), true); |
183 return $this->run_command(sprintf('chgrp -R %s %s', escapeshellarg($group), escapeshellarg($file)), true); |
211 return $this->run_command(sprintf('chgrp -R %s %s', escapeshellarg($group), escapeshellarg($file)), true); |
184 } |
212 } |
185 |
213 |
186 function chmod($file, $mode = false, $recursive = false) { |
214 /** |
|
215 * @param string $file |
|
216 * @param int $mode |
|
217 * @param bool $recursive |
|
218 * @return bool|string |
|
219 */ |
|
220 public function chmod($file, $mode = false, $recursive = false) { |
187 if ( ! $this->exists($file) ) |
221 if ( ! $this->exists($file) ) |
188 return false; |
222 return false; |
189 |
223 |
190 if ( ! $mode ) { |
224 if ( ! $mode ) { |
191 if ( $this->is_file($file) ) |
225 if ( $this->is_file($file) ) |
204 /** |
238 /** |
205 * Change the ownership of a file / folder. |
239 * Change the ownership of a file / folder. |
206 * |
240 * |
207 * @since Unknown |
241 * @since Unknown |
208 * |
242 * |
209 * @param string $file Path to the file. |
243 * @param string $file Path to the file. |
210 * @param mixed $owner A user name or number. |
244 * @param string|int $owner A user name or number. |
211 * @param bool $recursive Optional. If set True changes file owner recursivly. Defaults to False. |
245 * @param bool $recursive Optional. If set True changes file owner recursivly. Defaults to False. |
212 * @return bool Returns true on success or false on failure. |
246 * @return bool|string Returns true on success or false on failure. |
213 */ |
247 */ |
214 function chown( $file, $owner, $recursive = false ) { |
248 public function chown( $file, $owner, $recursive = false ) { |
215 if ( ! $this->exists($file) ) |
249 if ( ! $this->exists($file) ) |
216 return false; |
250 return false; |
217 if ( ! $recursive || ! $this->is_dir($file) ) |
251 if ( ! $recursive || ! $this->is_dir($file) ) |
218 return $this->run_command(sprintf('chown %s %s', escapeshellarg($owner), escapeshellarg($file)), true); |
252 return $this->run_command(sprintf('chown %s %s', escapeshellarg($owner), escapeshellarg($file)), true); |
219 return $this->run_command(sprintf('chown -R %s %s', escapeshellarg($owner), escapeshellarg($file)), true); |
253 return $this->run_command(sprintf('chown -R %s %s', escapeshellarg($owner), escapeshellarg($file)), true); |
220 } |
254 } |
221 |
255 |
222 function owner($file) { |
256 /** |
|
257 * @param string $file |
|
258 * @return string|false |
|
259 */ |
|
260 public function owner($file) { |
223 $owneruid = @fileowner('ssh2.sftp://' . $this->sftp_link . '/' . ltrim($file, '/')); |
261 $owneruid = @fileowner('ssh2.sftp://' . $this->sftp_link . '/' . ltrim($file, '/')); |
224 if ( ! $owneruid ) |
262 if ( ! $owneruid ) |
225 return false; |
263 return false; |
226 if ( ! function_exists('posix_getpwuid') ) |
264 if ( ! function_exists('posix_getpwuid') ) |
227 return $owneruid; |
265 return $owneruid; |
228 $ownerarray = posix_getpwuid($owneruid); |
266 $ownerarray = posix_getpwuid($owneruid); |
229 return $ownerarray['name']; |
267 return $ownerarray['name']; |
230 } |
268 } |
231 |
269 /** |
232 function getchmod($file) { |
270 * @param string $file |
233 return substr(decoct(@fileperms( 'ssh2.sftp://' . $this->sftp_link . '/' . ltrim($file, '/') )),3); |
271 * @return string |
234 } |
272 */ |
235 |
273 public function getchmod($file) { |
236 function group($file) { |
274 return substr( decoct( @fileperms( 'ssh2.sftp://' . $this->sftp_link . '/' . ltrim( $file, '/' ) ) ), -3 ); |
|
275 } |
|
276 |
|
277 /** |
|
278 * @param string $file |
|
279 * @return string|false |
|
280 */ |
|
281 public function group($file) { |
237 $gid = @filegroup('ssh2.sftp://' . $this->sftp_link . '/' . ltrim($file, '/')); |
282 $gid = @filegroup('ssh2.sftp://' . $this->sftp_link . '/' . ltrim($file, '/')); |
238 if ( ! $gid ) |
283 if ( ! $gid ) |
239 return false; |
284 return false; |
240 if ( ! function_exists('posix_getgrgid') ) |
285 if ( ! function_exists('posix_getgrgid') ) |
241 return $gid; |
286 return $gid; |
242 $grouparray = posix_getgrgid($gid); |
287 $grouparray = posix_getgrgid($gid); |
243 return $grouparray['name']; |
288 return $grouparray['name']; |
244 } |
289 } |
245 |
290 |
246 function copy($source, $destination, $overwrite = false, $mode = false) { |
291 /** |
|
292 * @param string $source |
|
293 * @param string $destination |
|
294 * @param bool $overwrite |
|
295 * @param int|bool $mode |
|
296 * @return bool |
|
297 */ |
|
298 public function copy($source, $destination, $overwrite = false, $mode = false) { |
247 if ( ! $overwrite && $this->exists($destination) ) |
299 if ( ! $overwrite && $this->exists($destination) ) |
248 return false; |
300 return false; |
249 $content = $this->get_contents($source); |
301 $content = $this->get_contents($source); |
250 if ( false === $content) |
302 if ( false === $content) |
251 return false; |
303 return false; |
252 return $this->put_contents($destination, $content, $mode); |
304 return $this->put_contents($destination, $content, $mode); |
253 } |
305 } |
254 |
306 |
255 function move($source, $destination, $overwrite = false) { |
307 /** |
256 return @ssh2_sftp_rename($this->link, $source, $destination); |
308 * @param string $source |
257 } |
309 * @param string $destination |
258 |
310 * @param bool $overwrite |
259 function delete($file, $recursive = false, $type = false) { |
311 * @return bool |
|
312 */ |
|
313 public function move($source, $destination, $overwrite = false) { |
|
314 return @ssh2_sftp_rename( $this->sftp_link, $source, $destination ); |
|
315 } |
|
316 |
|
317 /** |
|
318 * @param string $file |
|
319 * @param bool $recursive |
|
320 * @param string|bool $type |
|
321 * @return bool |
|
322 */ |
|
323 public function delete($file, $recursive = false, $type = false) { |
260 if ( 'f' == $type || $this->is_file($file) ) |
324 if ( 'f' == $type || $this->is_file($file) ) |
261 return ssh2_sftp_unlink($this->sftp_link, $file); |
325 return ssh2_sftp_unlink($this->sftp_link, $file); |
262 if ( ! $recursive ) |
326 if ( ! $recursive ) |
263 return ssh2_sftp_rmdir($this->sftp_link, $file); |
327 return ssh2_sftp_rmdir($this->sftp_link, $file); |
264 $filelist = $this->dirlist($file); |
328 $filelist = $this->dirlist($file); |
268 } |
332 } |
269 } |
333 } |
270 return ssh2_sftp_rmdir($this->sftp_link, $file); |
334 return ssh2_sftp_rmdir($this->sftp_link, $file); |
271 } |
335 } |
272 |
336 |
273 function exists($file) { |
337 /** |
|
338 * @param string $file |
|
339 * @return bool |
|
340 */ |
|
341 public function exists($file) { |
274 $file = ltrim($file, '/'); |
342 $file = ltrim($file, '/'); |
275 return file_exists('ssh2.sftp://' . $this->sftp_link . '/' . $file); |
343 return file_exists('ssh2.sftp://' . $this->sftp_link . '/' . $file); |
276 } |
344 } |
277 |
345 /** |
278 function is_file($file) { |
346 * @param string $file |
|
347 * @return bool |
|
348 */ |
|
349 public function is_file($file) { |
279 $file = ltrim($file, '/'); |
350 $file = ltrim($file, '/'); |
280 return is_file('ssh2.sftp://' . $this->sftp_link . '/' . $file); |
351 return is_file('ssh2.sftp://' . $this->sftp_link . '/' . $file); |
281 } |
352 } |
282 |
353 /** |
283 function is_dir($path) { |
354 * @param string $path |
|
355 * @return bool |
|
356 */ |
|
357 public function is_dir($path) { |
284 $path = ltrim($path, '/'); |
358 $path = ltrim($path, '/'); |
285 return is_dir('ssh2.sftp://' . $this->sftp_link . '/' . $path); |
359 return is_dir('ssh2.sftp://' . $this->sftp_link . '/' . $path); |
286 } |
360 } |
287 |
361 /** |
288 function is_readable($file) { |
362 * @param string $file |
|
363 * @return bool |
|
364 */ |
|
365 public function is_readable($file) { |
289 $file = ltrim($file, '/'); |
366 $file = ltrim($file, '/'); |
290 return is_readable('ssh2.sftp://' . $this->sftp_link . '/' . $file); |
367 return is_readable('ssh2.sftp://' . $this->sftp_link . '/' . $file); |
291 } |
368 } |
292 |
369 /** |
293 function is_writable($file) { |
370 * @param string $file |
|
371 * @return bool |
|
372 */ |
|
373 public function is_writable($file) { |
294 $file = ltrim($file, '/'); |
374 $file = ltrim($file, '/'); |
295 return is_writable('ssh2.sftp://' . $this->sftp_link . '/' . $file); |
375 return is_writable('ssh2.sftp://' . $this->sftp_link . '/' . $file); |
296 } |
376 } |
297 |
377 /** |
298 function atime($file) { |
378 * @param string $file |
|
379 * @return int |
|
380 */ |
|
381 public function atime($file) { |
299 $file = ltrim($file, '/'); |
382 $file = ltrim($file, '/'); |
300 return fileatime('ssh2.sftp://' . $this->sftp_link . '/' . $file); |
383 return fileatime('ssh2.sftp://' . $this->sftp_link . '/' . $file); |
301 } |
384 } |
302 |
385 |
303 function mtime($file) { |
386 /** |
|
387 * @param string $file |
|
388 * @return int |
|
389 */ |
|
390 public function mtime($file) { |
304 $file = ltrim($file, '/'); |
391 $file = ltrim($file, '/'); |
305 return filemtime('ssh2.sftp://' . $this->sftp_link . '/' . $file); |
392 return filemtime('ssh2.sftp://' . $this->sftp_link . '/' . $file); |
306 } |
393 } |
307 |
394 |
308 function size($file) { |
395 /** |
|
396 * @param string $file |
|
397 * @return int |
|
398 */ |
|
399 public function size($file) { |
309 $file = ltrim($file, '/'); |
400 $file = ltrim($file, '/'); |
310 return filesize('ssh2.sftp://' . $this->sftp_link . '/' . $file); |
401 return filesize('ssh2.sftp://' . $this->sftp_link . '/' . $file); |
311 } |
402 } |
312 |
403 |
313 function touch($file, $time = 0, $atime = 0) { |
404 /** |
|
405 * @param string $file |
|
406 * @param int $time |
|
407 * @param int $atime |
|
408 */ |
|
409 public function touch($file, $time = 0, $atime = 0) { |
314 //Not implemented. |
410 //Not implemented. |
315 } |
411 } |
316 |
412 |
317 function mkdir($path, $chmod = false, $chown = false, $chgrp = false) { |
413 /** |
|
414 * @param string $path |
|
415 * @param mixed $chmod |
|
416 * @param mixed $chown |
|
417 * @param mixed $chgrp |
|
418 * @return bool |
|
419 */ |
|
420 public function mkdir($path, $chmod = false, $chown = false, $chgrp = false) { |
318 $path = untrailingslashit($path); |
421 $path = untrailingslashit($path); |
319 if ( empty($path) ) |
422 if ( empty($path) ) |
320 return false; |
423 return false; |
321 |
424 |
322 if ( ! $chmod ) |
425 if ( ! $chmod ) |
328 if ( $chgrp ) |
431 if ( $chgrp ) |
329 $this->chgrp($path, $chgrp); |
432 $this->chgrp($path, $chgrp); |
330 return true; |
433 return true; |
331 } |
434 } |
332 |
435 |
333 function rmdir($path, $recursive = false) { |
436 /** |
|
437 * @param string $path |
|
438 * @param bool $recursive |
|
439 * @return bool |
|
440 */ |
|
441 public function rmdir($path, $recursive = false) { |
334 return $this->delete($path, $recursive); |
442 return $this->delete($path, $recursive); |
335 } |
443 } |
336 |
444 |
337 function dirlist($path, $include_hidden = true, $recursive = false) { |
445 /** |
|
446 * @param string $path |
|
447 * @param bool $include_hidden |
|
448 * @param bool $recursive |
|
449 * @return bool|array |
|
450 */ |
|
451 public function dirlist($path, $include_hidden = true, $recursive = false) { |
338 if ( $this->is_file($path) ) { |
452 if ( $this->is_file($path) ) { |
339 $limit_file = basename($path); |
453 $limit_file = basename($path); |
340 $path = dirname($path); |
454 $path = dirname($path); |
341 } else { |
455 } else { |
342 $limit_file = false; |
456 $limit_file = false; |