Subversion Repositories Applications.papyrus

Rev

Rev 320 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 320 Rev 969
1
<?php
1
<?php
2
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
2
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
 
3
 
4
/**
4
/**
5
 * Net_FTP main file.
5
 * Net_FTP main file.
6
 *
6
 *
7
 * This file must be included to use the Net_FTP package.
7
 * This file must be included to use the Net_FTP package.
8
 *
8
 *
9
 * PHP versions 4 and 5
9
 * PHP versions 4 and 5
10
 *
10
 *
11
 * LICENSE: This source file is subject to version 3.0 of the PHP license
11
 * LICENSE: This source file is subject to version 3.0 of the PHP license
12
 * that is available through the world-wide-web at the following URI:
12
 * that is available through the world-wide-web at the following URI:
13
 * http://www.php.net/license/3_0.txt.  If you did not receive a copy of
13
 * http://www.php.net/license/3_0.txt.  If you did not receive a copy of
14
 * the PHP License and are unable to obtain it through the web, please
14
 * the PHP License and are unable to obtain it through the web, please
15
 * send a note to license@php.net so we can mail you a copy immediately.
15
 * send a note to license@php.net so we can mail you a copy immediately.
16
 *
16
 *
17
 * @category   Networking
17
 * @category   Networking
18
 * @package    FTP
18
 * @package    FTP
19
 * @author     Tobias Schlitt <toby@php.net>
19
 * @author     Tobias Schlitt <toby@php.net>
20
 * @copyright  1997-2005 The PHP Group
20
 * @copyright  1997-2005 The PHP Group
21
 * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
21
 * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
22
 * @version    CVS: $Id: FTP.php,v 1.1 2005-03-30 08:50:33 jpm Exp $
22
 * @version    CVS: $Id: FTP.php,v 1.2 2006-10-05 08:55:35 florian Exp $
23
 * @link       http://pear.php.net/package/Net_FTP
23
 * @link       http://pear.php.net/package/Net_FTP
24
 * @since      File available since Release 0.0.1
24
 * @since      File available since Release 0.0.1
25
 */
25
 */
26
 
26
 
27
require_once 'PEAR.php';
27
require_once 'PEAR.php';
28
 
28
 
29
/**
29
/**
30
 * Option to let the ls() method return only files.
30
 * Option to let the ls() method return only files.
31
 *
31
 *
32
 * @since 1.3
32
 * @since 1.3
33
 * @name NET_FTP_FILES_ONLY
33
 * @name NET_FTP_FILES_ONLY
34
 * @see Net_FTP::ls()
34
 * @see Net_FTP::ls()
35
 */
35
 */
36
define('NET_FTP_FILES_ONLY', 0, true);
36
define('NET_FTP_FILES_ONLY', 0, true);
37
 
37
 
38
/**
38
/**
39
 * Option to let the ls() method return only directories.
39
 * Option to let the ls() method return only directories.
40
 *
40
 *
41
 * @since 1.3
41
 * @since 1.3
42
 * @name NET_FTP_DIRS_ONLY
42
 * @name NET_FTP_DIRS_ONLY
43
 * @see Net_FTP::ls()
43
 * @see Net_FTP::ls()
44
 */
44
 */
45
define('NET_FTP_DIRS_ONLY', 1, true);
45
define('NET_FTP_DIRS_ONLY', 1, true);
46
 
46
 
47
/**
47
/**
48
 * Option to let the ls() method return directories and files (default).
48
 * Option to let the ls() method return directories and files (default).
49
 *
49
 *
50
 * @since 1.3
50
 * @since 1.3
51
 * @name NET_FTP_DIRS_FILES
51
 * @name NET_FTP_DIRS_FILES
52
 * @see Net_FTP::ls()
52
 * @see Net_FTP::ls()
53
 */
53
 */
54
define('NET_FTP_DIRS_FILES', 2, true);
54
define('NET_FTP_DIRS_FILES', 2, true);
55
 
55
 
56
/**
56
/**
57
 * Option to let the ls() method return the raw directory listing from ftp_rawlist().
57
 * Option to let the ls() method return the raw directory listing from ftp_rawlist().
58
 *
58
 *
59
 * @since 1.3
59
 * @since 1.3
60
 * @name NET_FTP_RAWLIST
60
 * @name NET_FTP_RAWLIST
61
 * @see Net_FTP::ls()
61
 * @see Net_FTP::ls()
62
 */
62
 */
63
define('NET_FTP_RAWLIST', 3, true);
63
define('NET_FTP_RAWLIST', 3, true);
64
 
64
 
65
 
65
 
66
/**
66
/**
67
 * Error code to indicate a failed connection
67
 * Error code to indicate a failed connection
68
 * This error code indicates, that the connection you tryed to set up
68
 * This error code indicates, that the connection you tryed to set up
69
 * could not be established. Check your connection settings (host & port)!
69
 * could not be established. Check your connection settings (host & port)!
70
 *
70
 *
71
 * @since 1.3
71
 * @since 1.3
72
 * @name NET_FTP_ERR_CONNECT_FAILED
72
 * @name NET_FTP_ERR_CONNECT_FAILED
73
 * @see Net_FTP::connect()
73
 * @see Net_FTP::connect()
74
 */
74
 */
75
define('NET_FTP_ERR_CONNECT_FAILED', -1);
75
define('NET_FTP_ERR_CONNECT_FAILED', -1);
76
 
76
 
77
/**
77
/**
78
 * Error code to indicate a failed login
78
 * Error code to indicate a failed login
79
 * This error code indicates, that the login to the FTP server failed. Check
79
 * This error code indicates, that the login to the FTP server failed. Check
80
 * your user data (username & password).
80
 * your user data (username & password).
81
 *
81
 *
82
 * @since 1.3
82
 * @since 1.3
83
 * @name NET_FTP_ERR_LOGIN_FAILED
83
 * @name NET_FTP_ERR_LOGIN_FAILED
84
 * @see Net_FTP::login()
84
 * @see Net_FTP::login()
85
 */
85
 */
86
define('NET_FTP_ERR_LOGIN_FAILED', -2);
86
define('NET_FTP_ERR_LOGIN_FAILED', -2);
87
 
87
 
88
/**
88
/**
89
 * Error code to indicate a failed directory change
89
 * Error code to indicate a failed directory change
90
 * The cd() method failed. Ensure that the directory you wanted to access exists.
90
 * The cd() method failed. Ensure that the directory you wanted to access exists.
91
 *
91
 *
92
 * @since 1.3
92
 * @since 1.3
93
 * @name NET_FTP_ERR_DIRCHANGE_FAILED
93
 * @name NET_FTP_ERR_DIRCHANGE_FAILED
94
 * @see Net_FTP::cd()
94
 * @see Net_FTP::cd()
95
 */
95
 */
96
define('NET_FTP_ERR_DIRCHANGE_FAILED', 2); // Compatibillity reasons!
96
define('NET_FTP_ERR_DIRCHANGE_FAILED', 2); // Compatibillity reasons!
97
 
97
 
98
/**
98
/**
99
 * Error code to indicate that Net_FTP could not determine the current path
99
 * Error code to indicate that Net_FTP could not determine the current path
100
 * The cwd() method failed and could not determine the path you currently reside
100
 * The cwd() method failed and could not determine the path you currently reside
101
 * in on the FTP server.
101
 * in on the FTP server.
102
 *
102
 *
103
 * @since 1.3
103
 * @since 1.3
104
 * @name NET_FTP_ERR_DETERMINEPATH_FAILED
104
 * @name NET_FTP_ERR_DETERMINEPATH_FAILED
105
 * @see Net_FTP::pwd()
105
 * @see Net_FTP::pwd()
106
 */
106
 */
107
define('NET_FTP_ERR_DETERMINEPATH_FAILED', 4); // Compatibillity reasons!
107
define('NET_FTP_ERR_DETERMINEPATH_FAILED', 4); // Compatibillity reasons!
108
 
108
 
109
/**
109
/**
110
 * Error code to indicate that the creation of a directory failed
110
 * Error code to indicate that the creation of a directory failed
111
 * The directory you tryed to create could not be created. Check the
111
 * The directory you tryed to create could not be created. Check the
112
 * access rights on the parent directory!
112
 * access rights on the parent directory!
113
 *
113
 *
114
 * @since 1.3
114
 * @since 1.3
115
 * @name NET_FTP_ERR_CREATEDIR_FAILED
115
 * @name NET_FTP_ERR_CREATEDIR_FAILED
116
 * @see Net_FTP::mkdir()
116
 * @see Net_FTP::mkdir()
117
 */
117
 */
118
define('NET_FTP_ERR_CREATEDIR_FAILED', -4);
118
define('NET_FTP_ERR_CREATEDIR_FAILED', -4);
119
 
119
 
120
/**
120
/**
121
 * Error code to indicate that the EXEC execution failed.
121
 * Error code to indicate that the EXEC execution failed.
122
 * The execution of a command using EXEC failed. Ensure, that your
122
 * The execution of a command using EXEC failed. Ensure, that your
123
 * FTP server supports the EXEC command.
123
 * FTP server supports the EXEC command.
124
 *
124
 *
125
 * @since 1.3
125
 * @since 1.3
126
 * @name NET_FTP_ERR_EXEC_FAILED
126
 * @name NET_FTP_ERR_EXEC_FAILED
127
 * @see Net_FTP::execute()
127
 * @see Net_FTP::execute()
128
 */
128
 */
129
define('NET_FTP_ERR_EXEC_FAILED', -5);
129
define('NET_FTP_ERR_EXEC_FAILED', -5);
130
 
130
 
131
/**
131
/**
132
 * Error code to indicate that the SITE command failed.
132
 * Error code to indicate that the SITE command failed.
133
 * The execution of a command using SITE failed. Ensure, that your
133
 * The execution of a command using SITE failed. Ensure, that your
134
 * FTP server supports the SITE command.
134
 * FTP server supports the SITE command.
135
 *
135
 *
136
 * @since 1.3
136
 * @since 1.3
137
 * @name NET_FTP_ERR_SITE_FAILED
137
 * @name NET_FTP_ERR_SITE_FAILED
138
 * @see Net_FTP::site()
138
 * @see Net_FTP::site()
139
 */
139
 */
140
define('NET_FTP_ERR_SITE_FAILED', -6);
140
define('NET_FTP_ERR_SITE_FAILED', -6);
141
 
141
 
142
/**
142
/**
143
 * Error code to indicate that the CHMOD command failed.
143
 * Error code to indicate that the CHMOD command failed.
144
 * The execution of CHMOD failed. Ensure, that your
144
 * The execution of CHMOD failed. Ensure, that your
145
 * FTP server supports the CHMOD command and that you have the appropriate
145
 * FTP server supports the CHMOD command and that you have the appropriate
146
 * access rights to use CHMOD.
146
 * access rights to use CHMOD.
147
 *
147
 *
148
 * @since 1.3
148
 * @since 1.3
149
 * @name NET_FTP_ERR_CHMOD_FAILED
149
 * @name NET_FTP_ERR_CHMOD_FAILED
150
 * @see Net_FTP::chmod()
150
 * @see Net_FTP::chmod()
151
 */
151
 */
152
define('NET_FTP_ERR_CHMOD_FAILED', -7);
152
define('NET_FTP_ERR_CHMOD_FAILED', -7);
153
 
153
 
154
/**
154
/**
155
 * Error code to indicate that a file rename failed
155
 * Error code to indicate that a file rename failed
156
 * The renaming of a file on the server failed. Ensure that you have the
156
 * The renaming of a file on the server failed. Ensure that you have the
157
 * appropriate access rights to rename the file.
157
 * appropriate access rights to rename the file.
158
 *
158
 *
159
 * @since 1.3
159
 * @since 1.3
160
 * @name NET_FTP_ERR_RENAME_FAILED
160
 * @name NET_FTP_ERR_RENAME_FAILED
161
 * @see Net_FTP::rename()
161
 * @see Net_FTP::rename()
162
 */
162
 */
163
define('NET_FTP_ERR_RENAME_FAILED', -8);
163
define('NET_FTP_ERR_RENAME_FAILED', -8);
164
 
164
 
165
/**
165
/**
166
 * Error code to indicate that the MDTM command failed
166
 * Error code to indicate that the MDTM command failed
167
 * The MDTM command is not supported for directories. Ensure that you gave
167
 * The MDTM command is not supported for directories. Ensure that you gave
168
 * a file path to the mdtm() method, not a directory path.
168
 * a file path to the mdtm() method, not a directory path.
169
 *
169
 *
170
 * @since 1.3
170
 * @since 1.3
171
 * @name NET_FTP_ERR_MDTMDIR_UNSUPPORTED
171
 * @name NET_FTP_ERR_MDTMDIR_UNSUPPORTED
172
 * @see Net_FTP::mdtm()
172
 * @see Net_FTP::mdtm()
173
 */
173
 */
174
define('NET_FTP_ERR_MDTMDIR_UNSUPPORTED', -9);
174
define('NET_FTP_ERR_MDTMDIR_UNSUPPORTED', -9);
175
 
175
 
176
/**
176
/**
177
 * Error code to indicate that the MDTM command failed
177
 * Error code to indicate that the MDTM command failed
178
 * The MDTM command failed. Ensure that your server supports the MDTM command.
178
 * The MDTM command failed. Ensure that your server supports the MDTM command.
179
 *
179
 *
180
 * @since 1.3
180
 * @since 1.3
181
 * @name NET_FTP_ERR_MDTM_FAILED
181
 * @name NET_FTP_ERR_MDTM_FAILED
182
 * @see Net_FTP::mdtm()
182
 * @see Net_FTP::mdtm()
183
 */
183
 */
184
define('NET_FTP_ERR_MDTM_FAILED', -10);
184
define('NET_FTP_ERR_MDTM_FAILED', -10);
185
 
185
 
186
/**
186
/**
187
 * Error code to indicate that a date returned by the server was misformated
187
 * Error code to indicate that a date returned by the server was misformated
188
 * A date string returned by your server seems to be missformated and could not be
188
 * A date string returned by your server seems to be missformated and could not be
189
 * parsed. Check that the server is configured correctly. If you're sure, please
189
 * parsed. Check that the server is configured correctly. If you're sure, please
190
 * send an email to the auhtor with a dumped output of $ftp->ls('./', NET_FTP_RAWLIST);
190
 * send an email to the auhtor with a dumped output of $ftp->ls('./', NET_FTP_RAWLIST);
191
 * to get the date format supported.
191
 * to get the date format supported.
192
 *
192
 *
193
 * @since 1.3
193
 * @since 1.3
194
 * @name NET_FTP_ERR_DATEFORMAT_FAILED
194
 * @name NET_FTP_ERR_DATEFORMAT_FAILED
195
 * @see Net_FTP::mdtm(), Net_FTP::ls()
195
 * @see Net_FTP::mdtm(), Net_FTP::ls()
196
 */
196
 */
197
define('NET_FTP_ERR_DATEFORMAT_FAILED', -11);
197
define('NET_FTP_ERR_DATEFORMAT_FAILED', -11);
198
 
198
 
199
/**
199
/**
200
 * Error code to indicate that the SIZE command failed
200
 * Error code to indicate that the SIZE command failed
201
 * The determination of the filesize of a file failed. Ensure that your server supports the
201
 * The determination of the filesize of a file failed. Ensure that your server supports the
202
 * SIZE command.
202
 * SIZE command.
203
 *
203
 *
204
 * @since 1.3
204
 * @since 1.3
205
 * @name NET_FTP_ERR_SIZE_FAILED
205
 * @name NET_FTP_ERR_SIZE_FAILED
206
 * @see Net_FTP::size()
206
 * @see Net_FTP::size()
207
 */
207
 */
208
define('NET_FTP_ERR_SIZE_FAILED', -12);
208
define('NET_FTP_ERR_SIZE_FAILED', -12);
209
 
209
 
210
/**
210
/**
211
 * Error code to indicate that a local file could not be overwritten
211
 * Error code to indicate that a local file could not be overwritten
212
 * You specified not to overwrite files. Therefore the local file has not been
212
 * You specified not to overwrite files. Therefore the local file has not been
213
 * overwriten. If you want to get the file overwriten, please set the option to
213
 * overwriten. If you want to get the file overwriten, please set the option to
214
 * do so.
214
 * do so.
215
 *
215
 *
216
 * @since 1.3
216
 * @since 1.3
217
 * @name NET_FTP_ERR_OVERWRITELOCALFILE_FORBIDDEN
217
 * @name NET_FTP_ERR_OVERWRITELOCALFILE_FORBIDDEN
218
 * @see Net_FTP::get(), Net_FTP::getRecursive()
218
 * @see Net_FTP::get(), Net_FTP::getRecursive()
219
 */
219
 */
220
define('NET_FTP_ERR_OVERWRITELOCALFILE_FORBIDDEN', -13);
220
define('NET_FTP_ERR_OVERWRITELOCALFILE_FORBIDDEN', -13);
221
 
221
 
222
/**
222
/**
223
 * Error code to indicate that a local file could not be overwritten
223
 * Error code to indicate that a local file could not be overwritten
224
 * Also you specified to overwrite the local file you want to download to,
224
 * Also you specified to overwrite the local file you want to download to,
225
 * it has not been possible to do so. Check that you have the appropriate access
225
 * it has not been possible to do so. Check that you have the appropriate access
226
 * rights on the local file to overwrite it.
226
 * rights on the local file to overwrite it.
227
 *
227
 *
228
 * @since 1.3
228
 * @since 1.3
229
 * @name NET_FTP_ERR_OVERWRITELOCALFILE_FAILED
229
 * @name NET_FTP_ERR_OVERWRITELOCALFILE_FAILED
230
 * @see Net_FTP::get(), Net_FTP::getRecursive()
230
 * @see Net_FTP::get(), Net_FTP::getRecursive()
231
 */
231
 */
232
define('NET_FTP_ERR_OVERWRITELOCALFILE_FAILED', -14);
232
define('NET_FTP_ERR_OVERWRITELOCALFILE_FAILED', -14);
233
 
233
 
234
/**
234
/**
235
 * Error code to indicate that the file you wanted to upload does not exist
235
 * Error code to indicate that the file you wanted to upload does not exist
236
 * The file you tried to upload does not exist. Ensure that it exists.
236
 * The file you tried to upload does not exist. Ensure that it exists.
237
 *
237
 *
238
 * @since 1.3
238
 * @since 1.3
239
 * @name NET_FTP_ERR_LOCALFILENOTEXIST
239
 * @name NET_FTP_ERR_LOCALFILENOTEXIST
240
 * @see Net_FTP::put(), Net_FTP::putRecursive()
240
 * @see Net_FTP::put(), Net_FTP::putRecursive()
241
 */
241
 */
242
define('NET_FTP_ERR_LOCALFILENOTEXIST', -15);
242
define('NET_FTP_ERR_LOCALFILENOTEXIST', -15);
243
 
243
 
244
/**
244
/**
245
 * Error code to indicate that a remote file could not be overwritten
245
 * Error code to indicate that a remote file could not be overwritten
246
 * You specified not to overwrite files. Therefore the remote file has not been
246
 * You specified not to overwrite files. Therefore the remote file has not been
247
 * overwriten. If you want to get the file overwriten, please set the option to
247
 * overwriten. If you want to get the file overwriten, please set the option to
248
 * do so.
248
 * do so.
249
 *
249
 *
250
 * @since 1.3
250
 * @since 1.3
251
 * @name NET_FTP_ERR_OVERWRITEREMOTEFILE_FORBIDDEN
251
 * @name NET_FTP_ERR_OVERWRITEREMOTEFILE_FORBIDDEN
252
 * @see Net_FTP::put(), Net_FTP::putRecursive()
252
 * @see Net_FTP::put(), Net_FTP::putRecursive()
253
 */
253
 */
254
define('NET_FTP_ERR_OVERWRITEREMOTEFILE_FORBIDDEN', -16);
254
define('NET_FTP_ERR_OVERWRITEREMOTEFILE_FORBIDDEN', -16);
255
 
255
 
256
/**
256
/**
257
 * Error code to indicate that the upload of a file failed
257
 * Error code to indicate that the upload of a file failed
258
 * The upload you tried failed. Ensure that you have appropriate access rights
258
 * The upload you tried failed. Ensure that you have appropriate access rights
259
 * to upload the desired file.
259
 * to upload the desired file.
260
 *
260
 *
261
 * @since 1.3
261
 * @since 1.3
262
 * @name NET_FTP_ERR_UPLOADFILE_FAILED
262
 * @name NET_FTP_ERR_UPLOADFILE_FAILED
263
 * @see Net_FTP::put(), Net_FTP::putRecursive()
263
 * @see Net_FTP::put(), Net_FTP::putRecursive()
264
 */
