|
1 <?php |
|
2 |
|
3 /** |
|
4 * Base class for FTP implementations. |
|
5 */ |
|
6 abstract class FileTransferFTP extends FileTransfer { |
|
7 |
|
8 public function __construct($jail, $username, $password, $hostname, $port) { |
|
9 $this->username = $username; |
|
10 $this->password = $password; |
|
11 $this->hostname = $hostname; |
|
12 $this->port = $port; |
|
13 parent::__construct($jail); |
|
14 } |
|
15 |
|
16 /** |
|
17 * Return an object which can implement the FTP protocol. |
|
18 * |
|
19 * @param string $jail |
|
20 * @param array $settings |
|
21 * @return FileTransferFTP |
|
22 * The appropriate FileTransferFTP subclass based on the available |
|
23 * options. If the FTP PHP extension is available, use it. |
|
24 */ |
|
25 static function factory($jail, $settings) { |
|
26 $username = empty($settings['username']) ? '' : $settings['username']; |
|
27 $password = empty($settings['password']) ? '' : $settings['password']; |
|
28 $hostname = empty($settings['advanced']['hostname']) ? 'localhost' : $settings['advanced']['hostname']; |
|
29 $port = empty($settings['advanced']['port']) ? 21 : $settings['advanced']['port']; |
|
30 |
|
31 if (function_exists('ftp_connect')) { |
|
32 $class = 'FileTransferFTPExtension'; |
|
33 } |
|
34 else { |
|
35 throw new FileTransferException('No FTP backend available.'); |
|
36 } |
|
37 |
|
38 return new $class($jail, $username, $password, $hostname, $port); |
|
39 } |
|
40 |
|
41 /** |
|
42 * Returns the form to configure the FileTransfer class for FTP. |
|
43 */ |
|
44 public function getSettingsForm() { |
|
45 $form = parent::getSettingsForm(); |
|
46 $form['advanced']['port']['#default_value'] = 21; |
|
47 return $form; |
|
48 } |
|
49 } |
|
50 |
|
51 class FileTransferFTPExtension extends FileTransferFTP implements FileTransferChmodInterface { |
|
52 |
|
53 public function connect() { |
|
54 $this->connection = ftp_connect($this->hostname, $this->port); |
|
55 |
|
56 if (!$this->connection) { |
|
57 throw new FileTransferException("Cannot connect to FTP Server, check settings"); |
|
58 } |
|
59 if (!ftp_login($this->connection, $this->username, $this->password)) { |
|
60 throw new FileTransferException("Cannot log in to FTP server. Check username and password"); |
|
61 } |
|
62 } |
|
63 |
|
64 protected function copyFileJailed($source, $destination) { |
|
65 if (!@ftp_put($this->connection, $destination, $source, FTP_BINARY)) { |
|
66 throw new FileTransferException("Cannot move @source to @destination", NULL, array("@source" => $source, "@destination" => $destination)); |
|
67 } |
|
68 } |
|
69 |
|
70 protected function createDirectoryJailed($directory) { |
|
71 if (!ftp_mkdir($this->connection, $directory)) { |
|
72 throw new FileTransferException("Cannot create directory @directory", NULL, array("@directory" => $directory)); |
|
73 } |
|
74 } |
|
75 |
|
76 protected function removeDirectoryJailed($directory) { |
|
77 $pwd = ftp_pwd($this->connection); |
|
78 if (!ftp_chdir($this->connection, $directory)) { |
|
79 throw new FileTransferException("Unable to change to directory @directory", NULL, array('@directory' => $directory)); |
|
80 } |
|
81 $list = @ftp_nlist($this->connection, '.'); |
|
82 if (!$list) { |
|
83 $list = array(); |
|
84 } |
|
85 foreach ($list as $item) { |
|
86 if ($item == '.' || $item == '..') { |
|
87 continue; |
|
88 } |
|
89 if (@ftp_chdir($this->connection, $item)) { |
|
90 ftp_cdup($this->connection); |
|
91 $this->removeDirectory(ftp_pwd($this->connection) . '/' . $item); |
|
92 } |
|
93 else { |
|
94 $this->removeFile(ftp_pwd($this->connection) . '/' . $item); |
|
95 } |
|
96 } |
|
97 ftp_chdir($this->connection, $pwd); |
|
98 if (!ftp_rmdir($this->connection, $directory)) { |
|
99 throw new FileTransferException("Unable to remove to directory @directory", NULL, array('@directory' => $directory)); |
|
100 } |
|
101 } |
|
102 |
|
103 protected function removeFileJailed($destination) { |
|
104 if (!ftp_delete($this->connection, $destination)) { |
|
105 throw new FileTransferException("Unable to remove to file @file", NULL, array('@file' => $destination)); |
|
106 } |
|
107 } |
|
108 |
|
109 public function isDirectory($path) { |
|
110 $result = FALSE; |
|
111 $curr = ftp_pwd($this->connection); |
|
112 if (@ftp_chdir($this->connection, $path)) { |
|
113 $result = TRUE; |
|
114 } |
|
115 ftp_chdir($this->connection, $curr); |
|
116 return $result; |
|
117 } |
|
118 |
|
119 public function isFile($path) { |
|
120 return ftp_size($this->connection, $path) != -1; |
|
121 } |
|
122 |
|
123 function chmodJailed($path, $mode, $recursive) { |
|
124 if (!ftp_chmod($this->connection, $mode, $path)) { |
|
125 throw new FileTransferException("Unable to set permissions on %file", NULL, array('%file' => $path)); |
|
126 } |
|
127 if ($this->isDirectory($path) && $recursive) { |
|
128 $filelist = @ftp_nlist($this->connection, $path); |
|
129 if (!$filelist) { |
|
130 //empty directory - returns false |
|
131 return; |
|
132 } |
|
133 foreach ($filelist as $file) { |
|
134 $this->chmodJailed($file, $mode, $recursive); |
|
135 } |
|
136 } |
|
137 } |
|
138 } |
|
139 |
|
140 if (!function_exists('ftp_chmod')) { |
|
141 function ftp_chmod($ftp_stream, $mode, $filename) { |
|
142 return ftp_site($ftp_stream, sprintf('CHMOD %o %s', $mode, $filename)); |
|
143 } |
|
144 } |