264
 */
265
define('NET_FTP_ERR_UPLOADFILE_FAILED', -17);
265
define('NET_FTP_ERR_UPLOADFILE_FAILED', -17);
266
 
266
 
267
/**
267
/**
268
 * Error code to indicate that you specified an incorrect directory path
268
 * Error code to indicate that you specified an incorrect directory path
269
 * The remote path you specified seems not to be a directory. Ensure that
269
 * The remote path you specified seems not to be a directory. Ensure that
270
 * the path you specify is a directory and that the path string ends with
270
 * the path you specify is a directory and that the path string ends with
271
 * a /.
271
 * a /.
272
 *
272
 *
273
 * @since 1.3
273
 * @since 1.3
274
 * @name NET_FTP_ERR_REMOTEPATHNODIR
274
 * @name NET_FTP_ERR_REMOTEPATHNODIR
275
 * @see Net_FTP::putRecursive(), Net_FTP::getRecursive()
275
 * @see Net_FTP::putRecursive(), Net_FTP::getRecursive()
276
 */
276
 */
277
define('NET_FTP_ERR_REMOTEPATHNODIR', -18);
277
define('NET_FTP_ERR_REMOTEPATHNODIR', -18);
278
 
278
 
279
/**
279
/**
280
 * Error code to indicate that you specified an incorrect directory path
280
 * Error code to indicate that you specified an incorrect directory path
281
 * The local path you specified seems not to be a directory. Ensure that
281
 * The local path you specified seems not to be a directory. Ensure that
282
 * the path you specify is a directory and that the path string ends with
282
 * the path you specify is a directory and that the path string ends with
283
 * a /.
283
 * a /.
284
 *
284
 *
285
 * @since 1.3
285
 * @since 1.3
286
 * @name NET_FTP_ERR_LOCALPATHNODIR
286
 * @name NET_FTP_ERR_LOCALPATHNODIR
287
 * @see Net_FTP::putRecursive(), Net_FTP::getRecursive()
287
 * @see Net_FTP::putRecursive(), Net_FTP::getRecursive()
288
 */
288
 */
289
define('NET_FTP_ERR_LOCALPATHNODIR', -19);
289
define('NET_FTP_ERR_LOCALPATHNODIR', -19);
290
 
290
 
291
/**
291
/**
292
 * Error code to indicate that a local directory failed to be created
292
 * Error code to indicate that a local directory failed to be created
293
 * You tried to create a local directory through getRecursive() method,
293
 * You tried to create a local directory through getRecursive() method,
294
 * which has failed. Ensure that you have the appropriate access rights
294
 * which has failed. Ensure that you have the appropriate access rights
295
 * to create it.
295
 * to create it.
296
 *
296
 *
297
 * @since 1.3
297
 * @since 1.3
298
 * @name NET_FTP_ERR_CREATELOCALDIR_FAILED
298
 * @name NET_FTP_ERR_CREATELOCALDIR_FAILED
299
 * @see Net_FTP::getRecursive()
299
 * @see Net_FTP::getRecursive()
300
 */
300
 */
301
define('NET_FTP_ERR_CREATELOCALDIR_FAILED', -20);
301
define('NET_FTP_ERR_CREATELOCALDIR_FAILED', -20);
302
 
302
 
303
/**
303
/**
304
 * Error code to indicate that the provided hostname was incorrect
304
 * Error code to indicate that the provided hostname was incorrect
305
 * The hostname you provided was invalid. Ensure to provide either a
305
 * The hostname you provided was invalid. Ensure to provide either a
306
 * full qualified domain name or an IP address.
306
 * full qualified domain name or an IP address.
307
 *
307
 *
308
 * @since 1.3
308
 * @since 1.3
309
 * @name NET_FTP_ERR_HOSTNAMENOSTRING
309
 * @name NET_FTP_ERR_HOSTNAMENOSTRING
310
 * @see Net_FTP::setHostname()
310
 * @see Net_FTP::setHostname()
311
 */
311
 */
312
define('NET_FTP_ERR_HOSTNAMENOSTRING', -21);
312
define('NET_FTP_ERR_HOSTNAMENOSTRING', -21);
313
 
313
 
314
/**
314
/**
315
 * Error code to indicate that the provided port was incorrect
315
 * Error code to indicate that the provided port was incorrect
316
 * The port number you provided was invalid. Ensure to provide either a
316
 * The port number you provided was invalid. Ensure to provide either a
317
 * a numeric port number greater zero.
317
 * a numeric port number greater zero.
318
 *
318
 *
319
 * @since 1.3
319
 * @since 1.3
320
 * @name NET_FTP_ERR_PORTLESSZERO
320
 * @name NET_FTP_ERR_PORTLESSZERO
321
 * @see Net_FTP::setPort()
321
 * @see Net_FTP::setPort()
322
 */
322
 */
323
define('NET_FTP_ERR_PORTLESSZERO', -22);
323
define('NET_FTP_ERR_PORTLESSZERO', -22);
324
 
324
 
325
/**
325
/**
326
 * Error code to indicate that you provided an invalid mode constant
326
 * Error code to indicate that you provided an invalid mode constant
327
 * The mode constant you provided was invalid. You may only provide
327
 * The mode constant you provided was invalid. You may only provide
328
 * FTP_ASCII or FTP_BINARY.
328
 * FTP_ASCII or FTP_BINARY.
329
 *
329
 *
330
 * @since 1.3
330
 * @since 1.3
331
 * @name NET_FTP_ERR_NOMODECONST
331
 * @name NET_FTP_ERR_NOMODECONST
332
 * @see Net_FTP::setMode()
332
 * @see Net_FTP::setMode()
333
 */
333
 */
334
define('NET_FTP_ERR_NOMODECONST', -23);
334
define('NET_FTP_ERR_NOMODECONST', -23);
335
 
335
 
336
/**
336
/**
337
 * Error code to indicate that you provided an invalid timeout
337
 * Error code to indicate that you provided an invalid timeout
338
 * The timeout you provided was invalid. You have to provide a timeout greater
338
 * The timeout you provided was invalid. You have to provide a timeout greater
339
 * or equal to zero.
339
 * or equal to zero.
340
 *
340
 *
341
 * @since 1.3
341
 * @since 1.3
342
 * @name NET_FTP_ERR_TIMEOUTLESSZERO
342
 * @name NET_FTP_ERR_TIMEOUTLESSZERO
343
 * @see Net_FTP::Net_FTP(), Net_FTP::setTimeout()
343
 * @see Net_FTP::Net_FTP(), Net_FTP::setTimeout()
344
 */
344
 */
345
define('NET_FTP_ERR_TIMEOUTLESSZERO', -24);
345
define('NET_FTP_ERR_TIMEOUTLESSZERO', -24);
346
 
346
 
347
/**
347
/**
348
 * Error code to indicate that you provided an invalid timeout
348
 * Error code to indicate that you provided an invalid timeout
349
 * An error occured while setting the timeout. Ensure that you provide a
349
 * An error occured while setting the timeout. Ensure that you provide a
350
 * valid integer for the timeount and that your PHP installation works
350
 * valid integer for the timeount and that your PHP installation works
351
 * correctly.
351
 * correctly.
352
 *
352
 *
353
 * @since 1.3
353
 * @since 1.3
354
 * @name NET_FTP_ERR_SETTIMEOUT_FAILED
354
 * @name NET_FTP_ERR_SETTIMEOUT_FAILED
355
 * @see Net_FTP::Net_FTP(), Net_FTP::setTimeout()
355
 * @see Net_FTP::Net_FTP(), Net_FTP::setTimeout()
356
 */
356
 */
357
define('NET_FTP_ERR_SETTIMEOUT_FAILED', -25);
357
define('NET_FTP_ERR_SETTIMEOUT_FAILED', -25);
358
 
358
 
359
/**
359
/**
360
 * Error code to indicate that the provided extension file doesn't exist
360
 * Error code to indicate that the provided extension file doesn't exist
361
 * The provided extension file does not exist. Ensure to provided an
361
 * The provided extension file does not exist. Ensure to provided an
362
 * existant extension file.
362
 * existant extension file.
363
 *
363
 *
364
 * @since 1.3
364
 * @since 1.3
365
 * @name NET_FTP_ERR_EXTFILENOTEXIST
365
 * @name NET_FTP_ERR_EXTFILENOTEXIST
366
 * @see Net_FTP::getExtensionFile()
366
 * @see Net_FTP::getExtensionFile()
367
 */
367
 */
368
define('NET_FTP_ERR_EXTFILENOTEXIST', -26);
368
define('NET_FTP_ERR_EXTFILENOTEXIST', -26);
369
 
369
 
370
/**
370
/**
371
 * Error code to indicate that the provided extension file is not readable
371
 * Error code to indicate that the provided extension file is not readable
372
 * The provided extension file is not readable. Ensure to have sufficient
372
 * The provided extension file is not readable. Ensure to have sufficient
373
 * access rights for it.
373
 * access rights for it.
374
 *
374
 *
375
 * @since 1.3
375
 * @since 1.3
376
 * @name NET_FTP_ERR_EXTFILEREAD_FAILED
376
 * @name NET_FTP_ERR_EXTFILEREAD_FAILED
377
 * @see Net_FTP::getExtensionFile()
377
 * @see Net_FTP::getExtensionFile()
378
 */
378
 */
379
define('NET_FTP_ERR_EXTFILEREAD_FAILED', -27);
379
define('NET_FTP_ERR_EXTFILEREAD_FAILED', -27);
380
 
380
 
381
/**
381
/**
382
 * Error code to indicate that the deletion of a file failed
382
 * Error code to indicate that the deletion of a file failed
383
 * The specified file could not be deleted. Ensure to have sufficient
383
 * The specified file could not be deleted. Ensure to have sufficient
384
 * access rights to delete the file.
384
 * access rights to delete the file.
385
 *
385
 *
386
 * @since 1.3
386
 * @since 1.3
387
 * @name NET_FTP_ERR_EXTFILEREAD_FAILED
387
 * @name NET_FTP_ERR_EXTFILEREAD_FAILED
388
 * @see Net_FTP::rm()
388
 * @see Net_FTP::rm()
389
 */
389
 */
390
define('NET_FTP_ERR_DELETEFILE_FAILED', -28);
390
define('NET_FTP_ERR_DELETEFILE_FAILED', -28);
391
 
391
 
392
/**
392
/**
393
 * Error code to indicate that the deletion of a directory faild
393
 * Error code to indicate that the deletion of a directory faild
394
 * The specified file could not be deleted. Ensure to have sufficient
394
 * The specified file could not be deleted. Ensure to have sufficient
395
 * access rights to delete the file.
395
 * access rights to delete the file.
396
 *
396
 *
397
 * @since 1.3
397
 * @since 1.3
398
 * @name NET_FTP_ERR_EXTFILEREAD_FAILED
398
 * @name NET_FTP_ERR_EXTFILEREAD_FAILED
399
 * @see Net_FTP::rm()
399
 * @see Net_FTP::rm()
400
 */
400
 */
401
define('NET_FTP_ERR_DELETEDIR_FAILED', -29);
401
define('NET_FTP_ERR_DELETEDIR_FAILED', -29);
402
 
402
 
403
/**
403
/**
404
 * Error code to indicate that the directory listing failed
404
 * Error code to indicate that the directory listing failed
405
 * PHP could not list the directory contents on the server. Ensure
405
 * PHP could not list the directory contents on the server. Ensure
406
 * that your server is configured appropriate.
406
 * that your server is configured appropriate.
407
 *
407
 *
408
 * @since 1.3
408
 * @since 1.3
409
 * @name NET_FTP_ERR_RAWDIRLIST_FAILED
409
 * @name NET_FTP_ERR_RAWDIRLIST_FAILED
410
 * @see Net_FTP::ls()
410
 * @see Net_FTP::ls()
411
 */
411
 */
412
define('NET_FTP_ERR_RAWDIRLIST_FAILED', -30);
412
define('NET_FTP_ERR_RAWDIRLIST_FAILED', -30);
413
 
413
 
414
/**
414
/**
415
 * Error code to indicate that the directory listing failed
415
 * Error code to indicate that the directory listing failed
416
 * The directory listing format your server uses seems not to
416
 * The directory listing format your server uses seems not to
417
 * be supported by Net_FTP. Please send the output of the
417
 * be supported by Net_FTP. Please send the output of the
418
 * call ls('./', NET_FTP_RAWLIST); to the author of this
418
 * call ls('./', NET_FTP_RAWLIST); to the author of this
419
 * class to get it supported.
419
 * class to get it supported.
420
 *
420
 *
421
 * @since 1.3
421
 * @since 1.3
422
 * @name NET_FTP_ERR_DIRLIST_UNSUPPORTED
422
 * @name NET_FTP_ERR_DIRLIST_UNSUPPORTED
423
 * @see Net_FTP::ls()
423
 * @see Net_FTP::ls()
424
 */
424
 */
425
define('NET_FTP_ERR_DIRLIST_UNSUPPORTED', -31);
425
define('NET_FTP_ERR_DIRLIST_UNSUPPORTED', -31);
426
 
426
 
427
/**
427
/**
428
 * Error code to indicate failed disconnecting
428
 * Error code to indicate failed disconnecting
429
 * This error code indicates, that disconnection was not possible.
429
 * This error code indicates, that disconnection was not possible.
430
 *
430
 *
431
 * @since 1.3
431
 * @since 1.3
432
 * @name NET_FTP_ERR_DISCONNECT_FAILED
432
 * @name NET_FTP_ERR_DISCONNECT_FAILED
433
 * @see Net_FTP::disconnect()
433
 * @see Net_FTP::disconnect()
434
 */
434
 */
435
define('NET_FTP_ERR_DISCONNECT_FAILED', -32);
435
define('NET_FTP_ERR_DISCONNECT_FAILED', -32);
436
 
436
 
437
/**
437
/**
438
 * Error code to indicate that the username you provided was invalid.
438
 * Error code to indicate that the username you provided was invalid.
439
 * Check that you provided a non-empty string as the username.
439
 * Check that you provided a non-empty string as the username.
440
 *
440
 *
441
 * @since 1.3
441
 * @since 1.3
442
 * @name NET_FTP_ERR_USERNAMENOSTRING
442
 * @name NET_FTP_ERR_USERNAMENOSTRING
443
 * @see Net_FTP::setUsername()
443
 * @see Net_FTP::setUsername()
444
 */
444
 */
445
define('NET_FTP_ERR_USERNAMENOSTRING', -33);
445
define('NET_FTP_ERR_USERNAMENOSTRING', -33);
446
 
446
 
447
/**
447
/**
448
 * Error code to indicate that the username you provided was invalid.
448
 * Error code to indicate that the username you provided was invalid.
449
 * Check that you provided a non-empty string as the username.
449
 * Check that you provided a non-empty string as the username.
450
 *
450
 *
451
 * @since 1.3
451
 * @since 1.3
452
 * @name NET_FTP_ERR_PASSWORDNOSTRING
452
 * @name NET_FTP_ERR_PASSWORDNOSTRING
453
 * @see Net_FTP::setPassword()
453
 * @see Net_FTP::setPassword()
454
 */
454
 */
455
define('NET_FTP_ERR_PASSWORDNOSTRING', -33);
455
define('NET_FTP_ERR_PASSWORDNOSTRING', -33);
456
 
456
 
457
/**
457
/**
458
 * Class for comfortable FTP-communication
458
 * Class for comfortable FTP-communication
459
 *
459
 *
460
 * This class provides comfortable communication with FTP-servers. You may do everything
460
 * This class provides comfortable communication with FTP-servers. You may do everything
461
 * enabled by the PHP-FTP-extension and further functionalities, like recursive-deletion,
461
 * enabled by the PHP-FTP-extension and further functionalities, like recursive-deletion,
462
 * -up- and -download. Another feature is to create directories recursively.
462
 * -up- and -download. Another feature is to create directories recursively.
463
 *
463
 *
464
 * @license   http://www.php.net/license/3_0.txt  PHP License 3.0
464
 * @license   http://www.php.net/license/3_0.txt  PHP License 3.0
465
 * @category  Networking
465
 * @category  Networking
466
 * @package   FTP
466
 * @package   FTP
467
 * @author    Tobias Schlitt <toby@php.net>
467
 * @author    Tobias Schlitt <toby@php.net>
468
 * @copyright 1997-2005 The PHP Group
468
 * @copyright 1997-2005 The PHP Group
469
 * @version   Release: 1.3.0
469
 * @version   Release: @package_version@
470
 * @link      http://pear.php.net/package/Net_FTP
470
 * @link      http://pear.php.net/package/Net_FTP
471
 * @since     0.0.1
471
 * @since     0.0.1
472
 * @access    public
472
 * @access    public
473
 */
473
 */
474
class Net_FTP extends PEAR 
474
class Net_FTP extends PEAR 
475
{
475
{
476
    /**
476
    /**
477
     * The host to connect to
477
     * The host to connect to
478
     *
478
     *
479
     * @access  private
479
     * @access  private
480
     * @var     string
480
     * @var     string
481
     */
481
     */
482
    
482
    
483
    var $_hostname;
483
    var $_hostname;
484
 
484
 
485
    /**
485
    /**
486
     * The port for ftp-connection (standard is 21)
486
     * The port for ftp-connection (standard is 21)
487
     *
487
     *
488
     * @access  private
488
     * @access  private
489
     * @var     int
489
     * @var     int
490
     */
490
     */
491
    
491
    
492
    var $_port = 21;
492
    var $_port = 21;
493
 
493
 
494
    /**
494
    /**
495
     * The username for login
495
     * The username for login
496
     *
496
     *
497
     * @access  private
497
     * @access  private
498
     * @var     string
498
     * @var     string
499
     */
499
     */
500
    
500
    
501
    var $_username;
501
    var $_username;
502
 
502
 
503
    /**
503
    /**
504
     * The password for login
504
     * The password for login
505
     *
505
     *
506
     * @access  private
506
     * @access  private
507
     * @var     string
507
     * @var     string
508
     */
508
     */
509
    
509
    
510
    var $_password;
510
    var $_password;
511
 
511
 
512
    /**
512
    /**
513
     * Determine whether to use passive-mode (true) or active-mode (false)
513
     * Determine whether to use passive-mode (true) or active-mode (false)
514
     *
514
     *
515
     * @access  private
515
     * @access  private
516
     * @var     bool
516
     * @var     bool
517
     */
517
     */
518
    
518
    
519
    var $_passv;
519
    var $_passv;
520
 
520
 
521
    /**
521
    /**
522
     * The standard mode for ftp-transfer
522
     * The standard mode for ftp-transfer
523
     *
523
     *
524
     * @access  private
524
     * @access  private
525
     * @var     int
525
     * @var     int
526
     */
526
     */
527
    
527
    
528
    var $_mode = FTP_BINARY;
528
    var $_mode = FTP_BINARY;
529
 
529
 
530
    /**
530
    /**
531
     * This holds the handle for the ftp-connection
531
     * This holds the handle for the ftp-connection
532
     *
532
     *
533
     * @access  private
533
     * @access  private
534
     * @var     resource
534
     * @var     resource
535
     */
535
     */
536
    
536
    
537
    var $_handle;
537
    var $_handle;
538
 
538
 
539
    /**
539
    /**
540
     * Contains the timeout for FTP operations
540
     * Contains the timeout for FTP operations
541
     *
541
     *
542
     * @access  private
542
     * @access  private
543
     * @var     int
543
     * @var     int
544
     * @since   1.3
544
     * @since   1.3
545
     */
545
     */
546
    
546
    
547
    var $_timeout = 90;
547
    var $_timeout = 90;
548
        
548
        
549
    /**
549
    /**
550
     * Saves file-extensions for ascii- and binary-mode
550
     * Saves file-extensions for ascii- and binary-mode
551
     *
551
     *
552
     * The array contains 2 sub-arrays ("ascii" and "binary"), which both contain
552
     * The array contains 2 sub-arrays ("ascii" and "binary"), which both contain
553
     * file-extensions without the "." (".php" = "php").
553
     * file-extensions without the "." (".php" = "php").
554
     *
554
     *
555
     * @access  private
555
     * @access  private
556
     * @var     array
556
     * @var     array
557
     */
557
     */
558
    
558
    
559
    var $_file_extensions;
559
    var $_file_extensions;
560
 
560
 
561
    /**
561
    /**
562
     * ls match
562
     * ls match
563
     * Matches the ls entries against a regex and maps the resulting array to speaking names
563
     * Matches the ls entries against a regex and maps the resulting array to speaking names
564
     *
564
     *
565
     * @access  private
565
     * @access  private
566
     * @var     array
566
     * @var     array
567
     * @since   1.3
567
     * @since   1.3
568
     */
568
     */
569
    
569
    
570
    var $_ls_match = array(
570
    var $_ls_match = array(
571
        'unix'    => array(
571
        'unix'    => array(
572
            'pattern' => '/(?:(d)|.)([rwxt-]+)\s+(\w+)\s+(\w+)\s+(\w+)\s+(\w+)\s+(\S+\s+\S+\s+\S+)\s+(.+)/',
572
            'pattern' => '/(?:(d)|.)([rwxt-]+)\s+(\w+)\s+([\w\d-]+)\s+([\w\d-]+)\s+(\w+)\s+(\S+\s+\S+\s+\S+)\s+(.+)/',
573
            'map'     => array('name'=>8,'size'=>6,'rights'=>2,'user'=>4,'group'=>5,
573
            'map'     => array(
-
 
574
                'is_dir'        => 1,
-
 
575
                'rights'        => 2,
574
                              'files_inside'=>3,'date'=>7,'is_dir'=>1)
576
                'files_inside'  => 3,
-
 
577
                'user'          => 4,
-
 
578
                'group'         => 5,
-
 
579
                'size'          => 6,
-
 
580
                'date'          => 7,
-
 
581
                'name'          => 8,
-
 
582
            )
575
        ),
583
        ),
576
        'windows' => array(
584
        'windows' => array(
577
            'pattern' => '/(.+)\s+(.+)\s+((<DIR>)|[0-9]+)\s+(.+)/',
585
            'pattern' => '/(.+)\s+(.+)\s+((<DIR>)|[0-9]+)\s+(.+)/',
578
            'map'     => array('name'=>5,'date'=>1,'is_dir'=>3)
586
            'map'     => array(
-
 
587
                'name'   => 5,
-
 
588
                'date'   => 1,
-
 
589
                'size'   => 3,
-
 
590
                'is_dir' => 4,
-
 
591
            )
579
        )
592
        )
580
    );
593
    );
581
    
594
    
582
    /**
595
    /**
583
     * matcher
596
     * matcher
584
     * Stores the matcher for the current connection
597
     * Stores the matcher for the current connection
585
     *
598
     *
586
     * @access  private
599
     * @access  private
587
     * @var     array
600
     * @var     array
588
     * @since   1.3
601
     * @since   1.3
589
     */
602
     */
590
    var $_matcher = null;
603
    var $_matcher = null;
591
    
604
    
592
    /**
605
    /**
593
     * Holds all Net_FTP_Observer objects 
606
     * Holds all Net_FTP_Observer objects 
594
     * that wish to be notified of new messages.
607
     * that wish to be notified of new messages.
595
     *
608
     *
596
     * @var     array
609
     * @var     array
597
     * @access  private
610
     * @access  private
598
     * @since   1.3
611
     * @since   1.3
599
     */
612
     */
600
    
613
    
601
    var $_listeners = array();
614
    var $_listeners = array();
602
 
615
 
603
    /**
616
    /**
604
     * This generates a new FTP-Object. The FTP-connection will not be established, yet.
617
     * This generates a new FTP-Object. The FTP-connection will not be established, yet.
605
     * You can leave $host and $port blank, if you want. The $host will not be set
618
     * You can leave $host and $port blank, if you want. The $host will not be set
606
     * and the $port will be left at 21. You have to set the $host manualy before
619
     * and the $port will be left at 21. You have to set the $host manualy before
607
     * trying to connect or with the connect() method.
620
     * trying to connect or with the connect() method.
608
     *
621
     *
609
     * @access  public
622
     * @access  public
610
     * @param   string $host    (optional) The hostname 
623
     * @param   string $host    (optional) The hostname 
611
     * @param   int    $port    (optional) The port
624
     * @param   int    $port    (optional) The port
612
     * @param   int    $timeout (optional) Sets the standard timeout
625
     * @param   int    $timeout (optional) Sets the standard timeout
613
     * @return  void
626
     * @return  void
614
     * @see     Net_FTP::setHostname(), Net_FTP::setPort(), Net_FTP::connect()
627
     * @see     Net_FTP::setHostname(), Net_FTP::setPort(), Net_FTP::connect()
615
     */
628
     */
616
    
629
    
617
    function Net_FTP($host = null, $port = null, $timeout = 90)
630
    function Net_FTP($host = null, $port = null, $timeout = 90)
618
    {
631
    {
619
        $this->PEAR();
632
        $this->PEAR();
620
        if (isset($host)) {
633
        if (isset($host)) {
621
            $this->setHostname($host);
634
            $this->setHostname($host);
622
        }
635
        }
623
        if (isset($port)) {
636
        if (isset($port)) {
624
            $this->setPort($port);
637
            $this->setPort($port);
625
        }
638
        }
626
        $this->_timeout = $timeout;
639
        $this->_timeout = $timeout;
627
        $this->_file_extensions[FTP_ASCII] = array();
640
        $this->_file_extensions[FTP_ASCII] = array();
628
        $this->_file_extensions[FTP_BINARY] = array();
641
        $this->_file_extensions[FTP_BINARY] = array();
629
    }
642
    }
630
 
643
 
631
    /**
644
    /**
632
     * This function generates the FTP-connection. You can optionally define a
645
     * This function generates the FTP-connection. You can optionally define a
633
     * hostname and/or a port. If you do so, this data is stored inside the object.
646
     * hostname and/or a port. If you do so, this data is stored inside the object.
634
     *
647
     *
635
     * @access  public
648
     * @access  public
636
     * @param   string $host    (optional) The Hostname
649
     * @param   string $host    (optional) The Hostname
637
     * @param   int    $port    (optional) The Port 
650
     * @param   int    $port    (optional) The Port 
638
     * @return  mixed           True on success, otherwise PEAR::Error
651
     * @return  mixed           True on success, otherwise PEAR::Error
639
     * @see     NET_FTP_ERR_CONNECT_FAILED
652
     * @see     NET_FTP_ERR_CONNECT_FAILED
640
     */
653
     */
641
    
654
    
642
    function connect($host = null, $port = null)
655
    function connect($host = null, $port = null)
643
    {
656
    {
644
        $this->_matcher = null;
657
        $this->_matcher = null;
645
        if (isset($host)) {
658
        if (isset($host)) {
646
            $this->setHostname($host);
659
            $this->setHostname($host);
647
        }
660
        }
648
        if (isset($port)) {
661
        if (isset($port)) {
649
            $this->setPort($port);
662
            $this->setPort($port);
650
        }
663
        }
651
        $handle = @ftp_connect($this->getHostname(), $this->getPort(), $this->_timeout);
664
        $handle = @ftp_connect($this->getHostname(), $this->getPort(), $this->_timeout);
652
        if (!$handle) {
665
        if (!$handle) {
653
            return $this->raiseError("Connection to host failed", NET_FTP_ERR_CONNECT_FAILED);
666
            return $this->raiseError("Connection to host failed", NET_FTP_ERR_CONNECT_FAILED);
654
        } else {
667
        } else {
655
            $this->_handle =& $handle;
668
            $this->_handle =& $handle;
656
            return true;
669
            return true;
657
        }
670
        }
658
    }
671
    }
659
 
672
 
660
    /**
673
    /**
661
     * This function close the FTP-connection
674
     * This function close the FTP-connection
662
     *
675
     *
663
     * @access  public
676
     * @access  public
664
     * @return  bool|PEAR_Error Returns true on success, PEAR_Error on failure
677
     * @return  bool|PEAR_Error Returns true on success, PEAR_Error on failure
665
     */
678
     */
666
    
679
    
667
    function disconnect()
680
    function disconnect()
668
    {
681
    {
669
        $res = @ftp_close($this->_handle);
682
        $res = @ftp_close($this->_handle);
670
        if (!$res) {
683
        if (!$res) {
671
            return PEAR::raiseError('Disconnect failed.', NET_FTP_ERR_DISCONNECT_FAILED);
684
            return PEAR::raiseError('Disconnect failed.', NET_FTP_ERR_DISCONNECT_FAILED);
672
        }
685
        }
673
        return true;
686
        return true;
674
    }
687
    }
675
 
688
 
676
    /**
689
    /**
677
     * This logges you into the ftp-server. You are free to specify username and password
690
     * This logges you into the ftp-server. You are free to specify username and password
678
     * in this method. If you specify it, the values will be taken into the corresponding
691
     * in this method. If you specify it, the values will be taken into the corresponding
679
     * attributes, if do not specify, the attributes are taken.
692
     * attributes, if do not specify, the attributes are taken.
680
     *
693
     *
681
     * @access  public
694
     * @access  public
682
     * @param   string $username  (optional) The username to use 
695
     * @param   string $username  (optional) The username to use 
683
     * @param   string $password  (optional) The password to use
696
     * @param   string $password  (optional) The password to use
684
     * @return  mixed             True on success, otherwise PEAR::Error
697
     * @return  mixed             True on success, otherwise PEAR::Error
685
     * @see     NET_FTP_ERR_LOGIN_FAILED
698
     * @see     NET_FTP_ERR_LOGIN_FAILED
686
     */
699
     */
687
    
700
    
688
    function login($username = null, $password = null)
701
    function login($username = null, $password = null)
689
    {
702
    {
690
        if (!isset($username)) {
703
        if (!isset($username)) {
691
            $username = $this->getUsername();
704
            $username = $this->getUsername();
692
        } else {
705
        } else {
693
            $this->setUsername($username);
706
            $this->setUsername($username);
694
        }
707
        }
695
 
708
 
696
        if (!isset($password)) {
709
        if (!isset($password)) {
697
            $password = $this->getPassword();
710
            $password = $this->getPassword();
698
        } else {
711
        } else {
699
            $this->setPassword($password);
712
            $this->setPassword($password);
700
        }
713
        }
701
 
714
 
702
        $res = @ftp_login($this->_handle, $username, $password);
715
        $res = @ftp_login($this->_handle, $username, $password);
703
 
716
 
704
        if (!$res) {
717
        if (!$res) {
705
            return $this->raiseError("Unable to login", NET_FTP_ERR_LOGIN_FAILED);
718
            return $this->raiseError("Unable to login", NET_FTP_ERR_LOGIN_FAILED);
706
        } else {
719
        } else {
707
            return true;
720
            return true;
708
        }
721
        }
709
    }
722
    }
710
 
723
 
711
    /**
724
    /**
712
     * This changes the currently used directory. You can use either an absolute
725
     * This changes the currently used directory. You can use either an absolute
713
     * directory-path (e.g. "/home/blah") or a relative one (e.g. "../test").
726
     * directory-path (e.g. "/home/blah") or a relative one (e.g. "../test").
714
     *
727
     *
715
     * @access  public
728
     * @access  public
716
     * @param   string $dir  The directory to go to.
729
     * @param   string $dir  The directory to go to.
717
     * @return  mixed        True on success, otherwise PEAR::Error
730
     * @return  mixed        True on success, otherwise PEAR::Error
718
     * @see     NET_FTP_ERR_DIRCHANGE_FAILED
731
     * @see     NET_FTP_ERR_DIRCHANGE_FAILED
719
     */
732
     */
720
    
733
    
721
    function cd($dir)
734
    function cd($dir)
722
    {
735
    {
723
        $erg = @ftp_chdir($this->_handle, $dir);
736
        $erg = @ftp_chdir($this->_handle, $dir);
724
        if (!$erg) {
737
        if (!$erg) {
725
            return $this->raiseError("Directory change failed", NET_FTP_ERR_DIRCHANGE_FAILED);
738
            return $this->raiseError("Directory change failed", NET_FTP_ERR_DIRCHANGE_FAILED);
726
        } else {
739
        } else {
727
            return true;
740
            return true;
728
        }
741
        }
729
    }
742
    }
730
 
743
 
731
    /**
744
    /**
732
     * Show's you the actual path on the server
745
     * Show's you the actual path on the server
733
     * This function questions the ftp-handle for the actual selected path and returns it.
746
     * This function questions the ftp-handle for the actual selected path and returns it.
734
     *
747
     *
735
     * @access  public
748
     * @access  public
736
     * @return  mixed        The actual path or PEAR::Error
749
     * @return  mixed        The actual path or PEAR::Error
737
     * @see     NET_FTP_ERR_DETERMINEPATH_FAILED
750
     * @see     NET_FTP_ERR_DETERMINEPATH_FAILED
738
     */
751
     */
739
    
752
    
740
    function pwd()
753
    function pwd()
741
    {
754
    {
742
        $res = @ftp_pwd($this->_handle);
755
        $res = @ftp_pwd($this->_handle);
743
        if (!$res) {
756
        if (!$res) {
744
            return $this->raiseError("Could not determine the actual path.", NET_FTP_ERR_DETERMINEPATH_FAILED);
757
            return $this->raiseError("Could not determine the actual path.", NET_FTP_ERR_DETERMINEPATH_FAILED);
745
        } else {
758
        } else {
746
            return $res;
759
            return $res;
747
        }
760
        }
748
    }
761
    }
749
 
762
 
750
    /**
763
    /**
751
     * This works similar to the mkdir-command on your local machine. You can either give
764
     * This works similar to the mkdir-command on your local machine. You can either give
752
     * it an absolute or relative path. The relative path will be completed with the actual
765
     * it an absolute or relative path. The relative path will be completed with the actual
753
     * selected server-path. (see: pwd())
766
     * selected server-path. (see: pwd())
754
     *
767
     *
755
     * @access  public
768
     * @access  public
756
     * @param   string $dir       Absolute or relative dir-path
769
     * @param   string $dir       Absolute or relative dir-path
757
     * @param   bool   $recursive (optional) Create all needed directories
770
     * @param   bool   $recursive (optional) Create all needed directories
758
     * @return  mixed             True on success, otherwise PEAR::Error
771
     * @return  mixed             True on success, otherwise PEAR::Error
759
     * @see     NET_FTP_ERR_CREATEDIR_FAILED
772
     * @see     NET_FTP_ERR_CREATEDIR_FAILED
760
     */
773
     */
761
    
774
    
762
    function mkdir($dir, $recursive = false)
775
    function mkdir($dir, $recursive = false)
763
    {
776
    {
764
        $dir = $this->_construct_path($dir);
777
        $dir = $this->_construct_path($dir);
765
        $savedir = $this->pwd();
778
        $savedir = $this->pwd();
766
        $this->pushErrorHandling(PEAR_ERROR_RETURN);
779
        $this->pushErrorHandling(PEAR_ERROR_RETURN);
767
        $e = $this->cd($dir);
780
        $e = $this->cd($dir);
768
        $this->popErrorHandling();
781
        $this->popErrorHandling();
769
        if ($e === true) {
782
        if ($e === true) {
770
            $this->cd($savedir);
783
            $this->cd($savedir);
771
            return true;
784
            return true;
772
        }
785
        }
773
        $this->cd($savedir);
786
        $this->cd($savedir);
774
        if ($recursive === false){
787
        if ($recursive === false){
775
            $res = @ftp_mkdir($this->_handle, $dir);
788
            $res = @ftp_mkdir($this->_handle, $dir);
776
            if (!$res) {
789
            if (!$res) {
777
                return $this->raiseError("Creation of '$dir' failed", NET_FTP_ERR_CREATEDIR_FAILED);
790
                return $this->raiseError("Creation of '$dir' failed", NET_FTP_ERR_CREATEDIR_FAILED);
778
            } else {
791
            } else {
779
                return true;
792
                return true;
780
            }
793
            }
781
        } else {
794
        } else {
782
            if(strpos($dir, '/') === false) {
795
            if(strpos($dir, '/') === false) {
783
                return $this->mkdir($dir,false);
796
                return $this->mkdir($dir,false);
784
            }
797
            }
785
            $pos = 0;
798
            $pos = 0;
786
            $res = $this->mkdir(dirname($dir), true);
799
            $res = $this->mkdir(dirname($dir), true);
787
            $res = $this->mkdir($dir, false);
800
            $res = $this->mkdir($dir, false);
788
            if ($res !== true) {
801
            if ($res !== true) {
789
                return $res;
802
                return $res;
790
            }
803
            }
791
            return true;
804
            return true;
792
        }
805
        }
793
    }
806
    }
794
 
807
 
795
    /**
808
    /**
796
     * This method tries executing a command on the ftp, using SITE EXEC.
809
     * This method tries executing a command on the ftp, using SITE EXEC.
797
     *
810
     *
798
     * @access  public
811
     * @access  public
799
     * @param   string $command The command to execute
812
     * @param   string $command The command to execute
800
     * @return  mixed           The result of the command (if successfull), otherwise PEAR::Error
813
     * @return  mixed           The result of the command (if successfull), otherwise PEAR::Error
801
     * @see     NET_FTP_ERR_EXEC_FAILED
814
     * @see     NET_FTP_ERR_EXEC_FAILED
802
     */
815
     */
803
    
816
    
804
    function execute($command)
817
    function execute($command)
805
    {
818
    {
806
        $res = @ftp_exec($this->_handle, $command);
819
        $res = @ftp_exec($this->_handle, $command);
807
        if (!$res) {
820
        if (!$res) {
808
            return $this->raiseError("Execution of command '$command' failed.", NET_FTP_ERR_EXEC_FAILED);
821
            return $this->raiseError("Execution of command '$command' failed.", NET_FTP_ERR_EXEC_FAILED);
809
        } else {
822
        } else {
810
            return $res;
823
            return $res;
811
        }
824
        }
812
    }
825
    }
813
 
826
 
814
    /**
827
    /**
815
     * Execute a SITE command on the server
828
     * Execute a SITE command on the server
816
     * This method tries to execute a SITE command on the ftp server.
829
     * This method tries to execute a SITE command on the ftp server.
817
     *
830
     *
818
     * @access  public
831
     * @access  public
819
     * @param   string $command   The command with parameters to execute
832
     * @param   string $command   The command with parameters to execute
820
     * @return  mixed             True if successful, otherwise PEAR::Error
833
     * @return  mixed             True if successful, otherwise PEAR::Error
821
     * @see     NET_FTP_ERR_SITE_FAILED
834
     * @see     NET_FTP_ERR_SITE_FAILED
822
     */
835
     */
823
    
836
    
824
    function site($command)
837
    function site($command)
825
    {
838
    {
826
        $res = @ftp_site($this->_handle, $command);
839
        $res = @ftp_site($this->_handle, $command);
827
        if (!$res) {
840
        if (!$res) {
828
            return $this->raiseError("Execution of SITE command '$command' failed.", NET_FTP_ERR_SITE_FAILED);
841
            return $this->raiseError("Execution of SITE command '$command' failed.", NET_FTP_ERR_SITE_FAILED);
829
        } else {
842
        } else {
830
            return $res;
843
            return $res;
831
        }
844
        }
832
    }
845
    }
833
 
846
 
834
    /**
847
    /**
835
     * This method will try to chmod the file specified on the server
848
     * This method will try to chmod the file specified on the server
836
     * Currently, you must give a number as the the permission argument (777 or
849
     * Currently, you must give a number as the the permission argument (777 or
837
     * similar). The file can be either a relative or absolute path.
850
     * similar). The file can be either a relative or absolute path.
838
     * NOTE: Some servers do not support this feature. In that case, you will
851
     * NOTE: Some servers do not support this feature. In that case, you will
839
     * get a PEAR error object returned. If successful, the method returns true
852
     * get a PEAR error object returned. If successful, the method returns true
840
     *
853
     *
841
     * @access  public
854
     * @access  public
842
     * @param   mixed   $target        The file or array of files to set permissions for
855
     * @param   mixed   $target        The file or array of files to set permissions for
843
     * @param   integer $permissions   The mode to set the file permissions to
856
     * @param   integer $permissions   The mode to set the file permissions to
844
     * @return  mixed                  True if successful, otherwise PEAR::Error
857
     * @return  mixed                  True if successful, otherwise PEAR::Error
845
     * @see     NET_FTP_ERR_CHMOD_FAILED
858
     * @see     NET_FTP_ERR_CHMOD_FAILED
846
     */
859
     */
847
    
860
    
848
    function chmod($target, $permissions)
861
    function chmod($target, $permissions)
849
    {
862
    {
850
        // If $target is an array: Loop through it.
863
        // If $target is an array: Loop through it.
851
        if (is_array($target)) {
864
        if (is_array($target)) {
852
 
865
 
853
            for ($i = 0; $i < count($target); $i++) {
866
            for ($i = 0; $i < count($target); $i++) {
854
                $res = $this->chmod($target[$i], $permissions);
867
                $res = $this->chmod($target[$i], $permissions);
855
                if (PEAR::isError($res)) {
868
                if (PEAR::isError($res)) {
856
                    return $res;
869
                    return $res;
857
                } // end if isError
870
                } // end if isError
858
            } // end for i < count($target)
871
            } // end for i < count($target)
859
 
872
 
860
        } else {
873
        } else {
861
 
874
 
862
            $res = $this->site("CHMOD " . $permissions . " " . $target);
875
            $res = $this->site("CHMOD " . $permissions . " " . $target);
863
            if (!$res) {
876
            if (!$res) {
864
                return PEAR::raiseError("CHMOD " . $permissions . " " . $target . " failed", NET_FTP_ERR_CHMOD_FAILED);
877
                return PEAR::raiseError("CHMOD " . $permissions . " " . $target . " failed", NET_FTP_ERR_CHMOD_FAILED);
865
            } else {
878
            } else {
866
                return $res;
879
                return $res;
867
            }
880
            }
868
 
881
 
869
        } // end if is_array
882
        } // end if is_array
870
 
883
 
871
    } // end method chmod
884
    } // end method chmod
872
 
885
 
873
    /**
886
    /**
874
     * This method will try to chmod a folder and all of its contents
887
     * This method will try to chmod a folder and all of its contents
875
     * on the server. The target argument must be a folder or an array of folders
888
     * on the server. The target argument must be a folder or an array of folders
876
     * and the permissions argument have to be an integer (i.e. 777).
889
     * and the permissions argument have to be an integer (i.e. 777).
877
     * The file can be either a relative or absolute path.
890
     * The file can be either a relative or absolute path.
878
     * NOTE: Some servers do not support this feature. In that case, you
891
     * NOTE: Some servers do not support this feature. In that case, you
879
     * will get a PEAR error object returned. If successful, the method
892
     * will get a PEAR error object returned. If successful, the method
880
     * returns true
893
     * returns true
881
     *
894
     *
882
     * @access  public
895
     * @access  public
883
     * @param   mixed   $target        The folder or array of folders to
896
     * @param   mixed   $target        The folder or array of folders to
884
     *                                 set permissions for
897
     *                                 set permissions for
885
     * @param   integer $permissions   The mode to set the folder
898
     * @param   integer $permissions   The mode to set the folder
886
     *                                 and file permissions to
899
     *                                 and file permissions to
887
     * @return  mixed                  True if successful, otherwise PEAR::Error
900
     * @return  mixed                  True if successful, otherwise PEAR::Error
888
     * @see     NET_FTP_ERR_CHMOD_FAILED, NET_FTP_ERR_DETERMINEPATH_FAILED, NET_FTP_ERR_RAWDIRLIST_FAILED, NET_FTP_ERR_DIRLIST_UNSUPPORTED
901
     * @see     NET_FTP_ERR_CHMOD_FAILED, NET_FTP_ERR_DETERMINEPATH_FAILED, NET_FTP_ERR_RAWDIRLIST_FAILED, NET_FTP_ERR_DIRLIST_UNSUPPORTED
889
     */
902
     */
890
    
903
    
891
    function chmodRecursive($target, $permissions)
904
    function chmodRecursive($target, $permissions)
892
    {
905
    {
893
        static $dir_permissions;
906
        static $dir_permissions;
894
 
907
 
895
        if(!isset($dir_permissions)){ // Making directory specific permissions
908
        if(!isset($dir_permissions)){ // Making directory specific permissions
896
            $dir_permissions = $this->_makeDirPermissions($permissions);
909
            $dir_permissions = $this->_makeDirPermissions($permissions);
897
        }
910
        }
898
 
911
 
899
        // If $target is an array: Loop through it
912
        // If $target is an array: Loop through it
900
        if (is_array($target)) {
913
        if (is_array($target)) {
901
 
914
 
902
            for ($i = 0; $i < count($target); $i++) {
915
            for ($i = 0; $i < count($target); $i++) {
903
                $res = $this->chmodRecursive($target[$i], $permissions);
916
                $res = $this->chmodRecursive($target[$i], $permissions);
904
                if (PEAR::isError($res)) {
917
                if (PEAR::isError($res)) {
905
                    return $res;
918
                    return $res;
906
                } // end if isError
919
                } // end if isError
907
            } // end for i < count($target)
920
            } // end for i < count($target)
908
 
921
 
909
        } else {
922
        } else {
910
 
923
 
911
            $remote_path = $this->_construct_path($target);
924
            $remote_path = $this->_construct_path($target);
912
 
925
 
913
            // Chmod the directory itself
926
            // Chmod the directory itself
914
            $result = $this->chmod($remote_path, $dir_permissions);
927
            $result = $this->chmod($remote_path, $dir_permissions);
915
 
928
 
916
            if (PEAR::isError($result)) {
929
            if (PEAR::isError($result)) {
917
                return $result;
930
                return $result;
918
            }
931
            }
919
 
932
 
920
            // If $remote_path last character is not a slash, add one
933
            // If $remote_path last character is not a slash, add one
921
            if (substr($remote_path, strlen($remote_path)-1) != "/") {
934
            if (substr($remote_path, strlen($remote_path)-1) != "/") {
922
 
935
 
923
                $remote_path .= "/";
936
                $remote_path .= "/";
924
            }
937
            }
925
 
938
 
926
            $dir_list = array();
939
            $dir_list = array();
927
            $mode = NET_FTP_DIRS_ONLY;
940
            $mode = NET_FTP_DIRS_ONLY;
928
            $dir_list = $this->ls($remote_path, $mode);
941
            $dir_list = $this->ls($remote_path, $mode);
929
            foreach ($dir_list as $dir_entry) {
942
            foreach ($dir_list as $dir_entry) {
-
 
943
                if ($dir_entry == '.' || $dir_entry == '..') {;
-
 
944
                    continue;
-
 
945
                }
930
 
946
                
931
                $remote_path_new = $remote_path.$dir_entry["name"]."/";
947
                $remote_path_new = $remote_path.$dir_entry["name"]."/";
932
 
948
 
933
                // Chmod the directory we're about to enter
949
                // Chmod the directory we're about to enter
934
                $result = $this->chmod($remote_path_new, $dir_permissions);
950
                $result = $this->chmod($remote_path_new, $dir_permissions);
935
 
951
 
936
                if (PEAR::isError($result)) {
952
                if (PEAR::isError($result)) {
937
                    return $result;
953
                    return $result;
938
                }
954
                }
939
 
955
 
940
                $result = $this->chmodRecursive($remote_path_new, $permissions);
956
                $result = $this->chmodRecursive($remote_path_new, $permissions);
941
 
957
 
942
                if (PEAR::isError($result)) {
958
                if (PEAR::isError($result)) {
943
                    return $result;
959
                    return $result;
944
                }
960
                }
945
 
961
 
946
            } // end foreach dir_list as dir_entry
962
            } // end foreach dir_list as dir_entry
947
 
963
 
948
            $file_list = array();
964
            $file_list = array();
949
            $mode = NET_FTP_FILES_ONLY;
965
            $mode = NET_FTP_FILES_ONLY;
950
            $file_list = $this->ls($remote_path, $mode);
966
            $file_list = $this->ls($remote_path, $mode);
951
 
967
 
952
            foreach ($file_list as $file_entry) {
968
            foreach ($file_list as $file_entry) {
953
 
969
 
954
                $remote_file = $remote_path.$file_entry["name"];
970
                $remote_file = $remote_path.$file_entry["name"];
955
 
971
 
956
                $result = $this->chmod($remote_file, $permissions);
972
                $result = $this->chmod($remote_file, $permissions);
957
 
973
 
958
                if (PEAR::isError($result)) {
974
                if (PEAR::isError($result)) {
959
                    return $result;
975
                    return $result;
960
                }
976
                }
961
 
977
 
962
            } // end foreach $file_list
978
            } // end foreach $file_list
963
 
979
 
964
        } // end if is_array
980
        } // end if is_array
965
 
981
 
966
        return true; // No errors
982
        return true; // No errors
967
 
983
 
968
    } // end method chmodRecursive
984
    } // end method chmodRecursive
969
 
985
 
970
    /**
986
    /**
971
     * Rename or move a file or a directory from the ftp-server
987
     * Rename or move a file or a directory from the ftp-server
972
     *
988
     *
973
     * @access  public
989
     * @access  public
974
     * @param   string $remote_from The remote file or directory original to rename or move
990
     * @param   string $remote_from The remote file or directory original to rename or move
975
     * @param   string $remote_to The remote file or directory final to rename or move
991
     * @param   string $remote_to The remote file or directory final to rename or move
976
     * @return  bool $res True on success, otherwise PEAR::Error
992
     * @return  bool $res True on success, otherwise PEAR::Error
977
     * @see     NET_FTP_ERR_RENAME_FAILED
993
     * @see     NET_FTP_ERR_RENAME_FAILED
978
     */
994
     */
979
 
995
 
980
    function rename ($remote_from, $remote_to) 
996
    function rename ($remote_from, $remote_to) 
981
    {
997
    {
982
        $res = @ftp_rename($this->_handle, $remote_from, $remote_to);
998
        $res = @ftp_rename($this->_handle, $remote_from, $remote_to);
983
        if(!$res) {
999
        if(!$res) {
984
            return $this->raiseError("Could not rename ".$remote_from." to ".$remote_to." !", NET_FTP_ERR_RENAME_FAILED);
1000
            return $this->raiseError("Could not rename ".$remote_from." to ".$remote_to." !", NET_FTP_ERR_RENAME_FAILED);
985
        }
1001
        }
986
        return true;
1002
        return true;
987
    }
1003
    }
988
 
1004
 
989
    /**
1005
    /**
990
     * This will return logical permissions mask for directory.
1006
     * This will return logical permissions mask for directory.
991
     * if directory have to be writeable it have also be executable
1007
     * if directory have to be writeable it have also be executable
992
     *
1008
     *
993
     * @access  private
1009
     * @access  private
994
     * @param   string $permissions    File permissions in digits for file (i.e. 666)
1010
     * @param   string $permissions    File permissions in digits for file (i.e. 666)
995
     * @return  string                 File permissions in digits for directory (i.e. 777)
1011
     * @return  string                 File permissions in digits for directory (i.e. 777)
996
     */
1012
     */
997
 
1013
 
998
    function _makeDirPermissions($permissions){
1014
    function _makeDirPermissions($permissions){
999
        $permissions = (string)$permissions;
1015
        $permissions = (string)$permissions;
1000
 
1016
 
1001
        for($i = 0; $i < strlen($permissions); $i++){ // going through (user, group, world)
1017
        for($i = 0; $i < strlen($permissions); $i++){ // going through (user, group, world)
1002
            if((int)$permissions{$i} & 4 and !((int)$permissions{$i} & 1)){ // Read permission is set
1018
            if((int)$permissions{$i} & 4 and !((int)$permissions{$i} & 1)){ // Read permission is set
1003
                                                                            // but execute not yet
1019
                                                                            // but execute not yet
1004
                (int)$permissions{$i} = (int)$permissions{$i} + 1; // Adding execute flag
1020
                (int)$permissions{$i} = (int)$permissions{$i} + 1; // Adding execute flag
1005
            }
1021
            }
1006
        }
1022
        }
1007
 
1023
 
1008
        return (string)$permissions;
1024
        return (string)$permissions;
1009
    }
1025
    }
1010
 
1026
 
1011
    /**
1027
    /**
1012
     * This will return the last modification-time of a file. You can either give this
1028
     * This will return the last modification-time of a file. You can either give this
1013
     * function a relative or an absolute path to the file to check.
1029
     * function a relative or an absolute path to the file to check.
1014
     * NOTE: Some servers will not support this feature and the function works
1030
     * NOTE: Some servers will not support this feature and the function works
1015
     * only on files, not directories! When successful,
1031
     * only on files, not directories! When successful,
1016
     * it will return the last modification-time as a unix-timestamp or, when $format is
1032
     * it will return the last modification-time as a unix-timestamp or, when $format is
1017
     * specified, a preformated timestring.
1033
     * specified, a preformated timestring.
1018
     *
1034
     *
1019
     * @access  public
1035
     * @access  public
1020
     * @param   string $file    The file to check
1036
     * @param   string $file    The file to check
1021
     * @param   string $format  (optional) The format to give the date back 
1037
     * @param   string $format  (optional) The format to give the date back 
1022
     *                          if not set, it will return a Unix timestamp
1038
     *                          if not set, it will return a Unix timestamp
1023
     * @return  mixed           Unix timestamp, a preformated date-string or PEAR::Error
1039
     * @return  mixed           Unix timestamp, a preformated date-string or PEAR::Error
1024
     * @see     NET_FTP_ERR_MDTMDIR_UNSUPPORTED, NET_FTP_ERR_MDTM_FAILED, NET_FTP_ERR_DATEFORMAT_FAILED
1040
     * @see     NET_FTP_ERR_MDTMDIR_UNSUPPORTED, NET_FTP_ERR_MDTM_FAILED, NET_FTP_ERR_DATEFORMAT_FAILED
1025
     */
1041
     */
1026
    
1042
    
1027
    function mdtm($file, $format = null)
1043
    function mdtm($file, $format = null)
1028
    {
1044
    {
1029
        $file = $this->_construct_path($file);
1045
        $file = $this->_construct_path($file);
1030
        if ($this->_check_dir($file)) {
1046
        if ($this->_check_dir($file)) {
1031
            return $this->raiseError("Filename '$file' seems to be a directory.", NET_FTP_ERR_MDTMDIR_UNSUPPORTED);
1047
            return $this->raiseError("Filename '$file' seems to be a directory.", NET_FTP_ERR_MDTMDIR_UNSUPPORTED);
1032
        }
1048
        }
1033
        $res = @ftp_mdtm($this->_handle, $file);
1049
        $res = @ftp_mdtm($this->_handle, $file);
1034
        if ($res == -1) {
1050
        if ($res == -1) {
1035
            return $this->raiseError("Could not get last-modification-date of '$file'.", NET_FTP_ERR_MDTM_FAILED);
1051
            return $this->raiseError("Could not get last-modification-date of '$file'.", NET_FTP_ERR_MDTM_FAILED);
1036
        }
1052
        }
1037
        if (isset($format)) {
1053
        if (isset($format)) {
1038
            $res = date($format, $res);
1054
            $res = date($format, $res);
1039
            if (!$res) {
1055
            if (!$res) {
1040
                return $this->raiseError("Date-format failed on timestamp '$res'.", NET_FTP_ERR_DATEFORMAT_FAILED);
1056
                return $this->raiseError("Date-format failed on timestamp '$res'.", NET_FTP_ERR_DATEFORMAT_FAILED);
1041
            }
1057
            }
1042
        }
1058
        }
1043
        return $res;
1059
        return $res;
1044
    }
1060
    }
1045
 
1061
 
1046
    /**
1062
    /**
1047
     * This will return the size of a given file in bytes. You can either give this function
1063
     * This will return the size of a given file in bytes. You can either give this function
1048
     * a relative or an absolute file-path. NOTE: Some servers do not support this feature!
1064
     * a relative or an absolute file-path. NOTE: Some servers do not support this feature!
1049
     *
1065
     *
1050
     * @access  public
1066
     * @access  public
1051
     * @param   string $file   The file to check
1067
     * @param   string $file   The file to check
1052
     * @return  mixed          Size in bytes or PEAR::Error
1068
     * @return  mixed          Size in bytes or PEAR::Error
1053
     * @see     NET_FTP_ERR_SIZE_FAILED
1069
     * @see     NET_FTP_ERR_SIZE_FAILED
1054
     */
1070
     */
1055
    
1071
    
1056
    function size($file)
1072
    function size($file)
1057
    {
1073
    {
1058
        $file = $this->_construct_path($file);
1074
        $file = $this->_construct_path($file);
1059
        $res = @ftp_size($this->_handle, $file);
1075
        $res = @ftp_size($this->_handle, $file);
1060
        if ($res == -1) {
1076
        if ($res == -1) {
1061
            return $this->raiseError("Could not determine filesize of '$file'.", NET_FTP_ERR_SIZE_FAILED);
1077
            return $this->raiseError("Could not determine filesize of '$file'.", NET_FTP_ERR_SIZE_FAILED);
1062
        } else {
1078
        } else {
1063
            return $res;
1079
            return $res;
1064
        }
1080
        }
1065
    }
1081
    }
1066
 
1082
 
1067
    /**
1083
    /**
1068
     * This method returns a directory-list of the current directory or given one.
1084
     * This method returns a directory-list of the current directory or given one.
1069
     * To display the current selected directory, simply set the first parameter to null
1085
     * To display the current selected directory, simply set the first parameter to null
1070
     * or leave it blank, if you do not want to use any other parameters.
1086
     * or leave it blank, if you do not want to use any other parameters.
1071
     * <BR><BR>
1087
     * <BR><BR>
1072
     * There are 4 different modes of listing directories. Either to list only
1088
     * There are 4 different modes of listing directories. Either to list only
1073
     * the files (using NET_FTP_FILES_ONLY), to list only directories (using
1089
     * the files (using NET_FTP_FILES_ONLY), to list only directories (using
1074
     * NET_FTP_DIRS_ONLY) or to show both (using NET_FTP_DIRS_FILES, which is default).
1090
     * NET_FTP_DIRS_ONLY) or to show both (using NET_FTP_DIRS_FILES, which is default).
1075
     * <BR><BR>
1091
     * <BR><BR>
1076
     * The 4th one is the NET_FTP_RAWLIST, which returns just the array created by the
1092
     * The 4th one is the NET_FTP_RAWLIST, which returns just the array created by the
1077
     * ftp_rawlist()-function build into PHP.
1093
     * ftp_rawlist()-function build into PHP.
1078
     * <BR><BR>
1094
     * <BR><BR>
1079
     * The other function-modes will return an array containing the requested data.
1095
     * The other function-modes will return an array containing the requested data.
1080
     * The files and dirs are listed in human-sorted order, but if you select
1096
     * The files and dirs are listed in human-sorted order, but if you select
1081
     * NET_FTP_DIRS_FILES the directories will be added above the files,
1097
     * NET_FTP_DIRS_FILES the directories will be added above the files,
1082
     * but although both sorted.
1098
     * but although both sorted.
1083
     * <BR><BR>
1099
     * <BR><BR>
1084
     * All elements in the arrays are associative arrays themselves. The have the following
1100
     * All elements in the arrays are associative arrays themselves. The have the following
1085
     * structure:
1101
     * structure:
1086
     * <BR><BR>
1102
     * <BR><BR>
1087
     * Dirs:<BR>
1103
     * Dirs:<BR>
1088
     *           ["name"]        =>  string The name of the directory<BR>
1104
     *           ["name"]        =>  string The name of the directory<BR>
1089
     *           ["rights"]      =>  string The rights of the directory (in style "rwxr-xr-x")<BR>
1105
     *           ["rights"]      =>  string The rights of the directory (in style "rwxr-xr-x")<BR>
1090
     *           ["user"]        =>  string The owner of the directory<BR>
1106
     *           ["user"]        =>  string The owner of the directory<BR>
1091
     *           ["group"]       =>  string The group-owner of the directory<BR>
1107
     *           ["group"]       =>  string The group-owner of the directory<BR>
1092
     *           ["files_inside"]=>  string The number of files/dirs inside the directory
1108
     *           ["files_inside"]=>  string The number of files/dirs inside the directory
1093
     *                                      excluding "." and ".."<BR>
1109
     *                                      excluding "." and ".."<BR>
1094
     *           ["date"]        =>  int The creation-date as Unix timestamp<BR>
1110
     *           ["date"]        =>  int The creation-date as Unix timestamp<BR>
1095
     *           ["is_dir"]      =>  bool true, cause this is a dir<BR>
1111
     *           ["is_dir"]      =>  bool true, cause this is a dir<BR>
1096
     * <BR><BR>
1112
     * <BR><BR>
1097
     * Files:<BR>
1113
     * Files:<BR>
1098
     *           ["name"]        =>  string The name of the file<BR>
1114
     *           ["name"]        =>  string The name of the file<BR>
1099
     *           ["size"]        =>  int Size in bytes<BR>
1115
     *           ["size"]        =>  int Size in bytes<BR>
1100
     *           ["rights"]      =>  string The rights of the file (in style "rwxr-xr-x")<BR>
1116
     *           ["rights"]      =>  string The rights of the file (in style "rwxr-xr-x")<BR>
1101
     *           ["user"]        =>  string The owner of the file<BR>
1117
     *           ["user"]        =>  string The owner of the file<BR>
1102
     *           ["group"]       =>  string The group-owner of the file<BR>
1118
     *           ["group"]       =>  string The group-owner of the file<BR>
1103
     *           ["date"]        =>  int The creation-date as Unix timestamp<BR>
1119
     *           ["date"]        =>  int The creation-date as Unix timestamp<BR>
1104
     *           ["is_dir"]      =>  bool false, cause this is a file<BR>
1120
     *           ["is_dir"]      =>  bool false, cause this is a file<BR>
1105
     *
1121
     *
1106
     * @access  public
1122
     * @access  public
1107
     * @param   string $dir   (optional) The directory to list or null, when listing the current directory.
1123
     * @param   string $dir   (optional) The directory to list or null, when listing the current directory.
1108
     * @param   int    $mode  (optional) The mode which types to list (files, directories or both).
1124
     * @param   int    $mode  (optional) The mode which types to list (files, directories or both).
1109
     * @return  mixed         The directory list as described above or PEAR::Error on failure.
1125
     * @return  mixed         The directory list as described above or PEAR::Error on failure.
1110
     * @see     NET_FTP_DIRS_FILES, NET_FTP_DIRS_ONLY, NET_FTP_FILES_ONLY, NET_FTP_RAWLIST, NET_FTP_ERR_DETERMINEPATH_FAILED, NET_FTP_ERR_RAWDIRLIST_FAILED, NET_FTP_ERR_DIRLIST_UNSUPPORTED
1126
     * @see     NET_FTP_DIRS_FILES, NET_FTP_DIRS_ONLY, NET_FTP_FILES_ONLY, NET_FTP_RAWLIST, NET_FTP_ERR_DETERMINEPATH_FAILED, NET_FTP_ERR_RAWDIRLIST_FAILED, NET_FTP_ERR_DIRLIST_UNSUPPORTED
1111
     */
1127
     */
1112
     
1128
     
1113
    function ls($dir = null, $mode = NET_FTP_DIRS_FILES)
1129
    function ls($dir = null, $mode = NET_FTP_DIRS_FILES)
1114
    {
1130
    {
1115
        if (!isset($dir)) {
1131
        if (!isset($dir)) {
1116
            $dir = @ftp_pwd($this->_handle);
1132
            $dir = @ftp_pwd($this->_handle);
1117
            if (!$dir) {
1133
            if (!$dir) {
1118
                return $this->raiseError("Could not retrieve current directory", NET_FTP_ERR_DETERMINEPATH_FAILED);
1134
                return $this->raiseError("Could not retrieve current directory", NET_FTP_ERR_DETERMINEPATH_FAILED);
1119
            }
1135
            }
1120
        }
1136
        }
1121
        if (($mode != NET_FTP_FILES_ONLY) && ($mode != NET_FTP_DIRS_ONLY) && ($mode != NET_FTP_RAWLIST)) {
1137
        if (($mode != NET_FTP_FILES_ONLY) && ($mode != NET_FTP_DIRS_ONLY) && ($mode != NET_FTP_RAWLIST)) {
1122
            $mode = NET_FTP_DIRS_FILES;
1138
            $mode = NET_FTP_DIRS_FILES;
1123
        }
1139
        }
1124
 
1140
 
1125
        switch ($mode) {
1141
        switch ($mode) {
1126
            case NET_FTP_DIRS_FILES:    $res = $this->_ls_both ( $dir );
1142
            case NET_FTP_DIRS_FILES:    $res = $this->_ls_both ( $dir );
1127
                                        break;
1143
                                        break;
1128
            case NET_FTP_DIRS_ONLY:     $res = $this->_ls_dirs ( $dir );
1144
            case NET_FTP_DIRS_ONLY:     $res = $this->_ls_dirs ( $dir );
1129
                                        break;
1145
                                        break;
1130
            case NET_FTP_FILES_ONLY:    $res = $this->_ls_files ( $dir );
1146
            case NET_FTP_FILES_ONLY:    $res = $this->_ls_files ( $dir );
1131
                                        break;
1147
                                        break;
1132
            case NET_FTP_RAWLIST:       $res = @ftp_rawlist($this->_handle, $dir);
1148
            case NET_FTP_RAWLIST:       $res = @ftp_rawlist($this->_handle, $dir);
1133
                                        break;
1149
                                        break;
1134
        }
1150
        }
1135
 
1151
 
1136
        return $res;
1152
        return $res;
1137
    }
1153
    }
1138
 
1154
 
1139
    /**
1155
    /**
1140
     * This method will delete the given file or directory ($path) from the server
1156
     * This method will delete the given file or directory ($path) from the server
1141
     * (maybe recursive).
1157
     * (maybe recursive).
1142
     *
1158
     *
1143
     * Whether the given string is a file or directory is only determined by the last
1159
     * Whether the given string is a file or directory is only determined by the last
1144
     * sign inside the string ("/" or not).
1160
     * sign inside the string ("/" or not).
1145
     *
1161
     *
1146
     * If you specify a directory, you can optionally specify $recursive as true,
1162
     * If you specify a directory, you can optionally specify $recursive as true,
1147
     * to let the directory be deleted recursive (with all sub-directories and files
1163
     * to let the directory be deleted recursive (with all sub-directories and files
1148
     * inherited).
1164
     * inherited).
1149
     *
1165
     *
1150
     * You can either give a absolute or relative path for the file / dir. If you choose to
1166
     * You can either give a absolute or relative path for the file / dir. If you choose to
1151
     * use the relative path, it will be automatically completed with the actual
1167
     * use the relative path, it will be automatically completed with the actual
1152
     * selected directory.
1168
     * selected directory.
1153
     *
1169
     *
1154
     * @access  public
1170
     * @access  public
1155
     * @param   string $path      The absolute or relative path to the file / directory.
1171
     * @param   string $path      The absolute or relative path to the file / directory.
1156
     * @param   bool   $recursive (optional)
1172
     * @param   bool   $recursive (optional)
1157
     * @return  mixed             True on success, otherwise PEAR::Error
1173
     * @return  mixed             True on success, otherwise PEAR::Error
1158
     * @see     NET_FTP_ERR_DELETEFILE_FAILED, NET_FTP_ERR_DELETEDIR_FAILED, NET_FTP_ERR_REMOTEPATHNODIR
1174
     * @see     NET_FTP_ERR_DELETEFILE_FAILED, NET_FTP_ERR_DELETEDIR_FAILED, NET_FTP_ERR_REMOTEPATHNODIR
1159
     */
1175
     */
1160
    
1176
    
1161
    function rm($path, $recursive = false)
1177
    function rm($path, $recursive = false)
1162
    {
1178
    {
1163
        $path = $this->_construct_path($path);
1179
        $path = $this->_construct_path($path);
1164
 
1180
 
1165
        if ($this->_check_dir($path)) {
1181
        if ($this->_check_dir($path)) {
1166
            if ($recursive) {
1182
            if ($recursive) {
1167
                return $this->_rm_dir_recursive($path);
1183
                return $this->_rm_dir_recursive($path);
1168
            } else {
1184
            } else {
1169
                return $this->_rm_dir($path);
1185
                return $this->_rm_dir($path);
1170
            }
1186
            }
1171
        } else {
1187
        } else {
1172
            return $this->_rm_file($path);
1188
            return $this->_rm_file($path);
1173
        }
1189
        }
1174
    }
1190
    }
1175
 
1191
 
1176
    /**
1192
    /**
1177
     * This function will download a file from the ftp-server. You can either spcify a absolute
1193
     * This function will download a file from the ftp-server. You can either spcify a absolute
1178
     * path to the file (beginning with "/") or a relative one, which will be completed
1194
     * path to the file (beginning with "/") or a relative one, which will be completed
1179
     * with the actual directory you selected on the server. You can specify
1195
     * with the actual directory you selected on the server. You can specify
1180
     * the path to which the file will be downloaded on the local
1196
     * the path to which the file will be downloaded on the local
1181
     * maschine, if the file should be overwritten if it exists (optionally, default is
1197
     * maschine, if the file should be overwritten if it exists (optionally, default is
1182
     * no overwriting) and in which mode (FTP_ASCII or FTP_BINARY) the file should be
1198
     * no overwriting) and in which mode (FTP_ASCII or FTP_BINARY) the file should be
1183
     * downloaded (if you do not specify this, the method tries to determine it automatically
1199
     * downloaded (if you do not specify this, the method tries to determine it automatically
1184
     * from the mode-directory or uses the default-mode, set by you). If you give a relative
1200
     * from the mode-directory or uses the default-mode, set by you). If you give a relative
1185
     * path to the local-file, the script-path is used as basepath.
1201
     * path to the local-file, the script-path is used as basepath.
1186
     *
1202
     *
1187
     * @access  public
1203
     * @access  public
1188
     * @param   string $remote_file The absolute or relative path to the file to download
1204
     * @param   string $remote_file The absolute or relative path to the file to download
1189
     * @param   string $local_file  The local file to put the downloaded in
1205
     * @param   string $local_file  The local file to put the downloaded in
1190
     * @param   bool   $overwrite   (optional) Whether to overwrite existing file
1206
     * @param   bool   $overwrite   (optional) Whether to overwrite existing file
1191
     * @param   int    $mode        (optional) Either FTP_ASCII or FTP_BINARY
1207
     * @param   int    $mode        (optional) Either FTP_ASCII or FTP_BINARY
1192
     * @return  mixed               True on success, otherwise PEAR::Error
1208
     * @return  mixed               True on success, otherwise PEAR::Error
1193
     * @see     NET_FTP_ERR_OVERWRITELOCALFILE_FORBIDDEN, NET_FTP_ERR_OVERWRITELOCALFILE_FAILED, NET_FTP_ERR_OVERWRITELOCALFILE_FAILED
1209
     * @see     NET_FTP_ERR_OVERWRITELOCALFILE_FORBIDDEN, NET_FTP_ERR_OVERWRITELOCALFILE_FAILED, NET_FTP_ERR_OVERWRITELOCALFILE_FAILED
1194
     */
1210
     */
1195
    
1211
    
1196
    function get($remote_file, $local_file, $overwrite = false, $mode = null)
1212
    function get($remote_file, $local_file, $overwrite = false, $mode = null)
1197
    {
1213
    {
1198
        if (!isset($mode)) {
1214
        if (!isset($mode)) {
1199
            $mode = $this->checkFileExtension($remote_file);
1215
            $mode = $this->checkFileExtension($remote_file);
1200
        }
1216
        }
1201
 
1217
 
1202
        $remote_file = $this->_construct_path($remote_file);
1218
        $remote_file = $this->_construct_path($remote_file);
1203
 
1219
 
1204
        if (@file_exists($local_file) && !$overwrite) {
1220
        if (@file_exists($local_file) && !$overwrite) {
1205
            return $this->raiseError("Local file '$local_file' exists and may not be overwriten.", NET_FTP_ERR_OVERWRITELOCALFILE_FORBIDDEN);
1221
            return $this->raiseError("Local file '$local_file' exists and may not be overwriten.", NET_FTP_ERR_OVERWRITELOCALFILE_FORBIDDEN);
1206
        }
1222
        }
1207
        if (@file_exists($local_file) && !@is_writeable($local_file) && $overwrite) {
1223
        if (@file_exists($local_file) && !@is_writeable($local_file) && $overwrite) {
1208
            return $this->raiseError("Local file '$local_file' is not writeable. Can not overwrite.", NET_FTP_ERR_OVERWRITELOCALFILE_FAILED);
1224
            return $this->raiseError("Local file '$local_file' is not writeable. Can not overwrite.", NET_FTP_ERR_OVERWRITELOCALFILE_FAILED);
1209
        }
1225
        }
1210
 
1226
 
1211
        if (@function_exists('ftp_nb_get')){
1227
        if (@function_exists('ftp_nb_get')){
1212
            $res = @ftp_nb_get($this->_handle, $local_file, $remote_file, $mode);
1228
            $res = @ftp_nb_get($this->_handle, $local_file, $remote_file, $mode);
1213
            while ($res == FTP_MOREDATA) {
1229
            while ($res == FTP_MOREDATA) {
1214
                $this->_announce('nb_get');
1230
                $this->_announce('nb_get');
1215
                $res = @ftp_nb_continue ($this->_handle);
1231
                $res = @ftp_nb_continue ($this->_handle);
1216
            }
1232
            }
1217
        } else {
1233
        } else {
1218
            $res = @ftp_get($this->_handle, $local_file, $remote_file, $mode);
1234
            $res = @ftp_get($this->_handle, $local_file, $remote_file, $mode);
1219
        }
1235
        }
1220
        if (!$res) {
1236
        if (!$res) {
1221
            return $this->raiseError("File '$remote_file' could not be downloaded to '$local_file'.", NET_FTP_ERR_OVERWRITELOCALFILE_FAILED);
1237
            return $this->raiseError("File '$remote_file' could not be downloaded to '$local_file'.", NET_FTP_ERR_OVERWRITELOCALFILE_FAILED);
1222
        } else {
1238
        } else {
1223
            return true;
1239
            return true;
1224
        }
1240
        }
1225
    }
1241
    }
1226
 
1242
 
1227
    /**
1243
    /**
1228
     * This function will upload a file to the ftp-server. You can either specify a absolute
1244
     * This function will upload a file to the ftp-server. You can either specify a absolute
1229
     * path to the remote-file (beginning with "/") or a relative one, which will be completed
1245
     * path to the remote-file (beginning with "/") or a relative one, which will be completed
1230
     * with the actual directory you selected on the server. You can specify
1246
     * with the actual directory you selected on the server. You can specify
1231
     * the path from which the file will be uploaded on the local
1247
     * the path from which the file will be uploaded on the local
1232
     * maschine, if the file should be overwritten if it exists (optionally, default is
1248
     * maschine, if the file should be overwritten if it exists (optionally, default is
1233
     * no overwriting) and in which mode (FTP_ASCII or FTP_BINARY) the file should be
1249
     * no overwriting) and in which mode (FTP_ASCII or FTP_BINARY) the file should be
1234
     * downloaded (if you do not specify this, the method tries to determine it automatically
1250
     * downloaded (if you do not specify this, the method tries to determine it automatically
1235
     * from the mode-directory or uses the default-mode, set by you). If you give a relative
1251
     * from the mode-directory or uses the default-mode, set by you). If you give a relative
1236
     * path to the local-file, the script-path is used as basepath.
1252
     * path to the local-file, the script-path is used as basepath.
1237
     *
1253
     *
1238
     * @access  public
1254
     * @access  public
1239
     * @param   string $local_file  The local file to upload
1255
     * @param   string $local_file  The local file to upload
1240
     * @param   string $remote_file The absolute or relative path to the file to upload to
1256
     * @param   string $remote_file The absolute or relative path to the file to upload to
1241
     * @param   bool   $overwrite   (optional) Whether to overwrite existing file
1257
     * @param   bool   $overwrite   (optional) Whether to overwrite existing file
1242
     * @param   int    $mode        (optional) Either FTP_ASCII or FTP_BINARY
1258
     * @param   int    $mode        (optional) Either FTP_ASCII or FTP_BINARY
1243
     * @return  mixed               True on success, otherwise PEAR::Error
1259
     * @return  mixed               True on success, otherwise PEAR::Error
1244
     * @see     NET_FTP_ERR_LOCALFILENOTEXIST, NET_FTP_ERR_OVERWRITEREMOTEFILE_FORBIDDEN, NET_FTP_ERR_UPLOADFILE_FAILED
1260
     * @see     NET_FTP_ERR_LOCALFILENOTEXIST, NET_FTP_ERR_OVERWRITEREMOTEFILE_FORBIDDEN, NET_FTP_ERR_UPLOADFILE_FAILED
1245
     */
1261
     */
1246
    
1262
    
1247
    function put($local_file, $remote_file, $overwrite = false, $mode = null)
1263
    function put($local_file, $remote_file, $overwrite = false, $mode = null)
1248
    {
1264
    {
1249
        if (!isset($mode)) {
1265
        if (!isset($mode)) {
1250
            $mode = $this->checkFileExtension($local_file);
1266
            $mode = $this->checkFileExtension($local_file);
1251
        }
1267
        }
1252
        $remote_file = $this->_construct_path($remote_file);
1268
        $remote_file = $this->_construct_path($remote_file);
1253
 
1269
 
1254
        if (!@file_exists($local_file)) {
1270
        if (!@file_exists($local_file)) {
1255
            return $this->raiseError("Local file '$local_file' does not exist.", NET_FTP_ERR_LOCALFILENOTEXIST);
1271
            return $this->raiseError("Local file '$local_file' does not exist.", NET_FTP_ERR_LOCALFILENOTEXIST);
1256
        }
1272
        }
1257
        if ((@ftp_size($this->_handle, $remote_file) != -1) && !$overwrite) {
1273
        if ((@ftp_size($this->_handle, $remote_file) != -1) && !$overwrite) {
1258
            return $this->raiseError("Remote file '$remote_file' exists and may not be overwriten.", NET_FTP_ERR_OVERWRITEREMOTEFILE_FORBIDDEN);
1274
            return $this->raiseError("Remote file '$remote_file' exists and may not be overwriten.", NET_FTP_ERR_OVERWRITEREMOTEFILE_FORBIDDEN);
1259
        }
1275
        }
1260
 
1276
 
1261
        if (function_exists('ftp_nb_put')){
1277
        if (function_exists('ftp_nb_put')){
1262
            $res = @ftp_nb_put($this->_handle, $remote_file, $local_file, $mode);
1278
            $res = @ftp_nb_put($this->_handle, $remote_file, $local_file, $mode);
1263
            while ($res == FTP_MOREDATA) {
1279
            while ($res == FTP_MOREDATA) {
1264
                $this->_announce('nb_put');
1280
                $this->_announce('nb_put');
1265
                $res = @ftp_nb_continue($this->_handle);
1281
                $res = @ftp_nb_continue($this->_handle);
1266
            }
1282
            }
1267
 
1283
 
1268
        } else {
1284
        } else {
1269
            $res = @ftp_put($this->_handle, $remote_file, $local_file, $mode);
1285
            $res = @ftp_put($this->_handle, $remote_file, $local_file, $mode);
1270
        }
1286
        }
1271
        if (!$res) {
1287
        if (!$res) {
1272
            return $this->raiseError("File '$local_file' could not be uploaded to '$remote_file'.", NET_FTP_ERR_UPLOADFILE_FAILED);
1288
            return $this->raiseError("File '$local_file' could not be uploaded to '$remote_file'.", NET_FTP_ERR_UPLOADFILE_FAILED);
1273
        } else {
1289
        } else {
1274
            return true;
1290
            return true;
1275
        }
1291
        }
1276
    }
1292
    }
1277
 
1293
 
1278
    /**
1294
    /**
1279
     * This functionality allows you to transfer a whole directory-structure from the
1295
     * This functionality allows you to transfer a whole directory-structure from the
1280
     * remote-ftp to your local host. You have to give a remote-directory (ending with
1296
     * remote-ftp to your local host. You have to give a remote-directory (ending with
1281
     * '/') and the local directory (ending with '/') where to put the files you download.
1297
     * '/') and the local directory (ending with '/') where to put the files you download.
1282
     * The remote path is automatically completed with the current-remote-dir, if you give
1298
     * The remote path is automatically completed with the current-remote-dir, if you give
1283
     * a relative path to this function. You can give a relative path for the $local_path,
1299
     * a relative path to this function. You can give a relative path for the $local_path,
1284
     * too. Then the script-basedir will be used for comletion of the path.
1300
     * too. Then the script-basedir will be used for comletion of the path.
1285
     * The parameter $overwrite will determine, whether to overwrite existing files or not.
1301
     * The parameter $overwrite will determine, whether to overwrite existing files or not.
1286
     * Standard for this is false. Fourth you can explicitly set a mode for all transfer-
1302
     * Standard for this is false. Fourth you can explicitly set a mode for all transfer-
1287
     * actions done. If you do not set this, the method tries to determine the transfer-
1303
     * actions done. If you do not set this, the method tries to determine the transfer-
1288
     * mode by checking your mode-directory for the file-extension. If the extension is not
1304
     * mode by checking your mode-directory for the file-extension. If the extension is not
1289
     * inside the mode-directory, it will get your default-mode.
1305
     * inside the mode-directory, it will get your default-mode.
1290
     *
1306
     *
1291
     * @access  public
1307
     * @access  public
1292
     * @param   string $remote_path The path to download
1308
     * @param   string $remote_path The path to download
1293
     * @param   string $local_path  The path to download to
1309
     * @param   string $local_path  The path to download to
1294
     * @param   bool   $overwrite   (optional) Whether to overwrite existing files (true) or not (false, standard).
1310
     * @param   bool   $overwrite   (optional) Whether to overwrite existing files (true) or not (false, standard).
1295
     * @param   int    $mode        (optional) The transfermode (either FTP_ASCII or FTP_BINARY).
1311
     * @param   int    $mode        (optional) The transfermode (either FTP_ASCII or FTP_BINARY).
1296
     * @return  mixed               True on succes, otherwise PEAR::Error
1312
     * @return  mixed               True on succes, otherwise PEAR::Error
1297
     * @see     NET_FTP_ERR_OVERWRITELOCALFILE_FORBIDDEN, NET_FTP_ERR_OVERWRITELOCALFILE_FAILED, NET_FTP_ERR_OVERWRITELOCALFILE_FAILED, NET_FTP_ERR_REMOTEPATHNODIR, NET_FTP_ERR_LOCALPATHNODIR,NET_FTP_ERR_CREATELOCALDIR_FAILED
1313
     * @see     NET_FTP_ERR_OVERWRITELOCALFILE_FORBIDDEN, NET_FTP_ERR_OVERWRITELOCALFILE_FAILED, NET_FTP_ERR_OVERWRITELOCALFILE_FAILED, NET_FTP_ERR_REMOTEPATHNODIR, NET_FTP_ERR_LOCALPATHNODIR,NET_FTP_ERR_CREATELOCALDIR_FAILED
1298
     */
1314
     */
1299
    
1315
    
1300
    function getRecursive($remote_path, $local_path, $overwrite = false, $mode = null)
1316
    function getRecursive($remote_path, $local_path, $overwrite = false, $mode = null)
1301
    {
1317
    {
1302
        $remote_path = $this->_construct_path($remote_path);
1318
        $remote_path = $this->_construct_path($remote_path);
1303
        if (!$this->_check_dir($remote_path)) {
1319
        if (!$this->_check_dir($remote_path)) {
1304
            return $this->raiseError("Given remote-path '$remote_path' seems not to be a directory.", NET_FTP_ERR_REMOTEPATHNODIR);
1320
            return $this->raiseError("Given remote-path '$remote_path' seems not to be a directory.", NET_FTP_ERR_REMOTEPATHNODIR);
1305
        }
1321
        }
1306
        if (!$this->_check_dir($local_path)) {
1322
        if (!$this->_check_dir($local_path)) {
1307
            return $this->raiseError("Given local-path '$local_path' seems not to be a directory.", NET_FTP_ERR_LOCALPATHNODIR);
1323
            return $this->raiseError("Given local-path '$local_path' seems not to be a directory.", NET_FTP_ERR_LOCALPATHNODIR);
1308
        }
1324
        }
1309
 
1325
 
1310
        if (!@is_dir($local_path)) {
1326
        if (!@is_dir($local_path)) {
1311
            $res = @mkdir($local_path);
1327
            $res = @mkdir($local_path);
1312
            if (!$res) {
1328
            if (!$res) {
1313
                return $this->raiseError("Could not create dir '$local_path'", NET_FTP_ERR_CREATELOCALDIR_FAILED);
1329
                return $this->raiseError("Could not create dir '$local_path'", NET_FTP_ERR_CREATELOCALDIR_FAILED);
1314
            }
1330
            }
1315
        }
1331
        }
1316
        $dir_list = array();
1332
        $dir_list = array();
1317
        $dir_list = $this->ls($remote_path, NET_FTP_DIRS_ONLY);
1333
        $dir_list = $this->ls($remote_path, NET_FTP_DIRS_ONLY);
1318
        foreach ($dir_list as $dir_entry) {
1334
        foreach ($dir_list as $dir_entry) {
1319
            if ($dir_entry['name'] != '.' && $dir_entry['name'] != '..') {
1335
            if ($dir_entry['name'] != '.' && $dir_entry['name'] != '..') {
1320
                $remote_path_new = $remote_path.$dir_entry["name"]."/";
1336
                $remote_path_new = $remote_path.$dir_entry["name"]."/";
1321
                $local_path_new = $local_path.$dir_entry["name"]."/";
1337
                $local_path_new = $local_path.$dir_entry["name"]."/";
1322
                $result = $this->getRecursive($remote_path_new, $local_path_new, $overwrite, $mode);
1338
                $result = $this->getRecursive($remote_path_new, $local_path_new, $overwrite, $mode);
1323
                if ($this->isError($result)) {
1339
                if ($this->isError($result)) {
1324
                    return $result;
1340
                    return $result;
1325
                }
1341
                }
1326
            }
1342
            }
1327
        }
1343
        }
1328
        $file_list = array();
1344
        $file_list = array();
1329
        $file_list = $this->ls($remote_path, NET_FTP_FILES_ONLY);
1345
        $file_list = $this->ls($remote_path, NET_FTP_FILES_ONLY);
1330
        foreach ($file_list as $file_entry) {
1346
        foreach ($file_list as $file_entry) {
1331
            $remote_file = $remote_path.$file_entry["name"];
1347
            $remote_file = $remote_path.$file_entry["name"];
1332
            $local_file = $local_path.$file_entry["name"];
1348
            $local_file = $local_path.$file_entry["name"];
1333
            $result = $this->get($remote_file, $local_file, $overwrite, $mode);
1349
            $result = $this->get($remote_file, $local_file, $overwrite, $mode);
1334
            if ($this->isError($result)) {
1350
            if ($this->isError($result)) {
1335
                return $result;
1351
                return $result;
1336
            }
1352
            }
1337
        }
1353
        }
1338
        return true;
1354
        return true;
1339
    }
1355
    }
1340
 
1356
 
1341
    /**
1357
    /**
1342
     * This functionality allows you to transfer a whole directory-structure from your
1358
     * This functionality allows you to transfer a whole directory-structure from your
1343
     * local host to the remote-ftp. You have to give a remote-directory (ending with
1359
     * local host to the remote-ftp. You have to give a remote-directory (ending with
1344
     * '/') and the local directory (ending with '/') where to put the files you download.
1360
     * '/') and the local directory (ending with '/') where to put the files you download.
1345
     * The remote path is automatically completed with the current-remote-dir, if you give
1361
     * The remote path is automatically completed with the current-remote-dir, if you give
1346
     * a relative path to this function. You can give a relative path for the $local_path,
1362
     * a relative path to this function. You can give a relative path for the $local_path,
1347
     * too. Then the script-basedir will be used for comletion of the path.
1363
     * too. Then the script-basedir will be used for comletion of the path.
1348
     * The parameter $overwrite will determine, whether to overwrite existing files or not.
1364
     * The parameter $overwrite will determine, whether to overwrite existing files or not.
1349
     * Standard for this is false. Fourth you can explicitly set a mode for all transfer-
1365
     * Standard for this is false. Fourth you can explicitly set a mode for all transfer-
1350
     * actions done. If you do not set this, the method tries to determine the transfer-
1366
     * actions done. If you do not set this, the method tries to determine the transfer-
1351
     * mode by checking your mode-directory for the file-extension. If the extension is not
1367
     * mode by checking your mode-directory for the file-extension. If the extension is not
1352
     * inside the mode-directory, it will get your default-mode.
1368
     * inside the mode-directory, it will get your default-mode.
1353
     *
1369
     *
1354
     * @access  public
1370
     * @access  public
1355
     * @param   string $remote_path The path to download 
1371
     * @param   string $remote_path The path to download 
1356
     * @param   string $local_path  The path to download to
1372
     * @param   string $local_path  The path to download to
1357
     * @param   bool   $overwrite   (optional) Whether to overwrite existing files (true) or not (false, standard).
1373
     * @param   bool   $overwrite   (optional) Whether to overwrite existing files (true) or not (false, standard).
1358
     * @param   int    $mode        (optional) The transfermode (either FTP_ASCII or FTP_BINARY).
1374
     * @param   int    $mode        (optional) The transfermode (either FTP_ASCII or FTP_BINARY).
1359
     * @return  mixed               True on succes, otherwise PEAR::Error
1375
     * @return  mixed               True on succes, otherwise PEAR::Error
1360
     * @see     NET_FTP_ERR_LOCALFILENOTEXIST, NET_FTP_ERR_OVERWRITEREMOTEFILE_FORBIDDEN, NET_FTP_ERR_UPLOADFILE_FAILED, NET_FTP_ERR_LOCALPATHNODIR, NET_FTP_ERR_REMOTEPATHNODIR
1376
     * @see     NET_FTP_ERR_LOCALFILENOTEXIST, NET_FTP_ERR_OVERWRITEREMOTEFILE_FORBIDDEN, NET_FTP_ERR_UPLOADFILE_FAILED, NET_FTP_ERR_LOCALPATHNODIR, NET_FTP_ERR_REMOTEPATHNODIR
1361
     */
1377
     */
1362
    
1378
    
1363
    function putRecursive($local_path, $remote_path, $overwrite = false, $mode = null)
1379
    function putRecursive($local_path, $remote_path, $overwrite = false, $mode = null)
1364
    {
1380
    {
1365
        $remote_path = $this->_construct_path($remote_path);
1381
        $remote_path = $this->_construct_path($remote_path);
1366
        if (!$this->_check_dir($local_path) || !is_dir($local_path)) {
1382
        if (!$this->_check_dir($local_path) || !is_dir($local_path)) {
1367
            return $this->raiseError("Given local-path '$local_path' seems not to be a directory.", NET_FTP_ERR_LOCALPATHNODIR);
1383
            return $this->raiseError("Given local-path '$local_path' seems not to be a directory.", NET_FTP_ERR_LOCALPATHNODIR);
1368
        }
1384
        }
1369
        if (!$this->_check_dir($remote_path)) {
1385
        if (!$this->_check_dir($remote_path)) {
1370
            return $this->raiseError("Given remote-path '$remote_path' seems not to be a directory.", NET_FTP_ERR_REMOTEPATHNODIR);
1386
            return $this->raiseError("Given remote-path '$remote_path' seems not to be a directory.", NET_FTP_ERR_REMOTEPATHNODIR);
1371
        }
1387
        }
1372
        $old_path = $this->pwd();
1388
        $old_path = $this->pwd();
1373
        if ($this->isError($this->cd($remote_path))) {
1389
        if ($this->isError($this->cd($remote_path))) {
1374
            $res = $this->mkdir($remote_path);
1390
            $res = $this->mkdir($remote_path);
1375
            if ($this->isError($res)) {
1391
            if ($this->isError($res)) {
1376
                return $res;
1392
                return $res;
1377
            }
1393
            }
1378
        }
1394
        }
1379
        $this->cd($old_path);
1395
        $this->cd($old_path);
1380
        $dir_list = $this->_ls_local($local_path);
1396
        $dir_list = $this->_ls_local($local_path);
1381
        foreach ($dir_list["dirs"] as $dir_entry) {
1397
        foreach ($dir_list["dirs"] as $dir_entry) {
1382
            $remote_path_new = $remote_path.$dir_entry."/";
1398
            $remote_path_new = $remote_path.$dir_entry."/";
1383
            $local_path_new = $local_path.$dir_entry."/";
1399
            $local_path_new = $local_path.$dir_entry."/";
1384
            $result = $this->putRecursive($local_path_new, $remote_path_new, $overwrite, $mode);
1400
            $result = $this->putRecursive($local_path_new, $remote_path_new, $overwrite, $mode);
1385
            if ($this->isError($result)) {
1401
            if ($this->isError($result)) {
1386
                return $result;
1402
                return $result;
1387
            }
1403
            }
1388
        }
1404
        }
1389
 
1405
 
1390
        foreach ($dir_list["files"] as $file_entry) {
1406
        foreach ($dir_list["files"] as $file_entry) {
1391
            $remote_file = $remote_path.$file_entry;
1407
            $remote_file = $remote_path.$file_entry;
1392
            $local_file = $local_path.$file_entry;
1408
            $local_file = $local_path.$file_entry;
1393
            $result = $this->put($local_file, $remote_file, $overwrite, $mode);
1409
            $result = $this->put($local_file, $remote_file, $overwrite, $mode);
1394
            if ($this->isError($result)) {
1410
            if ($this->isError($result)) {
1395
                return $result;
1411
                return $result;
1396
            }
1412
            }
1397
        }
1413
        }
1398
        return true;
1414
        return true;
1399
    }
1415
    }
1400
 
1416
 
1401
    /**
1417
    /**
1402
     * This checks, whether a file should be transfered in ascii- or binary-mode
1418
     * This checks, whether a file should be transfered in ascii- or binary-mode
1403
     * by it's file-extension. If the file-extension is not set or
1419
     * by it's file-extension. If the file-extension is not set or
1404
     * the extension is not inside one of the extension-dirs, the actual set
1420
     * the extension is not inside one of the extension-dirs, the actual set
1405
     * transfer-mode is returned.
1421
     * transfer-mode is returned.
1406
     *
1422
     *
1407
     * @access  public
1423
     * @access  public
1408
     * @param   string $filename  The filename to be checked
1424
     * @param   string $filename  The filename to be checked
1409
     * @return  int               Either FTP_ASCII or FTP_BINARY
1425
     * @return  int               Either FTP_ASCII or FTP_BINARY
1410
     */
1426
     */
1411
    
1427
    
1412
    function checkFileExtension($filename)
1428
    function checkFileExtension($filename)
1413
    {
1429
    {
1414
        $pattern = "/\.(.*)$/";
1430
        $pattern = "/\.(.*)$/";
1415
        $has_extension = preg_match($pattern, $filename, $eregs);
1431
        $has_extension = preg_match($pattern, $filename, $eregs);
1416
        if (!$has_extension) {
1432
        if (!$has_extension) {
1417
            return $this->_mode;
1433
            return $this->_mode;
1418
        } else {
1434
        } else {
1419
            $ext = $eregs[1];
1435
            $ext = $eregs[1];
1420
        }
1436
        }
1421
 
1437
 
1422
        if (!empty($this->_file_extensions[$ext])) {
1438
        if (!empty($this->_file_extensions[$ext])) {
1423
            return $this->_file_extensions[$ext];
1439
            return $this->_file_extensions[$ext];
1424
        }
1440
        }
1425
 
1441
 
1426
        return $this->_mode;
1442
        return $this->_mode;
1427
    }
1443
    }
1428
 
1444
 
1429
    /**
1445
    /**
1430
     * Set the Hostname
1446
     * Set the Hostname
1431
     *
1447
     *
1432
     * @access  public
1448
     * @access  public
1433
     * @param   string $host The Hostname to set
1449
     * @param   string $host The Hostname to set
1434
     * @return  bool True on success, otherwise PEAR::Error
1450
     * @return  bool True on success, otherwise PEAR::Error
1435
     * @see     NET_FTP_ERR_HOSTNAMENOSTRING
1451
     * @see     NET_FTP_ERR_HOSTNAMENOSTRING
1436
     */
1452
     */
1437
    
1453
    
1438
    function setHostname($host)
1454
    function setHostname($host)
1439
    {
1455
    {
1440
        if (!is_string($host)) {
1456
        if (!is_string($host)) {
1441
            return PEAR::raiseError("Hostname must be a string.", NET_FTP_ERR_HOSTNAMENOSTRING);
1457
            return PEAR::raiseError("Hostname must be a string.", NET_FTP_ERR_HOSTNAMENOSTRING);
1442
        }
1458
        }
1443
        $this->_hostname = $host;
1459
        $this->_hostname = $host;
1444
        return true;
1460
        return true;
1445
    }
1461
    }
1446
 
1462
 
1447
    /**
1463
    /**
1448
     * Set the Port
1464
     * Set the Port
1449
     *
1465
     *
1450
     * @access  public
1466
     * @access  public
1451
     * @param   int $port    The Port to set
1467
     * @param   int $port    The Port to set
1452
     * @return  bool True on success, otherwise PEAR::Error
1468
     * @return  bool True on success, otherwise PEAR::Error
1453
     * @see     NET_FTP_ERR_PORTLESSZERO
1469
     * @see     NET_FTP_ERR_PORTLESSZERO
1454
     */
1470
     */
1455
    
1471
    
1456
    function setPort($port)
1472
    function setPort($port)
1457
    {
1473
    {
1458
        if (!is_int($port) || ($port < 0)) {
1474
        if (!is_int($port) || ($port < 0)) {
1459
            PEAR::raiseError("Invalid port. Has to be integer >= 0", NET_FTP_ERR_PORTLESSZERO);
1475
            PEAR::raiseError("Invalid port. Has to be integer >= 0", NET_FTP_ERR_PORTLESSZERO);
1460
        }
1476
        }
1461
        $this->_port = $port;
1477
        $this->_port = $port;
1462
        return true;
1478
        return true;
1463
    }
1479
    }
1464
 
1480
 
1465
    /**
1481
    /**
1466
     * Set the Username
1482
     * Set the Username
1467
     *
1483
     *
1468
     * @access  public
1484
     * @access  public
1469
     * @param   string $user The Username to set
1485
     * @param   string $user The Username to set
1470
     * @return  mixed True on success, otherwise PEAR::Error
1486
     * @return  mixed True on success, otherwise PEAR::Error
1471
     * @see     NET_FTP_ERR_USERNAMENOSTRING
1487
     * @see     NET_FTP_ERR_USERNAMENOSTRING
1472
     */
1488
     */
1473
    
1489
    
1474
    function setUsername($user)
1490
    function setUsername($user)
1475
    {
1491
    {
1476
        if (empty($user) || !is_string($user)) {
1492
        if (empty($user) || !is_string($user)) {
1477
            return PEAR::raiseError('Username $user invalid.', NET_FTP_ERR_USERNAMENOSTRING);
1493
            return PEAR::raiseError('Username $user invalid.', NET_FTP_ERR_USERNAMENOSTRING);
1478
        }
1494
        }
1479
        $this->_username = $user;
1495
        $this->_username = $user;
1480
    }
1496
    }
1481
 
1497
 
1482
    /**
1498
    /**
1483
     * Set the Password
1499
     * Set the Password
1484
     *
1500
     *
1485
     * @access  private
1501
     * @access  private
1486
     * @param   string $password  The Password to set
1502
     * @param   string $password  The Password to set
1487
     * @return  void
1503
     * @return  void
1488
     * @see     NET_FTP_ERR_PASSWORDNOSTRING
1504
     * @see     NET_FTP_ERR_PASSWORDNOSTRING
1489
     */
1505
     */
1490
    
1506
    
1491
    function setPassword($password)
1507
    function setPassword($password)
1492
    {
1508
    {
1493
        if (empty($password) || !is_string($password)) {
1509
        if (empty($password) || !is_string($password)) {
1494
            return PEAR::raiseError('Password xxx invalid.', NET_FTP_ERR_PASSWORDNOSTRING);
1510
            return PEAR::raiseError('Password xxx invalid.', NET_FTP_ERR_PASSWORDNOSTRING);
1495
        }
1511
        }
1496
        $this->_password = $password;
1512
        $this->_password = $password;
1497
    }
1513
    }
1498
 
1514
 
1499
    /**
1515
    /**
1500
     * Set the transfer-mode. You can use the predefined constants
1516
     * Set the transfer-mode. You can use the predefined constants
1501
     * FTP_ASCII or FTP_BINARY. The mode will be stored for any further transfers.
1517
     * FTP_ASCII or FTP_BINARY. The mode will be stored for any further transfers.
1502
     *
1518
     *
1503
     * @access  public
1519
     * @access  public
1504
     * @param   int    $mode  The mode to set
1520
     * @param   int    $mode  The mode to set
1505
     * @return  mixed         True on success, otherwise PEAR::Error
1521
     * @return  mixed         True on success, otherwise PEAR::Error
1506
     * @see     NET_FTP_ERR_NOMODECONST
1522
     * @see     NET_FTP_ERR_NOMODECONST
1507
     */
1523
     */
1508
    
1524
    
1509
    function setMode($mode)
1525
    function setMode($mode)
1510
    {
1526
    {
1511
        if (($mode == FTP_ASCII) || ($mode == FTP_BINARY)) {
1527
        if (($mode == FTP_ASCII) || ($mode == FTP_BINARY)) {
1512
            $this->_mode = $mode;
1528
            $this->_mode = $mode;
1513
            return true;
1529
            return true;
1514
        } else {
1530
        } else {
1515
            return $this->raiseError('FTP-Mode has either to be FTP_ASCII or FTP_BINARY', NET_FTP_ERR_NOMODECONST);
1531
            return $this->raiseError('FTP-Mode has either to be FTP_ASCII or FTP_BINARY', NET_FTP_ERR_NOMODECONST);
1516
        }
1532
        }
1517
    }
1533
    }
1518
 
1534
 
1519
    /**
1535
    /**
1520
     * Set the transfer-method to passive mode
1536
     * Set the transfer-method to passive mode
1521
     *
1537
     *
1522
     * @access  public
1538
     * @access  public
1523
     * @return  void
1539
     * @return  void
1524
     */
1540
     */
1525
    
1541
    
1526
    function setPassive()
1542
    function setPassive()
1527
    {
1543
    {
1528
        $this->_passv = true;
1544
        $this->_passv = true;
1529
        @ftp_pasv($this->_handle, true);
1545
        @ftp_pasv($this->_handle, true);
1530
    }
1546
    }
1531
 
1547
 
1532
    /**
1548
    /**
1533
     * Set the transfer-method to active mode
1549
     * Set the transfer-method to active mode
1534
     *
1550
     *
1535
     * @access  public
1551
     * @access  public
1536
     * @return  void
1552
     * @return  void
1537
     */
1553
     */
1538
    
1554
    
1539
    function setActive()
1555
    function setActive()
1540
    {
1556
    {
1541
        $this->_passv = false;
1557
        $this->_passv = false;
1542
        @ftp_pasv($this->_handle, false);
1558
        @ftp_pasv($this->_handle, false);
1543
    }
1559
    }
1544
 
1560
 
1545
    /**
1561
    /**
1546
     * Set the timeout for FTP operations
1562
     * Set the timeout for FTP operations
1547
     * Use this method to set a timeout for FTP operation. Timeout has to be an integer.
1563
     * Use this method to set a timeout for FTP operation. Timeout has to be an integer.
1548
     *
1564
     *
1549
     * @acess   public
1565
     * @acess   public
1550
     * @param   int $timeout the timeout to use
1566
     * @param   int $timeout the timeout to use
1551
     * @return  bool True on success, otherwise PEAR::Error
1567
     * @return  bool True on success, otherwise PEAR::Error
1552
     * @see     NET_FTP_ERR_TIMEOUTLESSZERO, NET_FTP_ERR_SETTIMEOUT_FAILED
1568
     * @see     NET_FTP_ERR_TIMEOUTLESSZERO, NET_FTP_ERR_SETTIMEOUT_FAILED
1553
     */
1569
     */
1554
     
1570
     
1555
    function setTimeout ( $timeout = 0 ) 
1571
    function setTimeout ( $timeout = 0 ) 
1556
    {
1572
    {
1557
        if (!is_int($timeout) || ($timeout < 0)) {
1573
        if (!is_int($timeout) || ($timeout < 0)) {
1558
            return PEAR::raiseError("Timeout $timeout is invalid, has to be an integer >= 0", NET_FTP_ERR_TIMEOUTLESSZERO);
1574
            return PEAR::raiseError("Timeout $timeout is invalid, has to be an integer >= 0", NET_FTP_ERR_TIMEOUTLESSZERO);
1559
        }
1575
        }
1560
        $this->_timeout = $timeout;
1576
        $this->_timeout = $timeout;
1561
        if (isset($this->_handle) && is_resource($this->_handle)) {
1577
        if (isset($this->_handle) && is_resource($this->_handle)) {
1562
            $res = @ftp_set_option($this->_handle, FTP_TIMEOUT_SEC, $timeout);
1578
            $res = @ftp_set_option($this->_handle, FTP_TIMEOUT_SEC, $timeout);
1563
        } else {
1579
        } else {
1564
            $res = true;
1580
            $res = true;
1565
        }
1581
        }
1566
        if (!$res) {
1582
        if (!$res) {
1567
            return PEAR::raiseError("Set timeout failed.", NET_FTP_ERR_SETTIMEOUT_FAILED);
1583
            return PEAR::raiseError("Set timeout failed.", NET_FTP_ERR_SETTIMEOUT_FAILED);
1568
        }
1584
        }
1569
        return true;
1585
        return true;
1570
    }        
1586
    }        
1571
    
1587
    
1572
    /**
1588
    /**
1573
     * Adds an extension to a mode-directory
1589
     * Adds an extension to a mode-directory
1574
     * The mode-directory saves file-extensions coresponding to filetypes
1590
     * The mode-directory saves file-extensions coresponding to filetypes
1575
     * (ascii e.g.: 'php', 'txt', 'htm',...; binary e.g.: 'jpg', 'gif', 'exe',...).
1591
     * (ascii e.g.: 'php', 'txt', 'htm',...; binary e.g.: 'jpg', 'gif', 'exe',...).
1576
     * The extensions have to be saved without the '.'. And
1592
     * The extensions have to be saved without the '.'. And
1577
     * can be predefined in an external file (see: getExtensionsFile()).
1593
     * can be predefined in an external file (see: getExtensionsFile()).
1578
     *
1594
     *
1579
     * The array is build like this: 'php' => FTP_ASCII, 'png' => FTP_BINARY
1595
     * The array is build like this: 'php' => FTP_ASCII, 'png' => FTP_BINARY
1580
     *
1596
     *
1581
     * To change the mode of an extension, just add it again with the new mode!
1597
     * To change the mode of an extension, just add it again with the new mode!
1582
     *
1598
     *
1583
     * @access  public
1599
     * @access  public
1584
     * @param   int    $mode  Either FTP_ASCII or FTP_BINARY
1600
     * @param   int    $mode  Either FTP_ASCII or FTP_BINARY
1585
     * @param   string $ext   Extension
1601
     * @param   string $ext   Extension
1586
     * @return  void
1602
     * @return  void
1587
     */
1603
     */
1588
    
1604
    
1589
    function addExtension($mode, $ext)
1605
    function addExtension($mode, $ext)
1590
    {
1606
    {
1591
        $this->_file_extensions[$ext] = $mode;
1607
        $this->_file_extensions[$ext] = $mode;
1592
    }
1608
    }
1593
 
1609
 
1594
    /**
1610
    /**
1595
     * This function removes an extension from the mode-directories 
1611
     * This function removes an extension from the mode-directories 
1596
     * (described above).
1612
     * (described above).
1597
     *
1613
     *
1598
     * @access  public
1614
     * @access  public
1599
     * @param   string $ext  The extension to remove
1615
     * @param   string $ext  The extension to remove
1600
     * @return  void
1616
     * @return  void
1601
     */
1617
     */
1602
    
1618
    
1603
    function removeExtension($ext)
1619
    function removeExtension($ext)
1604
    {
1620
    {
1605
        unset($this->_file_extensions[$ext]);
1621
        unset($this->_file_extensions[$ext]);
1606
    }
1622
    }
1607
 
1623
 
1608
    /**
1624
    /**
1609
     * This get's both (ascii- and binary-mode-directories) from the given file.
1625
     * This get's both (ascii- and binary-mode-directories) from the given file.
1610
     * Beware, if you read a file into the mode-directory, all former set values 
1626
     * Beware, if you read a file into the mode-directory, all former set values 
1611
     * will be unset!
1627
     * will be unset!
1612
     *
1628
     *
1613
     * @access  public
1629
     * @access  public
1614
     * @param   string $filename  The file to get from
1630
     * @param   string $filename  The file to get from
1615
     * @return  mixed             True on success, otherwise PEAR::Error
1631
     * @return  mixed             True on success, otherwise PEAR::Error
1616
     * @see     NET_FTP_ERR_EXTFILENOTEXIST, NET_FTP_ERR_EXTFILEREAD_FAILED
1632
     * @see     NET_FTP_ERR_EXTFILENOTEXIST, NET_FTP_ERR_EXTFILEREAD_FAILED
1617
     */
1633
     */
1618
    
1634
    
1619
    function getExtensionsFile($filename)
1635
    function getExtensionsFile($filename)
1620
    {
1636
    {
1621
        if (!file_exists($filename)) {
1637
        if (!file_exists($filename)) {
1622
            return $this->raiseError("Extensions-file '$filename' does not exist", NET_FTP_ERR_EXTFILENOTEXIST);
1638
            return $this->raiseError("Extensions-file '$filename' does not exist", NET_FTP_ERR_EXTFILENOTEXIST);
1623
        }
1639
        }
1624
 
1640
 
1625
        if (!is_readable($filename)) {
1641
        if (!is_readable($filename)) {
1626
            return $this->raiseError("Extensions-file '$filename' is not readable", NET_FTP_ERR_EXTFILEREAD_FAILED);
1642
            return $this->raiseError("Extensions-file '$filename' is not readable", NET_FTP_ERR_EXTFILEREAD_FAILED);
1627
        }
1643
        }
1628
 
1644
 
1629
        $this->_file_extension = @parse_ini_file($filename);
1645
        $this->_file_extension = @parse_ini_file($filename);
1630
        return true;
1646
        return true;
1631
    }
1647
    }
1632
 
1648
 
1633
    /**
1649
    /**
1634
     * Returns the Hostname
1650
     * Returns the Hostname
1635
     *
1651
     *
1636
     * @access  public
1652
     * @access  public
1637
     * @return  string  The Hostname
1653
     * @return  string  The Hostname
1638
     */
1654
     */
1639
    
1655
    
1640
    function getHostname()
1656
    function getHostname()
1641
    {
1657
    {
1642
        return $this->_hostname;
1658
        return $this->_hostname;
1643
    }
1659
    }
1644
 
1660
 
1645
    /**
1661
    /**
1646
     * Returns the Port
1662
     * Returns the Port
1647
     *
1663
     *
1648
     * @access  public
1664
     * @access  public
1649
     * @return  int     The Port
1665
     * @return  int     The Port
1650
     */
1666
     */
1651
    
1667
    
1652
    function getPort()
1668
    function getPort()
1653
    {
1669
    {
1654
        return $this->_port;
1670
        return $this->_port;
1655
    }
1671
    }
1656
 
1672
 
1657
    /**
1673
    /**
1658
     * Returns the Username
1674
     * Returns the Username
1659
     *
1675
     *
1660
     * @access  public
1676
     * @access  public
1661
     * @return  string  The Username
1677
     * @return  string  The Username
1662
     */
1678
     */
1663
    
1679
    
1664
    function getUsername()
1680
    function getUsername()
1665
    {
1681
    {
1666
        return $this->_username;
1682
        return $this->_username;
1667
    }
1683
    }
1668
 
1684
 
1669
    /**
1685
    /**
1670
     * Returns the Password
1686
     * Returns the Password
1671
     *
1687
     *
1672
     * @access  public
1688
     * @access  public
1673
     * @return  string  The Password
1689
     * @return  string  The Password
1674
     */
1690
     */
1675
    
1691
    
1676
    function getPassword()
1692
    function getPassword()
1677
    {
1693
    {
1678
        return $this->_password;
1694
        return $this->_password;
1679
    }
1695
    }
1680
 
1696
 
1681
    /**
1697
    /**
1682
     * Returns the Transfermode
1698
     * Returns the Transfermode
1683
     *
1699
     *
1684
     * @access  public
1700
     * @access  public
1685
     * @return  int     The transfermode, either FTP_ASCII or FTP_BINARY.
1701
     * @return  int     The transfermode, either FTP_ASCII or FTP_BINARY.
1686
     */
1702
     */
1687
    
1703
    
1688
    function getMode()
1704
    function getMode()
1689
    {
1705
    {
1690
        return $this->_mode;
1706
        return $this->_mode;
1691
    }
1707
    }
1692
 
1708
 
1693
    /**
1709
    /**
1694
     * Returns, whether the connection is set to passive mode or not
1710
     * Returns, whether the connection is set to passive mode or not
1695
     *
1711
     *
1696
     * @access  public
1712
     * @access  public
1697
     * @return  bool    True if passive-, false if active-mode
1713
     * @return  bool    True if passive-, false if active-mode
1698
     */
1714
     */
1699
    
1715
    
1700
    function isPassive()
1716
    function isPassive()
1701
    {
1717
    {
1702
        return $this->_passv;
1718
        return $this->_passv;
1703
    }
1719
    }
1704
 
1720
 
1705
    /**
1721
    /**
1706
     * Returns the mode set for a file-extension
1722
     * Returns the mode set for a file-extension
1707
     *
1723
     *
1708
     * @access  public
1724
     * @access  public
1709
     * @param   string   $ext    The extension you wanna ask for
1725
     * @param   string   $ext    The extension you wanna ask for
1710
     * @return  int              Either FTP_ASCII, FTP_BINARY or NULL (if not set a mode for it)
1726
     * @return  int              Either FTP_ASCII, FTP_BINARY or NULL (if not set a mode for it)
1711
     */
1727
     */
1712
    
1728
    
1713
    function getExtensionMode($ext)
1729
    function getExtensionMode($ext)
1714
    {
1730
    {
1715
        return @$this->_file_extensions[$ext];
1731
        return @$this->_file_extensions[$ext];
1716
    }
1732
    }
1717
 
1733
 
1718
    /**
1734
    /**
1719
     * Get the currently set timeout.
1735
     * Get the currently set timeout.
1720
     * Returns the actual timeout set.
1736
     * Returns the actual timeout set.
1721
     *
1737
     *
1722
     * @access public
1738
     * @access public
1723
     * @return int The actual timeout
1739
     * @return int The actual timeout
1724
     */
1740
     */
1725
    
1741
    
1726
    function getTimeout ( )
1742
    function getTimeout ( )
1727
    {
1743
    {
1728
        return ftp_get_option($this->_handle, FTP_TIMEOUT_SEC);
1744
        return ftp_get_option($this->_handle, FTP_TIMEOUT_SEC);
1729
    }    
1745
    }    
1730
 
1746
 
1731
    /**
1747
    /**
1732
     * Adds a Net_FTP_Observer instance to the list of observers 
1748
     * Adds a Net_FTP_Observer instance to the list of observers 
1733
     * that are listening for messages emitted by this Net_FTP instance.
1749
     * that are listening for messages emitted by this Net_FTP instance.
1734
     *
1750
     *
1735
     * @param   object   $observer     The Net_FTP_Observer instance to attach 
1751
     * @param   object   $observer     The Net_FTP_Observer instance to attach 
1736
     *                                 as a listener.
1752
     *                                 as a listener.
1737
     * @return  boolean                True if the observer is successfully attached.
1753
     * @return  boolean                True if the observer is successfully attached.
1738
     * @access  public
1754
     * @access  public
1739
     * @since   1.3
1755
     * @since   1.3
1740
     */
1756
     */
1741
    
1757
    
1742
    function attach(&$observer)
1758
    function attach(&$observer)
1743
    {
1759
    {
1744
        if (!is_a($observer, 'Net_FTP_Observer')) {
1760
        if (!is_a($observer, 'Net_FTP_Observer')) {
1745
            return false;
1761
            return false;
1746
        }
1762
        }
1747
 
1763
 
1748
        $this->_listeners[$observer->getId()] = &$observer;
1764
        $this->_listeners[$observer->getId()] = &$observer;
1749
        return true;
1765
        return true;
1750
    }
1766
    }
1751
 
1767
 
1752
    /**
1768
    /**
1753
     * Removes a Net_FTP_Observer instance from the list of observers.
1769
     * Removes a Net_FTP_Observer instance from the list of observers.
1754
     *
1770
     *
1755
     * @param   object   $observer     The Net_FTP_Observer instance to detach 
1771
     * @param   object   $observer     The Net_FTP_Observer instance to detach 
1756
     *                                 from the list of listeners.
1772
     *                                 from the list of listeners.
1757
     * @return  boolean                True if the observer is successfully detached.
1773
     * @return  boolean                True if the observer is successfully detached.
1758
     * @access  public
1774
     * @access  public
1759
     * @since   1.3
1775
     * @since   1.3
1760
     */
1776
     */
1761
    
1777
    
1762
    function detach($observer)
1778
    function detach($observer)
1763
    {
1779
    {
1764
        if (!is_a($observer, 'Net_FTP_Observer') ||
1780
        if (!is_a($observer, 'Net_FTP_Observer') ||
1765
            !isset($this->_listeners[$observer->getId()])) {
1781
            !isset($this->_listeners[$observer->getId()])) {
1766
            return false;
1782
            return false;
1767
        }
1783
        }
1768
 
1784
 
1769
        unset($this->_listeners[$observer->getId()]);
1785
        unset($this->_listeners[$observer->getId()]);
1770
        return true;
1786
        return true;
1771
    }
1787
    }
1772
 
1788
 
1773
    /**
1789
    /**
1774
     * Informs each registered observer instance that a new message has been
1790
     * Informs each registered observer instance that a new message has been
1775
     * sent.                                                                
1791
     * sent.                                                                
1776
     *                                                                      
1792
     *                                                                      
1777
     * @param   mixed     $event       A hash describing the net event.   
1793
     * @param   mixed     $event       A hash describing the net event.   
1778
     * @access  private                                                     
1794
     * @access  private                                                     
1779
     * @since   1.3                                                         
1795
     * @since   1.3                                                         
1780
     */                                                                     
1796
     */                                                                     
1781
    
1797
    
1782
    function _announce($event)
1798
    function _announce($event)
1783
    {
1799
    {
1784
        foreach ($this->_listeners as $id => $listener) {
1800
        foreach ($this->_listeners as $id => $listener) {
1785
            $this->_listeners[$id]->notify($event);
1801
            $this->_listeners[$id]->notify($event);
1786
        }
1802
        }
1787
    }
1803
    }
1788
    
1804
    
1789
        /**
1805
        /**
1790
     * Rebuild the path, if given relative
1806
     * Rebuild the path, if given relative
1791
     *
1807
     *
1792
     * @access  private
1808
     * @access  private
1793
     * @param   string $path   The path to check and construct
1809
     * @param   string $path   The path to check and construct
1794
     * @return  string         The build path
1810
     * @return  string         The build path
1795
     */
1811
     */
1796
    
1812
    
1797
    function _construct_path($path)
1813
    function _construct_path($path)
1798
    {
1814
    {
1799
        if ((substr($path, 0, 1) != "/") && (substr($path, 0, 2) != "./")) {
1815
        if ((substr($path, 0, 1) != "/") && (substr($path, 0, 2) != "./")) {
1800
            $actual_dir = @ftp_pwd($this->_handle);
1816
            $actual_dir = @ftp_pwd($this->_handle);
1801
            if (substr($actual_dir, (strlen($actual_dir) - 2), 1) != "/") {
1817
            if (substr($actual_dir, (strlen($actual_dir) - 2), 1) != "/") {
1802
                $actual_dir .= "/";
1818
                $actual_dir .= "/";
1803
            }
1819
            }
1804
            $path = $actual_dir.$path;
1820
            $path = $actual_dir.$path;
1805
        }
1821
        }
1806
        return $path;
1822
        return $path;
1807
    }
1823
    }
1808
 
1824
 
1809
    /**
1825
    /**
1810
     * Checks, whether a given string is a directory-path (ends with "/") or not.
1826
     * Checks, whether a given string is a directory-path (ends with "/") or not.
1811
     *
1827
     *
1812
     * @access  private
1828
     * @access  private
1813
     * @param   string $path  Path to check
1829
     * @param   string $path  Path to check
1814
     * @return  bool          True if $path is a directory, otherwise false
1830
     * @return  bool          True if $path is a directory, otherwise false
1815
     */
1831
     */
1816
    
1832
    
1817
    function _check_dir($path)
1833
    function _check_dir($path)
1818
    {
1834
    {
1819
        if (substr($path, (strlen($path) - 1), 1) == "/") {
1835
        if (!empty($path) && substr($path, (strlen($path) - 1), 1) == "/") {
1820
            return true;
1836
            return true;
1821
        } else {
1837
        } else {
1822
            return false;
1838
            return false;
1823
        }
1839
        }
1824
    }
1840
    }
1825
 
1841
 
1826
    /**
1842
    /**
1827
     * This will remove a file
1843
     * This will remove a file
1828
     *
1844
     *
1829
     * @access  private
1845
     * @access  private
1830
     * @param   string $file   The file to delete
1846
     * @param   string $file   The file to delete
1831
     * @return  mixed          True on success, otherwise PEAR::Error
1847
     * @return  mixed          True on success, otherwise PEAR::Error
1832
     * @see     NET_FTP_ERR_DELETEFILE_FAILED
1848
     * @see     NET_FTP_ERR_DELETEFILE_FAILED
1833
     */
1849
     */
1834
    
1850
    
1835
    function _rm_file($file)
1851
    function _rm_file($file)
1836
    {
1852
    {
1837
        if (substr($file, 0, 1) != "/") {
1853
        if (substr($file, 0, 1) != "/") {
1838
            $actual_dir = @ftp_pwd($this->_handle);
1854
            $actual_dir = @ftp_pwd($this->_handle);
1839
            if (substr($actual_dir, (strlen($actual_dir) - 2), 1) != "/") {
1855
            if (substr($actual_dir, (strlen($actual_dir) - 2), 1) != "/") {
1840
                $actual_dir .= "/";
1856
                $actual_dir .= "/";
1841
            }
1857
            }
1842
            $file = $actual_dir.$file;
1858
            $file = $actual_dir.$file;
1843
        }
1859
        }
1844
        $res = @ftp_delete($this->_handle, $file);
1860
        $res = @ftp_delete($this->_handle, $file);
1845
        
1861
        
1846
        if (!$res) {
1862
        if (!$res) {
1847
            return $this->raiseError("Could not delete file '$file'.", NET_FTP_ERR_DELETEFILE_FAILED);
1863
            return $this->raiseError("Could not delete file '$file'.", NET_FTP_ERR_DELETEFILE_FAILED);
1848
        } else {
1864
        } else {
1849
            return true;
1865
            return true;
1850
        }
1866
        }
1851
    }
1867
    }
1852
 
1868
 
1853
    /**
1869
    /**
1854
     * This will remove a dir
1870
     * This will remove a dir
1855
     *
1871
     *
1856
     * @access  private
1872
     * @access  private
1857
     * @param   string $dir  The dir to delete
1873
     * @param   string $dir  The dir to delete
1858
     * @return  mixed        True on success, otherwise PEAR::Error
1874
     * @return  mixed        True on success, otherwise PEAR::Error
1859
     * @see     NET_FTP_ERR_REMOTEPATHNODIR, NET_FTP_ERR_DELETEDIR_FAILED
1875
     * @see     NET_FTP_ERR_REMOTEPATHNODIR, NET_FTP_ERR_DELETEDIR_FAILED
1860
     */
1876
     */
1861
    
1877
    
1862
    function _rm_dir($dir)
1878
    function _rm_dir($dir)
1863
    {
1879
    {
1864
        if (substr($dir, (strlen($dir) - 1), 1) != "/") {
1880
        if (substr($dir, (strlen($dir) - 1), 1) != "/") {
1865
            return $this->raiseError("Directory name '$dir' is invalid, has to end with '/'", NET_FTP_ERR_REMOTEPATHNODIR);
1881
            return $this->raiseError("Directory name '$dir' is invalid, has to end with '/'", NET_FTP_ERR_REMOTEPATHNODIR);
1866
        }
1882
        }
1867
        $res = @ftp_rmdir($this->_handle, $dir);
1883
        $res = @ftp_rmdir($this->_handle, $dir);
1868
        if (!$res) {
1884
        if (!$res) {
1869
            return $this->raiseError("Could not delete directory '$dir'.", NET_FTP_ERR_DELETEDIR_FAILED);
1885
            return $this->raiseError("Could not delete directory '$dir'.", NET_FTP_ERR_DELETEDIR_FAILED);
1870
        } else {
1886
        } else {
1871
            return true;
1887
            return true;
1872
        }
1888
        }
1873
    }
1889
    }
1874
 
1890
 
1875
    /**
1891
    /**
1876
     * This will remove a dir and all subdirs and -files
1892
     * This will remove a dir and all subdirs and -files
1877
     *
1893
     *
1878
     * @access  private
1894
     * @access  private
1879
     * @param   string $file  The dir to delete recursively
1895
     * @param   string $file  The dir to delete recursively
1880
     * @return  mixed         True on success, otherwise PEAR::Error
1896
     * @return  mixed         True on success, otherwise PEAR::Error
1881
     * @see     NET_FTP_ERR_REMOTEPATHNODIR, NET_FTP_ERR_DELETEDIR_FAILED
1897
     * @see     NET_FTP_ERR_REMOTEPATHNODIR, NET_FTP_ERR_DELETEDIR_FAILED
1882
     */
1898
     */
1883
    
1899
    
1884
    function _rm_dir_recursive($dir)
1900
    function _rm_dir_recursive($dir)
1885
    {
1901
    {
1886
        if (substr($dir, (strlen($dir) - 1), 1) != "/") {
1902
        if (substr($dir, (strlen($dir) - 1), 1) != "/") {
1887
            return $this->raiseError("Directory name '$dir' is invalid, has to end with '/'", NET_FTP_ERR_REMOTEPATHNODIR);
1903
            return $this->raiseError("Directory name '$dir' is invalid, has to end with '/'", NET_FTP_ERR_REMOTEPATHNODIR);
1888
        }
1904
        }
1889
        $file_list = $this->_ls_files($dir);
1905
        $file_list = $this->_ls_files($dir);
1890
        foreach ($file_list as $file) {
1906
        foreach ($file_list as $file) {
1891
            $file = $dir.$file["name"];
1907
            $file = $dir.$file["name"];
1892
            $res = $this->rm($file);
1908
            $res = $this->rm($file);
1893
            if ($this->isError($res)) {
1909
            if ($this->isError($res)) {
1894
                return $res;
1910
                return $res;
1895
            }
1911
            }
1896
        }
1912
        }
1897
        $dir_list = $this->_ls_dirs($dir);
1913
        $dir_list = $this->_ls_dirs($dir);
1898
        foreach ($dir_list as $new_dir) {
1914
        foreach ($dir_list as $new_dir) {
-
 
1915
            if ($new_dir == '.' || $new_dir == '..') {
-
 
1916
                continue;
-
 
1917
            }
1899
            $new_dir = $dir.$new_dir["name"]."/";
1918
            $new_dir = $dir.$new_dir["name"]."/";
1900
            $res = $this->_rm_dir_recursive($new_dir);
1919
            $res = $this->_rm_dir_recursive($new_dir);
1901
            if ($this->isError($res)) {
1920
            if ($this->isError($res)) {
1902
                return $res;
1921
                return $res;
1903
            }
1922
            }
1904
        }
1923
        }
1905
        $res = $this->_rm_dir($dir);
1924
        $res = $this->_rm_dir($dir);
1906
        if (PEAR::isError($res)) {
1925
        if (PEAR::isError($res)) {
1907
            return $res;
1926
            return $res;
1908
        } else {
1927
        } else {
1909
            return true;
1928
            return true;
1910
        }
1929
        }
1911
    }
1930
    }
1912
 
1931
 
1913
    /**
1932
    /**
1914
     * Lists up files and directories
1933
     * Lists up files and directories
1915
     *
1934
     *
1916
     * @access  private
1935
     * @access  private
1917
     * @param   string $dir  The directory to list up
1936
     * @param   string $dir  The directory to list up
1918
     * @return  array        An array of dirs and files
1937
     * @return  array        An array of dirs and files
1919
     */
1938
     */
1920
    
1939
    
1921
    function _ls_both($dir)
1940
    function _ls_both($dir)
1922
    {
1941
    {
1923
        $list_splitted = $this->_list_and_parse($dir);
1942
        $list_splitted = $this->_list_and_parse($dir);
-
 
1943
        if (PEAR::isError($list_splitted)) {
-
 
1944
            return $list_splitted;
-
 
1945
        }
1924
        if (!is_array($list_splitted["files"])) {
1946
        if (!is_array($list_splitted["files"])) {
1925
            $list_splitted["files"] = array();
1947
            $list_splitted["files"] = array();
1926
        }
1948
        }
1927
        if (!is_array($list_splitted["dirs"])) {
1949
        if (!is_array($list_splitted["dirs"])) {
1928
            $list_splitted["dirs"] = array();
1950
            $list_splitted["dirs"] = array();
1929
        }
1951
        }
1930
        $res = array();
1952
        $res = array();
1931
        @array_splice($res, 0, 0, $list_splitted["files"]);
1953
        @array_splice($res, 0, 0, $list_splitted["files"]);
1932
        @array_splice($res, 0, 0, $list_splitted["dirs"]);
1954
        @array_splice($res, 0, 0, $list_splitted["dirs"]);
1933
        return $res;
1955
        return $res;
1934
    }
1956
    }
1935
 
1957
 
1936
    /**
1958
    /**
1937
     * Lists up directories
1959
     * Lists up directories
1938
     *
1960
     *
1939
     * @access  private
1961
     * @access  private
1940
     * @param   string $dir  The directory to list up
1962
     * @param   string $dir  The directory to list up
1941
     * @return  array        An array of dirs
1963
     * @return  array        An array of dirs
1942
     */
1964
     */
1943
    
1965
    
1944
    function _ls_dirs($dir)
1966
    function _ls_dirs($dir)
1945
    {
1967
    {
1946
        $list = $this->_list_and_parse($dir);
1968
        $list = $this->_list_and_parse($dir);
1947
        if (PEAR::isError($list)) {
1969
        if (PEAR::isError($list)) {
1948
            return $list;
1970
            return $list;
1949
        }
1971
        }
1950
        return $list["dirs"];
1972
        return $list["dirs"];
1951
    }
1973
    }
1952
 
1974
 
1953
    /**
1975
    /**
1954
     * Lists up files
1976
     * Lists up files
1955
     *
1977
     *
1956
     * @access  private
1978
     * @access  private
1957
     * @param   string $dir  The directory to list up
1979
     * @param   string $dir  The directory to list up
1958
     * @return  array        An array of files
1980
     * @return  array        An array of files
1959
     */
1981
     */
1960
    
1982
    
1961
    function _ls_files($dir)
1983
    function _ls_files($dir)
1962
    {
1984
    {
1963
        $list = $this->_list_and_parse($dir);
1985
        $list = $this->_list_and_parse($dir);
1964
        if (PEAR::isError($list)) {
1986
        if (PEAR::isError($list)) {
1965
            return $list;
1987
            return $list;
1966
        }
1988
        }
1967
        return $list["files"];
1989
        return $list["files"];
1968
    }
1990
    }
1969
 
1991
 
1970
    /**
1992
    /**
1971
     * This lists up the directory-content and parses the items into well-formated arrays
1993
     * This lists up the directory-content and parses the items into well-formated arrays
1972
     * The results of this array are sorted (dirs on top, sorted by name;
1994
     * The results of this array are sorted (dirs on top, sorted by name;
1973
     * files below, sorted by name).
1995
     * files below, sorted by name).
1974
     *
1996
     *
1975
     * @access  private
1997
     * @access  private
1976
     * @param   string $dir  The directory to parse
1998
     * @param   string $dir  The directory to parse
1977
     * @return  array        Lists of dirs and files
1999
     * @return  array        Lists of dirs and files
1978
     * @see     NET_FTP_ERR_RAWDIRLIST_FAILED
2000
     * @see     NET_FTP_ERR_RAWDIRLIST_FAILED
1979
     */
2001
     */
1980
    
2002
    
1981
    function _list_and_parse($dir)
2003
    function _list_and_parse($dir)
1982
    {
2004
    {
1983
        $dirs_list = array();
2005
        $dirs_list = array();
1984
        $files_list = array();
2006
        $files_list = array();
1985
        $dir_list = @ftp_rawlist($this->_handle, $dir);
2007
        $dir_list = @ftp_rawlist($this->_handle, $dir);
1986
        if ($dir_list === false) {
2008
        if (!is_array($dir_list)) {
1987
            return PEAR::raiseError('Could not get raw directory listing.', NET_FTP_ERR_RAWDIRLIST_FAILED);
2009
            return PEAR::raiseError('Could not get raw directory listing.', NET_FTP_ERR_RAWDIRLIST_FAILED);
1988
        }
2010
        }
-
 
2011
        // Handle empty directories
-
 
2012
        if (count($dir_list) == 0) {
-
 
2013
            return array('dirs' => $dirs_list, 'files' => $files_list);
-
 
2014
        }
-
 
2015
 
-
 
2016
        // Exception for some FTP servers seem to return this wiered result instead of an empty list
-
 
2017
        if (count($dirs_list) == 1 && $dirs_list[0] == 'total 0') {
-
 
2018
            return array('dirs' => array(), 'files' => $files_list);
-
 
2019
        }
-
 
2020
        
1989
        if (!isset($this->_matcher) || PEAR::isError($this->_matcher)) {
2021
        if (!isset($this->_matcher) || PEAR::isError($this->_matcher)) {
1990
            $this->_matcher = $this->_determine_os_match($dir_list);
2022
            $this->_matcher = $this->_determine_os_match($dir_list);
1991
            if (PEAR::isError($this->_matcher)) {
2023
            if (PEAR::isError($this->_matcher)) {
1992
                return $this->_matcher;
2024
                return $this->_matcher;
1993
            }
2025
            }
1994
        }
2026
        }
1995
        foreach ($dir_list as $entry) {
2027
        foreach ($dir_list as $entry) {
1996
            if (!preg_match($this->_matcher['pattern'], $entry, $m)) {
2028
            if (!preg_match($this->_matcher['pattern'], $entry, $m)) {
1997
                continue;
2029
                continue;
1998
            }
2030
            }
1999
            $entry = array();
2031
            $entry = array();
2000
            foreach ($this->_matcher['map'] as $key=>$val) {
2032
            foreach ($this->_matcher['map'] as $key=>$val) {
2001
                $entry[$key] = $m[$val];
2033
                $entry[$key] = $m[$val];
2002
            }
2034
            }
2003
            $entry['stamp'] = $this->_parse_Date($entry['date']);
2035
            $entry['stamp'] = $this->_parse_Date($entry['date']);
2004
 
2036
 
2005
            if ($entry['is_dir']) {
2037
            if ($entry['is_dir']) {
2006
                $dirs_list[] = $entry;
2038
                $dirs_list[] = $entry;
2007
            } else {
2039
            } else {
2008
                $files_list[] = $entry;
2040
                $files_list[] = $entry;
2009
            }
2041
            }
2010
        }
2042
        }
2011
        @usort($dirs_list, array("Net_FTP", "_nat_sort"));
2043
        @usort($dirs_list, array("Net_FTP", "_nat_sort"));
2012
        @usort($files_list, array("Net_FTP", "_nat_sort"));
2044
        @usort($files_list, array("Net_FTP", "_nat_sort"));
2013
        $res["dirs"] = (is_array($dirs_list)) ? $dirs_list : array();
2045
        $res["dirs"] = (is_array($dirs_list)) ? $dirs_list : array();
2014
        $res["files"] = (is_array($files_list)) ? $files_list : array();
2046
        $res["files"] = (is_array($files_list)) ? $files_list : array();
2015
        return $res;
2047
        return $res;
2016
    }
2048
    }
2017
    
2049
    
2018
    /**
2050
    /**
2019
     * Determine server OS
2051
     * Determine server OS
2020
     * This determines the server OS and returns a valid regex to parse
2052
     * This determines the server OS and returns a valid regex to parse
2021
     * ls() output.
2053
     * ls() output.
2022
     *
2054
     *
2023
     * @access  private
2055
     * @access  private
2024
     * @param   array $dir_list The raw dir list to parse
2056
     * @param   array $dir_list The raw dir list to parse
2025
     * @return  mixed An array of 'pattern' and 'map' on success, otherwise PEAR::Error
2057
     * @return  mixed An array of 'pattern' and 'map' on success, otherwise PEAR::Error
2026
     * @see     NET_FTP_ERR_DIRLIST_UNSUPPORTED
2058
     * @see     NET_FTP_ERR_DIRLIST_UNSUPPORTED
2027
     */
2059
     */
2028
    
2060
    
2029
    function _determine_os_match(&$dir_list) {
2061
    function _determine_os_match(&$dir_list) {
2030
    foreach ($dir_list as $entry) {
2062
    foreach ($dir_list as $entry) {
2031
        foreach ($this->_ls_match as $os => $match) {
2063
        foreach ($this->_ls_match as $os => $match) {
2032
            if (preg_match($match['pattern'], $entry)) {
2064
            if (preg_match($match['pattern'], $entry)) {
2033
                    return $match;
2065
                    return $match;
2034
                }
2066
                }
2035
            }
2067
            }
2036
    }
2068
    }
2037
        $error = 'The list style of your server seems not to be supported. Please email a "$ftp->ls(NET_FTP_RAWLIST);" output plus info on the server to the maintainer of this package to get it supported! Thanks for your help!';
2069
        $error = 'The list style of your server seems not to be supported. Please email a "$ftp->ls(NET_FTP_RAWLIST);" output plus info on the server to the maintainer of this package to get it supported! Thanks for your help!';
2038
        return PEAR::raiseError($error, NET_FTP_ERR_DIRLIST_UNSUPPORTED);
2070
        return PEAR::raiseError($error, NET_FTP_ERR_DIRLIST_UNSUPPORTED);
2039
    }
2071
    }
2040
    /**
2072
    /**
2041
     * Lists a local directory
2073
     * Lists a local directory
2042
     *
2074
     *
2043
     * @access  private
2075
     * @access  private
2044
     * @param   string $dir_path  The dir to list
2076
     * @param   string $dir_path  The dir to list
2045
     * @return  array             The list of dirs and files
2077
     * @return  array             The list of dirs and files
2046
     */
2078
     */
2047
    
2079
    
2048
    function _ls_local($dir_path)
2080
    function _ls_local($dir_path)
2049
    {
2081
    {
2050
        $dir = dir($dir_path);
2082
        $dir = dir($dir_path);
2051
        $dir_list = array();
2083
        $dir_list = array();
2052
        $file_list = array();
2084
        $file_list = array();
2053
        while (false !== ($entry = $dir->read())) {
2085
        while (false !== ($entry = $dir->read())) {
2054
            if (($entry != '.') && ($entry != '..')) {
2086
            if (($entry != '.') && ($entry != '..')) {
2055
                if (is_dir($dir_path.$entry)) {
2087
                if (is_dir($dir_path.$entry)) {
2056
                    $dir_list[] = $entry;
2088
                    $dir_list[] = $entry;
2057
                } else {
2089
                } else {
2058
                    $file_list[] = $entry;
2090
                    $file_list[] = $entry;
2059
                }
2091
                }
2060
            }
2092
            }
2061
        }
2093
        }
2062
        $dir->close();
2094
        $dir->close();
2063
        $res['dirs'] = $dir_list;
2095
        $res['dirs'] = $dir_list;
2064
        $res['files'] = $file_list;
2096
        $res['files'] = $file_list;
2065
        return $res;
2097
        return $res;
2066
    }
2098
    }
2067
 
2099
 
2068
    /**
2100
    /**
2069
     * Function for use with usort().
2101
     * Function for use with usort().
2070
     * Compares the list-array-elements by name.
2102
     * Compares the list-array-elements by name.
2071
     *
2103
     *
2072
     * @access  private
2104
     * @access  private
2073
     */
2105
     */
2074
    
2106
    
2075
    function _nat_sort($item_1, $item_2)
2107
    function _nat_sort($item_1, $item_2)
2076
    {
2108
    {
2077
        return strnatcmp($item_1['name'], $item_2['name']);
2109
        return strnatcmp($item_1['name'], $item_2['name']);
2078
    }
2110
    }
2079
 
2111
 
2080
    /**
2112
    /**
2081
     * Parse dates to timestamps
2113
     * Parse dates to timestamps
2082
     *
2114
     *
2083
     * @access  private
2115
     * @access  private
2084
     * @param   string $date  Date
2116
     * @param   string $date  Date
2085
     * @return  int           Timestamp
2117
     * @return  int           Timestamp
2086
     * @see     NET_FTP_ERR_DATEFORMAT_FAILED
2118
     * @see     NET_FTP_ERR_DATEFORMAT_FAILED
2087
     */
2119
     */
2088
    
2120
    
2089
    function _parse_Date($date)
2121
    function _parse_Date($date)
2090
    {
2122
    {
2091
        // Sep 10 22:06 => Sep 10, <year> 22:06
2123
        // Sep 10 22:06 => Sep 10, <year> 22:06
2092
        if (preg_match('/([A-Za-z]+)[ ]+([0-9]+)[ ]+([0-9]+):([0-9]+)/', $date, $res)) {
2124
        if (preg_match('/([A-Za-z]+)[ ]+([0-9]+)[ ]+([0-9]+):([0-9]+)/', $date, $res)) {
2093
            $year = date('Y');
2125
            $year = date('Y');
2094
            $month = $res[1];
2126
            $month = $res[1];
2095
            $day = $res[2];
2127
            $day = $res[2];
2096
            $hour = $res[3];
2128
            $hour = $res[3];
2097
            $minute = $res[4];
2129
            $minute = $res[4];
2098
            $date = "$month $day, $year $hour:$minute";
2130
            $date = "$month $day, $year $hour:$minute";
2099
            $tmpDate = strtotime($date);
2131
            $tmpDate = strtotime($date);
2100
            if ($tmpDate > time()) {
2132
            if ($tmpDate > time()) {
2101
                $year--;
2133
                $year--;
2102
                $date = "$month $day, $year $hour:$minute";
2134
                $date = "$month $day, $year $hour:$minute";
2103
            }
2135
            }
2104
        }
2136
        }
2105
        // 09-10-04 => 09/10/04
2137
        // 09-10-04 => 09/10/04
2106
        elseif (preg_match('/^\d\d-\d\d-\d\d/',$date)) {
2138
        elseif (preg_match('/^\d\d-\d\d-\d\d/',$date)) {
2107
            $date = str_replace('-','/',$date);
2139
            $date = str_replace('-','/',$date);
2108
        }
2140
        }
2109
        $res = strtotime($date);
2141
        $res = strtotime($date);
2110
        if (!$res) {
2142
        if (!$res) {
2111
            return $this->raiseError('Dateconversion failed.', NET_FTP_ERR_DATEFORMAT_FAILED);
2143
            return $this->raiseError('Dateconversion failed.', NET_FTP_ERR_DATEFORMAT_FAILED);
2112
        }
2144
        }
2113
        return $res;
2145
        return $res;
2114
    }
2146
    }
2115
}
2147
}
2116
?>
2148
?>