1 /*
2 +----------------------------------------------------------------------+
3 | PHP Version 7 |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 1997-2018 The PHP Group |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
15 | Authors: Andrew Skalski <askalski@chek.com> |
16 | Stefan Esser <sesser@php.net> (resume functions) |
17 +----------------------------------------------------------------------+
18 */
19
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include "php.h"
25
26 #ifdef HAVE_FTP_SSL
27 # include <openssl/ssl.h>
28 #endif
29
30 #if HAVE_FTP
31
32 #include "ext/standard/info.h"
33 #include "ext/standard/file.h"
34
35 #include "php_ftp.h"
36 #include "ftp.h"
37
38 static int le_ftpbuf;
39 #define le_ftpbuf_name "FTP Buffer"
40
41 /* {{{ arginfo */
42 ZEND_BEGIN_ARG_INFO_EX(arginfo_ftp_connect, 0, 0, 1)
43 ZEND_ARG_INFO(0, host)
44 ZEND_ARG_INFO(0, port)
45 ZEND_ARG_INFO(0, timeout)
46 ZEND_END_ARG_INFO()
47
48 #ifdef HAVE_FTP_SSL
49 ZEND_BEGIN_ARG_INFO_EX(arginfo_ftp_ssl_connect, 0, 0, 1)
50 ZEND_ARG_INFO(0, host)
51 ZEND_ARG_INFO(0, port)
52 ZEND_ARG_INFO(0, timeout)
53 ZEND_END_ARG_INFO()
54 #endif
55
56 ZEND_BEGIN_ARG_INFO(arginfo_ftp_login, 0)
57 ZEND_ARG_INFO(0, ftp)
58 ZEND_ARG_INFO(0, username)
59 ZEND_ARG_INFO(0, password)
60 ZEND_END_ARG_INFO()
61
62 ZEND_BEGIN_ARG_INFO(arginfo_ftp_pwd, 0)
63 ZEND_ARG_INFO(0, ftp)
64 ZEND_END_ARG_INFO()
65
66 ZEND_BEGIN_ARG_INFO(arginfo_ftp_cdup, 0)
67 ZEND_ARG_INFO(0, ftp)
68 ZEND_END_ARG_INFO()
69
70 ZEND_BEGIN_ARG_INFO(arginfo_ftp_chdir, 0)
71 ZEND_ARG_INFO(0, ftp)
72 ZEND_ARG_INFO(0, directory)
73 ZEND_END_ARG_INFO()
74
75 ZEND_BEGIN_ARG_INFO(arginfo_ftp_exec, 0)
76 ZEND_ARG_INFO(0, ftp)
77 ZEND_ARG_INFO(0, command)
78 ZEND_END_ARG_INFO()
79
80 ZEND_BEGIN_ARG_INFO(arginfo_ftp_raw, 0)
81 ZEND_ARG_INFO(0, ftp)
82 ZEND_ARG_INFO(0, command)
83 ZEND_END_ARG_INFO()
84
85 ZEND_BEGIN_ARG_INFO(arginfo_ftp_mkdir, 0)
86 ZEND_ARG_INFO(0, ftp)
87 ZEND_ARG_INFO(0, directory)
88 ZEND_END_ARG_INFO()
89
90 ZEND_BEGIN_ARG_INFO(arginfo_ftp_rmdir, 0)
91 ZEND_ARG_INFO(0, ftp)
92 ZEND_ARG_INFO(0, directory)
93 ZEND_END_ARG_INFO()
94
95 ZEND_BEGIN_ARG_INFO(arginfo_ftp_chmod, 0)
96 ZEND_ARG_INFO(0, ftp)
97 ZEND_ARG_INFO(0, mode)
98 ZEND_ARG_INFO(0, filename)
99 ZEND_END_ARG_INFO()
100
101 ZEND_BEGIN_ARG_INFO_EX(arginfo_ftp_alloc, 0, 0, 2)
102 ZEND_ARG_INFO(0, ftp)
103 ZEND_ARG_INFO(0, size)
104 ZEND_ARG_INFO(1, response)
105 ZEND_END_ARG_INFO()
106
107 ZEND_BEGIN_ARG_INFO(arginfo_ftp_nlist, 0)
108 ZEND_ARG_INFO(0, ftp)
109 ZEND_ARG_INFO(0, directory)
110 ZEND_END_ARG_INFO()
111
112 ZEND_BEGIN_ARG_INFO_EX(arginfo_ftp_rawlist, 0, 0, 2)
113 ZEND_ARG_INFO(0, ftp)
114 ZEND_ARG_INFO(0, directory)
115 ZEND_ARG_INFO(0, recursive)
116 ZEND_END_ARG_INFO()
117
118 ZEND_BEGIN_ARG_INFO(arginfo_ftp_mlsd, 0)
119 ZEND_ARG_INFO(0, ftp)
120 ZEND_ARG_INFO(0, directory)
121 ZEND_END_ARG_INFO()
122
123 ZEND_BEGIN_ARG_INFO(arginfo_ftp_systype, 0)
124 ZEND_ARG_INFO(0, ftp)
125 ZEND_END_ARG_INFO()
126
127 ZEND_BEGIN_ARG_INFO_EX(arginfo_ftp_fget, 0, 0, 3)
128 ZEND_ARG_INFO(0, ftp)
129 ZEND_ARG_INFO(0, fp)
130 ZEND_ARG_INFO(0, remote_file)
131 ZEND_ARG_INFO(0, mode)
132 ZEND_ARG_INFO(0, resumepos)
133 ZEND_END_ARG_INFO()
134
135 ZEND_BEGIN_ARG_INFO_EX(arginfo_ftp_nb_fget, 0, 0, 3)
136 ZEND_ARG_INFO(0, ftp)
137 ZEND_ARG_INFO(0, fp)
138 ZEND_ARG_INFO(0, remote_file)
139 ZEND_ARG_INFO(0, mode)
140 ZEND_ARG_INFO(0, resumepos)
141 ZEND_END_ARG_INFO()
142
143 ZEND_BEGIN_ARG_INFO_EX(arginfo_ftp_pasv, 0, 0, 2)
144 ZEND_ARG_INFO(0, ftp)
145 ZEND_ARG_INFO(0, pasv)
146 ZEND_END_ARG_INFO()
147
148 ZEND_BEGIN_ARG_INFO_EX(arginfo_ftp_get, 0, 0, 3)
149 ZEND_ARG_INFO(0, ftp)
150 ZEND_ARG_INFO(0, local_file)
151 ZEND_ARG_INFO(0, remote_file)
152 ZEND_ARG_INFO(0, mode)
153 ZEND_ARG_INFO(0, resume_pos)
154 ZEND_END_ARG_INFO()
155
156 ZEND_BEGIN_ARG_INFO_EX(arginfo_ftp_nb_get, 0, 0, 3)
157 ZEND_ARG_INFO(0, ftp)
158 ZEND_ARG_INFO(0, local_file)
159 ZEND_ARG_INFO(0, remote_file)
160 ZEND_ARG_INFO(0, mode)
161 ZEND_ARG_INFO(0, resume_pos)
162 ZEND_END_ARG_INFO()
163
164 ZEND_BEGIN_ARG_INFO(arginfo_ftp_nb_continue, 0)
165 ZEND_ARG_INFO(0, ftp)
166 ZEND_END_ARG_INFO()
167
168 ZEND_BEGIN_ARG_INFO_EX(arginfo_ftp_fput, 0, 0, 3)
169 ZEND_ARG_INFO(0, ftp)
170 ZEND_ARG_INFO(0, remote_file)
171 ZEND_ARG_INFO(0, fp)
172 ZEND_ARG_INFO(0, mode)
173 ZEND_ARG_INFO(0, startpos)
174 ZEND_END_ARG_INFO()
175
176 ZEND_BEGIN_ARG_INFO_EX(arginfo_ftp_nb_fput, 0, 0, 3)
177 ZEND_ARG_INFO(0, ftp)
178 ZEND_ARG_INFO(0, remote_file)
179 ZEND_ARG_INFO(0, fp)
180 ZEND_ARG_INFO(0, mode)
181 ZEND_ARG_INFO(0, startpos)
182 ZEND_END_ARG_INFO()
183
184 ZEND_BEGIN_ARG_INFO_EX(arginfo_ftp_put, 0, 0, 3)
185 ZEND_ARG_INFO(0, ftp)
186 ZEND_ARG_INFO(0, remote_file)
187 ZEND_ARG_INFO(0, local_file)
188 ZEND_ARG_INFO(0, mode)
189 ZEND_ARG_INFO(0, startpos)
190 ZEND_END_ARG_INFO()
191
192 ZEND_BEGIN_ARG_INFO_EX(arginfo_ftp_append, 0, 0, 3)
193 ZEND_ARG_INFO(0, ftp)
194 ZEND_ARG_INFO(0, remote_file)
195 ZEND_ARG_INFO(0, local_file)
196 ZEND_ARG_INFO(0, mode)
197 ZEND_END_ARG_INFO()
198
199 ZEND_BEGIN_ARG_INFO_EX(arginfo_ftp_nb_put, 0, 0, 3)
200 ZEND_ARG_INFO(0, ftp)
201 ZEND_ARG_INFO(0, remote_file)
202 ZEND_ARG_INFO(0, local_file)
203 ZEND_ARG_INFO(0, mode)
204 ZEND_ARG_INFO(0, startpos)
205 ZEND_END_ARG_INFO()
206
207 ZEND_BEGIN_ARG_INFO(arginfo_ftp_size, 0)
208 ZEND_ARG_INFO(0, ftp)
209 ZEND_ARG_INFO(0, filename)
210 ZEND_END_ARG_INFO()
211
212 ZEND_BEGIN_ARG_INFO(arginfo_ftp_mdtm, 0)
213 ZEND_ARG_INFO(0, ftp)
214 ZEND_ARG_INFO(0, filename)
215 ZEND_END_ARG_INFO()
216
217 ZEND_BEGIN_ARG_INFO(arginfo_ftp_rename, 0)
218 ZEND_ARG_INFO(0, ftp)
219 ZEND_ARG_INFO(0, src)
220 ZEND_ARG_INFO(0, dest)
221 ZEND_END_ARG_INFO()
222
223 ZEND_BEGIN_ARG_INFO(arginfo_ftp_delete, 0)
224 ZEND_ARG_INFO(0, ftp)
225 ZEND_ARG_INFO(0, file)
226 ZEND_END_ARG_INFO()
227
228 ZEND_BEGIN_ARG_INFO(arginfo_ftp_site, 0)
229 ZEND_ARG_INFO(0, ftp)
230 ZEND_ARG_INFO(0, cmd)
231 ZEND_END_ARG_INFO()
232
233 ZEND_BEGIN_ARG_INFO(arginfo_ftp_close, 0)
234 ZEND_ARG_INFO(0, ftp)
235 ZEND_END_ARG_INFO()
236
237 ZEND_BEGIN_ARG_INFO(arginfo_ftp_set_option, 0)
238 ZEND_ARG_INFO(0, ftp)
239 ZEND_ARG_INFO(0, option)
240 ZEND_ARG_INFO(0, value)
241 ZEND_END_ARG_INFO()
242
243 ZEND_BEGIN_ARG_INFO(arginfo_ftp_get_option, 0)
244 ZEND_ARG_INFO(0, ftp)
245 ZEND_ARG_INFO(0, option)
246 ZEND_END_ARG_INFO()
247
248 /* }}} */
249
250 static const zend_function_entry php_ftp_functions[] = {
251 PHP_FE(ftp_connect, arginfo_ftp_connect)
252 #ifdef HAVE_FTP_SSL
253 PHP_FE(ftp_ssl_connect, arginfo_ftp_ssl_connect)
254 #endif
255 PHP_FE(ftp_login, arginfo_ftp_login)
256 PHP_FE(ftp_pwd, arginfo_ftp_pwd)
257 PHP_FE(ftp_cdup, arginfo_ftp_cdup)
258 PHP_FE(ftp_chdir, arginfo_ftp_chdir)
259 PHP_FE(ftp_exec, arginfo_ftp_exec)
260 PHP_FE(ftp_raw, arginfo_ftp_raw)
261 PHP_FE(ftp_mkdir, arginfo_ftp_mkdir)
262 PHP_FE(ftp_rmdir, arginfo_ftp_rmdir)
263 PHP_FE(ftp_chmod, arginfo_ftp_chmod)
264 PHP_FE(ftp_alloc, arginfo_ftp_alloc)
265 PHP_FE(ftp_nlist, arginfo_ftp_nlist)
266 PHP_FE(ftp_rawlist, arginfo_ftp_rawlist)
267 PHP_FE(ftp_mlsd, arginfo_ftp_mlsd)
268 PHP_FE(ftp_systype, arginfo_ftp_systype)
269 PHP_FE(ftp_pasv, arginfo_ftp_pasv)
270 PHP_FE(ftp_get, arginfo_ftp_get)
271 PHP_FE(ftp_fget, arginfo_ftp_fget)
272 PHP_FE(ftp_put, arginfo_ftp_put)
273 PHP_FE(ftp_append, arginfo_ftp_append)
274 PHP_FE(ftp_fput, arginfo_ftp_fput)
275 PHP_FE(ftp_size, arginfo_ftp_size)
276 PHP_FE(ftp_mdtm, arginfo_ftp_mdtm)
277 PHP_FE(ftp_rename, arginfo_ftp_rename)
278 PHP_FE(ftp_delete, arginfo_ftp_delete)
279 PHP_FE(ftp_site, arginfo_ftp_site)
280 PHP_FE(ftp_close, arginfo_ftp_close)
281 PHP_FE(ftp_set_option, arginfo_ftp_set_option)
282 PHP_FE(ftp_get_option, arginfo_ftp_get_option)
283 PHP_FE(ftp_nb_fget, arginfo_ftp_nb_fget)
284 PHP_FE(ftp_nb_get, arginfo_ftp_nb_get)
285 PHP_FE(ftp_nb_continue, arginfo_ftp_nb_continue)
286 PHP_FE(ftp_nb_put, arginfo_ftp_nb_put)
287 PHP_FE(ftp_nb_fput, arginfo_ftp_nb_fput)
288 PHP_FALIAS(ftp_quit, ftp_close, arginfo_ftp_close)
289 PHP_FE_END
290 };
291
292 zend_module_entry php_ftp_module_entry = {
293 STANDARD_MODULE_HEADER_EX,
294 NULL,
295 NULL,
296 "ftp",
297 php_ftp_functions,
298 PHP_MINIT(ftp),
299 NULL,
300 NULL,
301 NULL,
302 PHP_MINFO(ftp),
303 PHP_FTP_VERSION,
304 STANDARD_MODULE_PROPERTIES
305 };
306
307 #if COMPILE_DL_FTP
ZEND_GET_MODULE(php_ftp)308 ZEND_GET_MODULE(php_ftp)
309 #endif
310
311 static void ftp_destructor_ftpbuf(zend_resource *rsrc)
312 {
313 ftpbuf_t *ftp = (ftpbuf_t *)rsrc->ptr;
314
315 ftp_close(ftp);
316 }
317
PHP_MINIT_FUNCTION(ftp)318 PHP_MINIT_FUNCTION(ftp)
319 {
320 #ifdef HAVE_FTP_SSL
321 SSL_library_init();
322 OpenSSL_add_all_ciphers();
323 OpenSSL_add_all_digests();
324 OpenSSL_add_all_algorithms();
325
326 SSL_load_error_strings();
327 #endif
328
329 le_ftpbuf = zend_register_list_destructors_ex(ftp_destructor_ftpbuf, NULL, le_ftpbuf_name, module_number);
330 REGISTER_LONG_CONSTANT("FTP_ASCII", FTPTYPE_ASCII, CONST_PERSISTENT | CONST_CS);
331 REGISTER_LONG_CONSTANT("FTP_TEXT", FTPTYPE_ASCII, CONST_PERSISTENT | CONST_CS);
332 REGISTER_LONG_CONSTANT("FTP_BINARY", FTPTYPE_IMAGE, CONST_PERSISTENT | CONST_CS);
333 REGISTER_LONG_CONSTANT("FTP_IMAGE", FTPTYPE_IMAGE, CONST_PERSISTENT | CONST_CS);
334 REGISTER_LONG_CONSTANT("FTP_AUTORESUME", PHP_FTP_AUTORESUME, CONST_PERSISTENT | CONST_CS);
335 REGISTER_LONG_CONSTANT("FTP_TIMEOUT_SEC", PHP_FTP_OPT_TIMEOUT_SEC, CONST_PERSISTENT | CONST_CS);
336 REGISTER_LONG_CONSTANT("FTP_AUTOSEEK", PHP_FTP_OPT_AUTOSEEK, CONST_PERSISTENT | CONST_CS);
337 REGISTER_LONG_CONSTANT("FTP_USEPASVADDRESS", PHP_FTP_OPT_USEPASVADDRESS, CONST_PERSISTENT | CONST_CS);
338 REGISTER_LONG_CONSTANT("FTP_FAILED", PHP_FTP_FAILED, CONST_PERSISTENT | CONST_CS);
339 REGISTER_LONG_CONSTANT("FTP_FINISHED", PHP_FTP_FINISHED, CONST_PERSISTENT | CONST_CS);
340 REGISTER_LONG_CONSTANT("FTP_MOREDATA", PHP_FTP_MOREDATA, CONST_PERSISTENT | CONST_CS);
341 return SUCCESS;
342 }
343
PHP_MINFO_FUNCTION(ftp)344 PHP_MINFO_FUNCTION(ftp)
345 {
346 php_info_print_table_start();
347 php_info_print_table_row(2, "FTP support", "enabled");
348 #ifdef HAVE_FTP_SSL
349 php_info_print_table_row(2, "FTPS support", "enabled");
350 #else
351 php_info_print_table_row(2, "FTPS support", "disabled");
352 #endif
353 php_info_print_table_end();
354 }
355
356 #define XTYPE(xtype, mode) { \
357 if (mode != FTPTYPE_ASCII && mode != FTPTYPE_IMAGE) { \
358 php_error_docref(NULL, E_WARNING, "Mode must be FTP_ASCII or FTP_BINARY"); \
359 RETURN_FALSE; \
360 } \
361 xtype = mode; \
362 }
363
364
365 /* {{{ proto resource ftp_connect(string host [, int port [, int timeout]])
366 Opens a FTP stream */
PHP_FUNCTION(ftp_connect)367 PHP_FUNCTION(ftp_connect)
368 {
369 ftpbuf_t *ftp;
370 char *host;
371 size_t host_len;
372 zend_long port = 0;
373 zend_long timeout_sec = FTP_DEFAULT_TIMEOUT;
374
375 if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|ll", &host, &host_len, &port, &timeout_sec) == FAILURE) {
376 return;
377 }
378
379 if (timeout_sec <= 0) {
380 php_error_docref(NULL, E_WARNING, "Timeout has to be greater than 0");
381 RETURN_FALSE;
382 }
383
384 /* connect */
385 if (!(ftp = ftp_open(host, (short)port, timeout_sec))) {
386 RETURN_FALSE;
387 }
388
389 /* autoseek for resuming */
390 ftp->autoseek = FTP_DEFAULT_AUTOSEEK;
391 ftp->usepasvaddress = FTP_DEFAULT_USEPASVADDRESS;
392 #ifdef HAVE_FTP_SSL
393 /* disable ssl */
394 ftp->use_ssl = 0;
395 #endif
396
397 RETURN_RES(zend_register_resource(ftp, le_ftpbuf));
398 }
399 /* }}} */
400
401 #ifdef HAVE_FTP_SSL
402 /* {{{ proto resource ftp_ssl_connect(string host [, int port [, int timeout]])
403 Opens a FTP-SSL stream */
PHP_FUNCTION(ftp_ssl_connect)404 PHP_FUNCTION(ftp_ssl_connect)
405 {
406 ftpbuf_t *ftp;
407 char *host;
408 size_t host_len;
409 zend_long port = 0;
410 zend_long timeout_sec = FTP_DEFAULT_TIMEOUT;
411
412 if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|ll", &host, &host_len, &port, &timeout_sec) == FAILURE) {
413 return;
414 }
415
416 if (timeout_sec <= 0) {
417 php_error_docref(NULL, E_WARNING, "Timeout has to be greater than 0");
418 RETURN_FALSE;
419 }
420
421 /* connect */
422 if (!(ftp = ftp_open(host, (short)port, timeout_sec))) {
423 RETURN_FALSE;
424 }
425
426 /* autoseek for resuming */
427 ftp->autoseek = FTP_DEFAULT_AUTOSEEK;
428 ftp->usepasvaddress = FTP_DEFAULT_USEPASVADDRESS;
429 /* enable ssl */
430 ftp->use_ssl = 1;
431
432 RETURN_RES(zend_register_resource(ftp, le_ftpbuf));
433 }
434 /* }}} */
435 #endif
436
437 /* {{{ proto bool ftp_login(resource stream, string username, string password)
438 Logs into the FTP server */
PHP_FUNCTION(ftp_login)439 PHP_FUNCTION(ftp_login)
440 {
441 zval *z_ftp;
442 ftpbuf_t *ftp;
443 char *user, *pass;
444 size_t user_len, pass_len;
445
446 if (zend_parse_parameters(ZEND_NUM_ARGS(), "rss", &z_ftp, &user, &user_len, &pass, &pass_len) == FAILURE) {
447 return;
448 }
449
450 if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
451 RETURN_FALSE;
452 }
453
454 /* log in */
455 if (!ftp_login(ftp, user, user_len, pass, pass_len)) {
456 php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
457 RETURN_FALSE;
458 }
459
460 RETURN_TRUE;
461 }
462 /* }}} */
463
464 /* {{{ proto string ftp_pwd(resource stream)
465 Returns the present working directory */
PHP_FUNCTION(ftp_pwd)466 PHP_FUNCTION(ftp_pwd)
467 {
468 zval *z_ftp;
469 ftpbuf_t *ftp;
470 const char *pwd;
471
472 if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &z_ftp) == FAILURE) {
473 return;
474 }
475
476 if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
477 RETURN_FALSE;
478 }
479
480 if (!(pwd = ftp_pwd(ftp))) {
481 php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
482 RETURN_FALSE;
483 }
484
485 RETURN_STRING((char*) pwd);
486 }
487 /* }}} */
488
489 /* {{{ proto bool ftp_cdup(resource stream)
490 Changes to the parent directory */
PHP_FUNCTION(ftp_cdup)491 PHP_FUNCTION(ftp_cdup)
492 {
493 zval *z_ftp;
494 ftpbuf_t *ftp;
495
496 if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &z_ftp) == FAILURE) {
497 return;
498 }
499
500 if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
501 RETURN_FALSE;
502 }
503
504 if (!ftp_cdup(ftp)) {
505 php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
506 RETURN_FALSE;
507 }
508
509 RETURN_TRUE;
510 }
511 /* }}} */
512
513 /* {{{ proto bool ftp_chdir(resource stream, string directory)
514 Changes directories */
PHP_FUNCTION(ftp_chdir)515 PHP_FUNCTION(ftp_chdir)
516 {
517 zval *z_ftp;
518 ftpbuf_t *ftp;
519 char *dir;
520 size_t dir_len;
521
522 if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs", &z_ftp, &dir, &dir_len) == FAILURE) {
523 return;
524 }
525
526 if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
527 RETURN_FALSE;
528 }
529
530 /* change directories */
531 if (!ftp_chdir(ftp, dir, dir_len)) {
532 php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
533 RETURN_FALSE;
534 }
535
536 RETURN_TRUE;
537 }
538 /* }}} */
539
540 /* {{{ proto bool ftp_exec(resource stream, string command)
541 Requests execution of a program on the FTP server */
PHP_FUNCTION(ftp_exec)542 PHP_FUNCTION(ftp_exec)
543 {
544 zval *z_ftp;
545 ftpbuf_t *ftp;
546 char *cmd;
547 size_t cmd_len;
548
549 if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs", &z_ftp, &cmd, &cmd_len) == FAILURE) {
550 return;
551 }
552
553 if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
554 RETURN_FALSE;
555 }
556
557 /* execute serverside command */
558 if (!ftp_exec(ftp, cmd, cmd_len)) {
559 php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
560 RETURN_FALSE;
561 }
562
563 RETURN_TRUE;
564 }
565 /* }}} */
566
567 /* {{{ proto array ftp_raw(resource stream, string command)
568 Sends a literal command to the FTP server */
PHP_FUNCTION(ftp_raw)569 PHP_FUNCTION(ftp_raw)
570 {
571 zval *z_ftp;
572 ftpbuf_t *ftp;
573 char *cmd;
574 size_t cmd_len;
575
576 if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs", &z_ftp, &cmd, &cmd_len) == FAILURE) {
577 return;
578 }
579
580 if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
581 RETURN_FALSE;
582 }
583
584 /* execute arbitrary ftp command */
585 ftp_raw(ftp, cmd, cmd_len, return_value);
586 }
587 /* }}} */
588
589 /* {{{ proto string ftp_mkdir(resource stream, string directory)
590 Creates a directory and returns the absolute path for the new directory or false on error */
PHP_FUNCTION(ftp_mkdir)591 PHP_FUNCTION(ftp_mkdir)
592 {
593 zval *z_ftp;
594 ftpbuf_t *ftp;
595 char *dir;
596 zend_string *tmp;
597 size_t dir_len;
598
599 if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs", &z_ftp, &dir, &dir_len) == FAILURE) {
600 return;
601 }
602
603 if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
604 RETURN_FALSE;
605 }
606
607 /* create directory */
608 if (NULL == (tmp = ftp_mkdir(ftp, dir, dir_len))) {
609 php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
610 RETURN_FALSE;
611 }
612
613 RETURN_STR(tmp);
614 }
615 /* }}} */
616
617 /* {{{ proto bool ftp_rmdir(resource stream, string directory)
618 Removes a directory */
PHP_FUNCTION(ftp_rmdir)619 PHP_FUNCTION(ftp_rmdir)
620 {
621 zval *z_ftp;
622 ftpbuf_t *ftp;
623 char *dir;
624 size_t dir_len;
625
626 if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs", &z_ftp, &dir, &dir_len) == FAILURE) {
627 return;
628 }
629
630 if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
631 RETURN_FALSE;
632 }
633
634 /* remove directorie */
635 if (!ftp_rmdir(ftp, dir, dir_len)) {
636 php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
637 RETURN_FALSE;
638 }
639
640 RETURN_TRUE;
641 }
642 /* }}} */
643
644 /* {{{ proto int ftp_chmod(resource stream, int mode, string filename)
645 Sets permissions on a file */
PHP_FUNCTION(ftp_chmod)646 PHP_FUNCTION(ftp_chmod)
647 {
648 zval *z_ftp;
649 ftpbuf_t *ftp;
650 char *filename;
651 size_t filename_len;
652 zend_long mode;
653
654 if (zend_parse_parameters(ZEND_NUM_ARGS(), "rlp", &z_ftp, &mode, &filename, &filename_len) == FAILURE) {
655 RETURN_FALSE;
656 }
657
658 if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
659 RETURN_FALSE;
660 }
661
662 if (!ftp_chmod(ftp, mode, filename, filename_len)) {
663 php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
664 RETURN_FALSE;
665 }
666
667 RETURN_LONG(mode);
668 }
669 /* }}} */
670
671 /* {{{ proto bool ftp_alloc(resource stream, int size[, &response])
672 Attempt to allocate space on the remote FTP server */
PHP_FUNCTION(ftp_alloc)673 PHP_FUNCTION(ftp_alloc)
674 {
675 zval *z_ftp, *zresponse = NULL;
676 ftpbuf_t *ftp;
677 zend_long size, ret;
678 zend_string *response = NULL;
679
680 if (zend_parse_parameters(ZEND_NUM_ARGS(), "rl|z/", &z_ftp, &size, &zresponse) == FAILURE) {
681 RETURN_FALSE;
682 }
683
684 if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
685 RETURN_FALSE;
686 }
687
688 ret = ftp_alloc(ftp, size, zresponse ? &response : NULL);
689 if (response) {
690 zval_ptr_dtor(zresponse);
691 ZVAL_STR(zresponse, response);
692 }
693
694 if (!ret) {
695 RETURN_FALSE;
696 }
697
698 RETURN_TRUE;
699 }
700 /* }}} */
701
702 /* {{{ proto array ftp_nlist(resource stream, string directory)
703 Returns an array of filenames in the given directory */
PHP_FUNCTION(ftp_nlist)704 PHP_FUNCTION(ftp_nlist)
705 {
706 zval *z_ftp;
707 ftpbuf_t *ftp;
708 char **nlist, **ptr, *dir;
709 size_t dir_len;
710
711 if (zend_parse_parameters(ZEND_NUM_ARGS(), "rp", &z_ftp, &dir, &dir_len) == FAILURE) {
712 return;
713 }
714
715 if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
716 RETURN_FALSE;
717 }
718
719 /* get list of files */
720 if (NULL == (nlist = ftp_nlist(ftp, dir, dir_len))) {
721 RETURN_FALSE;
722 }
723
724 array_init(return_value);
725 for (ptr = nlist; *ptr; ptr++) {
726 add_next_index_string(return_value, *ptr);
727 }
728 efree(nlist);
729 }
730 /* }}} */
731
732 /* {{{ proto array ftp_rawlist(resource stream, string directory [, bool recursive])
733 Returns a detailed listing of a directory as an array of output lines */
PHP_FUNCTION(ftp_rawlist)734 PHP_FUNCTION(ftp_rawlist)
735 {
736 zval *z_ftp;
737 ftpbuf_t *ftp;
738 char **llist, **ptr, *dir;
739 size_t dir_len;
740 zend_bool recursive = 0;
741
742 if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs|b", &z_ftp, &dir, &dir_len, &recursive) == FAILURE) {
743 return;
744 }
745
746 if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
747 RETURN_FALSE;
748 }
749
750 /* get raw directory listing */
751 if (NULL == (llist = ftp_list(ftp, dir, dir_len, recursive))) {
752 RETURN_FALSE;
753 }
754
755 array_init(return_value);
756 for (ptr = llist; *ptr; ptr++) {
757 add_next_index_string(return_value, *ptr);
758 }
759 efree(llist);
760 }
761 /* }}} */
762
763 /* {{{ proto array ftp_mlsd(resource stream, string directory)
764 Returns a detailed listing of a directory as an array of parsed output lines */
PHP_FUNCTION(ftp_mlsd)765 PHP_FUNCTION(ftp_mlsd)
766 {
767 zval *z_ftp;
768 ftpbuf_t *ftp;
769 char **llist, **ptr, *dir;
770 size_t dir_len;
771 zval entry;
772
773 if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs", &z_ftp, &dir, &dir_len) == FAILURE) {
774 return;
775 }
776
777 if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
778 RETURN_FALSE;
779 }
780
781 /* get raw directory listing */
782 if (NULL == (llist = ftp_mlsd(ftp, dir, dir_len))) {
783 RETURN_FALSE;
784 }
785
786 array_init(return_value);
787 for (ptr = llist; *ptr; ptr++) {
788 array_init(&entry);
789 if (ftp_mlsd_parse_line(Z_ARRVAL_P(&entry), *ptr) == SUCCESS) {
790 zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &entry);
791 } else {
792 zval_ptr_dtor(&entry);
793 }
794 }
795
796 efree(llist);
797 }
798 /* }}} */
799
800 /* {{{ proto string ftp_systype(resource stream)
801 Returns the system type identifier */
PHP_FUNCTION(ftp_systype)802 PHP_FUNCTION(ftp_systype)
803 {
804 zval *z_ftp;
805 ftpbuf_t *ftp;
806 const char *syst;
807
808 if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &z_ftp) == FAILURE) {
809 return;
810 }
811
812 if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
813 RETURN_FALSE;
814 }
815
816 if (NULL == (syst = ftp_syst(ftp))) {
817 php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
818 RETURN_FALSE;
819 }
820
821 RETURN_STRING((char*) syst);
822 }
823 /* }}} */
824
825 /* {{{ proto bool ftp_fget(resource stream, resource fp, string remote_file, [, int mode [, int resumepos]])
826 Retrieves a file from the FTP server and writes it to an open file */
PHP_FUNCTION(ftp_fget)827 PHP_FUNCTION(ftp_fget)
828 {
829 zval *z_ftp, *z_file;
830 ftpbuf_t *ftp;
831 ftptype_t xtype;
832 php_stream *stream;
833 char *file;
834 size_t file_len;
835 zend_long mode=FTPTYPE_IMAGE, resumepos=0;
836
837 if (zend_parse_parameters(ZEND_NUM_ARGS(), "rrs|ll", &z_ftp, &z_file, &file, &file_len, &mode, &resumepos) == FAILURE) {
838 return;
839 }
840
841 if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
842 RETURN_FALSE;
843 }
844 php_stream_from_res(stream, Z_RES_P(z_file));
845 XTYPE(xtype, mode);
846
847 /* ignore autoresume if autoseek is switched off */
848 if (!ftp->autoseek && resumepos == PHP_FTP_AUTORESUME) {
849 resumepos = 0;
850 }
851
852 if (ftp->autoseek && resumepos) {
853 /* if autoresume is wanted seek to end */
854 if (resumepos == PHP_FTP_AUTORESUME) {
855 php_stream_seek(stream, 0, SEEK_END);
856 resumepos = php_stream_tell(stream);
857 } else {
858 php_stream_seek(stream, resumepos, SEEK_SET);
859 }
860 }
861
862 if (!ftp_get(ftp, stream, file, file_len, xtype, resumepos)) {
863 php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
864 RETURN_FALSE;
865 }
866
867 RETURN_TRUE;
868 }
869 /* }}} */
870
871 /* {{{ proto int ftp_nb_fget(resource stream, resource fp, string remote_file [, int mode [, int resumepos]])
872 Retrieves a file from the FTP server asynchronly and writes it to an open file */
PHP_FUNCTION(ftp_nb_fget)873 PHP_FUNCTION(ftp_nb_fget)
874 {
875 zval *z_ftp, *z_file;
876 ftpbuf_t *ftp;
877 ftptype_t xtype;
878 php_stream *stream;
879 char *file;
880 size_t file_len;
881 zend_long mode=FTPTYPE_IMAGE, resumepos=0, ret;
882
883 if (zend_parse_parameters(ZEND_NUM_ARGS(), "rrs|ll", &z_ftp, &z_file, &file, &file_len, &mode, &resumepos) == FAILURE) {
884 return;
885 }
886
887 if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
888 RETURN_FALSE;
889 }
890 php_stream_from_res(stream, Z_RES_P(z_file));
891 XTYPE(xtype, mode);
892
893 /* ignore autoresume if autoseek is switched off */
894 if (!ftp->autoseek && resumepos == PHP_FTP_AUTORESUME) {
895 resumepos = 0;
896 }
897
898 if (ftp->autoseek && resumepos) {
899 /* if autoresume is wanted seek to end */
900 if (resumepos == PHP_FTP_AUTORESUME) {
901 php_stream_seek(stream, 0, SEEK_END);
902 resumepos = php_stream_tell(stream);
903 } else {
904 php_stream_seek(stream, resumepos, SEEK_SET);
905 }
906 }
907
908 /* configuration */
909 ftp->direction = 0; /* recv */
910 ftp->closestream = 0; /* do not close */
911
912 if ((ret = ftp_nb_get(ftp, stream, file, file_len, xtype, resumepos)) == PHP_FTP_FAILED) {
913 php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
914 RETURN_LONG(ret);
915 }
916
917 RETURN_LONG(ret);
918 }
919 /* }}} */
920
921 /* {{{ proto bool ftp_pasv(resource stream, bool pasv)
922 Turns passive mode on or off */
PHP_FUNCTION(ftp_pasv)923 PHP_FUNCTION(ftp_pasv)
924 {
925 zval *z_ftp;
926 ftpbuf_t *ftp;
927 zend_bool pasv;
928
929 if (zend_parse_parameters(ZEND_NUM_ARGS(), "rb", &z_ftp, &pasv) == FAILURE) {
930 return;
931 }
932
933 if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
934 RETURN_FALSE;
935 }
936
937 if (!ftp_pasv(ftp, pasv ? 1 : 0)) {
938 RETURN_FALSE;
939 }
940
941 RETURN_TRUE;
942 }
943 /* }}} */
944
945 /* {{{ proto bool ftp_get(resource stream, string local_file, string remote_file [, int mode [, int resume_pos]])
946 Retrieves a file from the FTP server and writes it to a local file */
PHP_FUNCTION(ftp_get)947 PHP_FUNCTION(ftp_get)
948 {
949 zval *z_ftp;
950 ftpbuf_t *ftp;
951 ftptype_t xtype;
952 php_stream *outstream;
953 char *local, *remote;
954 size_t local_len, remote_len;
955 zend_long mode=FTPTYPE_IMAGE, resumepos=0;
956
957 if (zend_parse_parameters(ZEND_NUM_ARGS(), "rpp|ll", &z_ftp, &local, &local_len, &remote, &remote_len, &mode, &resumepos) == FAILURE) {
958 return;
959 }
960
961 if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
962 RETURN_FALSE;
963 }
964 XTYPE(xtype, mode);
965
966 /* ignore autoresume if autoseek is switched off */
967 if (!ftp->autoseek && resumepos == PHP_FTP_AUTORESUME) {
968 resumepos = 0;
969 }
970
971 #ifdef PHP_WIN32
972 mode = FTPTYPE_IMAGE;
973 #endif
974
975 if (ftp->autoseek && resumepos) {
976 outstream = php_stream_open_wrapper(local, mode == FTPTYPE_ASCII ? "rt+" : "rb+", REPORT_ERRORS, NULL);
977 if (outstream == NULL) {
978 outstream = php_stream_open_wrapper(local, mode == FTPTYPE_ASCII ? "wt" : "wb", REPORT_ERRORS, NULL);
979 }
980 if (outstream != NULL) {
981 /* if autoresume is wanted seek to end */
982 if (resumepos == PHP_FTP_AUTORESUME) {
983 php_stream_seek(outstream, 0, SEEK_END);
984 resumepos = php_stream_tell(outstream);
985 } else {
986 php_stream_seek(outstream, resumepos, SEEK_SET);
987 }
988 }
989 } else {
990 outstream = php_stream_open_wrapper(local, mode == FTPTYPE_ASCII ? "wt" : "wb", REPORT_ERRORS, NULL);
991 }
992
993 if (outstream == NULL) {
994 php_error_docref(NULL, E_WARNING, "Error opening %s", local);
995 RETURN_FALSE;
996 }
997
998 if (!ftp_get(ftp, outstream, remote, remote_len, xtype, resumepos)) {
999 php_stream_close(outstream);
1000 VCWD_UNLINK(local);
1001 php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
1002 RETURN_FALSE;
1003 }
1004
1005 php_stream_close(outstream);
1006 RETURN_TRUE;
1007 }
1008 /* }}} */
1009
1010 /* {{{ proto int ftp_nb_get(resource stream, string local_file, string remote_file, [, int mode [, int resume_pos]])
1011 Retrieves a file from the FTP server nbhronly and writes it to a local file */
PHP_FUNCTION(ftp_nb_get)1012 PHP_FUNCTION(ftp_nb_get)
1013 {
1014 zval *z_ftp;
1015 ftpbuf_t *ftp;
1016 ftptype_t xtype;
1017 php_stream *outstream;
1018 char *local, *remote;
1019 size_t local_len, remote_len;
1020 int ret;
1021 zend_long mode=FTPTYPE_IMAGE, resumepos=0;
1022
1023 if (zend_parse_parameters(ZEND_NUM_ARGS(), "rss|ll", &z_ftp, &local, &local_len, &remote, &remote_len, &mode, &resumepos) == FAILURE) {
1024 return;
1025 }
1026
1027 if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
1028 RETURN_FALSE;
1029 }
1030 XTYPE(xtype, mode);
1031
1032 /* ignore autoresume if autoseek is switched off */
1033 if (!ftp->autoseek && resumepos == PHP_FTP_AUTORESUME) {
1034 resumepos = 0;
1035 }
1036 #ifdef PHP_WIN32
1037 mode = FTPTYPE_IMAGE;
1038 #endif
1039 if (ftp->autoseek && resumepos) {
1040 outstream = php_stream_open_wrapper(local, mode == FTPTYPE_ASCII ? "rt+" : "rb+", REPORT_ERRORS, NULL);
1041 if (outstream == NULL) {
1042 outstream = php_stream_open_wrapper(local, mode == FTPTYPE_ASCII ? "wt" : "wb", REPORT_ERRORS, NULL);
1043 }
1044 if (outstream != NULL) {
1045 /* if autoresume is wanted seek to end */
1046 if (resumepos == PHP_FTP_AUTORESUME) {
1047 php_stream_seek(outstream, 0, SEEK_END);
1048 resumepos = php_stream_tell(outstream);
1049 } else {
1050 php_stream_seek(outstream, resumepos, SEEK_SET);
1051 }
1052 }
1053 } else {
1054 outstream = php_stream_open_wrapper(local, mode == FTPTYPE_ASCII ? "wt" : "wb", REPORT_ERRORS, NULL);
1055 }
1056
1057 if (outstream == NULL) {
1058 php_error_docref(NULL, E_WARNING, "Error opening %s", local);
1059 RETURN_FALSE;
1060 }
1061
1062 /* configuration */
1063 ftp->direction = 0; /* recv */
1064 ftp->closestream = 1; /* do close */
1065
1066 if ((ret = ftp_nb_get(ftp, outstream, remote, remote_len, xtype, resumepos)) == PHP_FTP_FAILED) {
1067 php_stream_close(outstream);
1068 ftp->stream = NULL;
1069 VCWD_UNLINK(local);
1070 php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
1071 RETURN_LONG(PHP_FTP_FAILED);
1072 }
1073
1074 if (ret == PHP_FTP_FINISHED){
1075 php_stream_close(outstream);
1076 ftp->stream = NULL;
1077 }
1078
1079 RETURN_LONG(ret);
1080 }
1081 /* }}} */
1082
1083 /* {{{ proto int ftp_nb_continue(resource stream)
1084 Continues retrieving/sending a file nbronously */
PHP_FUNCTION(ftp_nb_continue)1085 PHP_FUNCTION(ftp_nb_continue)
1086 {
1087 zval *z_ftp;
1088 ftpbuf_t *ftp;
1089 zend_long ret;
1090
1091 if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &z_ftp) == FAILURE) {
1092 return;
1093 }
1094
1095 if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
1096 RETURN_FALSE;
1097 }
1098
1099 if (!ftp->nb) {
1100 php_error_docref(NULL, E_WARNING, "no nbronous transfer to continue.");
1101 RETURN_LONG(PHP_FTP_FAILED);
1102 }
1103
1104 if (ftp->direction) {
1105 ret=ftp_nb_continue_write(ftp);
1106 } else {
1107 ret=ftp_nb_continue_read(ftp);
1108 }
1109
1110 if (ret != PHP_FTP_MOREDATA && ftp->closestream) {
1111 php_stream_close(ftp->stream);
1112 ftp->stream = NULL;
1113 }
1114
1115 if (ret == PHP_FTP_FAILED) {
1116 php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
1117 }
1118
1119 RETURN_LONG(ret);
1120 }
1121 /* }}} */
1122
1123 /* {{{ proto bool ftp_fput(resource stream, string remote_file, resource fp [, int mode [, int startpos]])
1124 Stores a file from an open file to the FTP server */
PHP_FUNCTION(ftp_fput)1125 PHP_FUNCTION(ftp_fput)
1126 {
1127 zval *z_ftp, *z_file;
1128 ftpbuf_t *ftp;
1129 ftptype_t xtype;
1130 size_t remote_len;
1131 zend_long mode=FTPTYPE_IMAGE, startpos=0;
1132 php_stream *stream;
1133 char *remote;
1134
1135 if (zend_parse_parameters(ZEND_NUM_ARGS(), "rsr|ll", &z_ftp, &remote, &remote_len, &z_file, &mode, &startpos) == FAILURE) {
1136 return;
1137 }
1138
1139 if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
1140 RETURN_FALSE;
1141 }
1142 php_stream_from_zval(stream, z_file);
1143 XTYPE(xtype, mode);
1144
1145 /* ignore autoresume if autoseek is switched off */
1146 if (!ftp->autoseek && startpos == PHP_FTP_AUTORESUME) {
1147 startpos = 0;
1148 }
1149
1150 if (ftp->autoseek && startpos) {
1151 /* if autoresume is wanted ask for remote size */
1152 if (startpos == PHP_FTP_AUTORESUME) {
1153 startpos = ftp_size(ftp, remote, remote_len);
1154 if (startpos < 0) {
1155 startpos = 0;
1156 }
1157 }
1158 if (startpos) {
1159 php_stream_seek(stream, startpos, SEEK_SET);
1160 }
1161 }
1162
1163 if (!ftp_put(ftp, remote, remote_len, stream, xtype, startpos)) {
1164 php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
1165 RETURN_FALSE;
1166 }
1167
1168 RETURN_TRUE;
1169 }
1170 /* }}} */
1171
1172 /* {{{ proto int ftp_nb_fput(resource stream, string remote_file, resource fp [, int mode [, int startpos]])
1173 Stores a file from an open file to the FTP server nbronly */
PHP_FUNCTION(ftp_nb_fput)1174 PHP_FUNCTION(ftp_nb_fput)
1175 {
1176 zval *z_ftp, *z_file;
1177 ftpbuf_t *ftp;
1178 ftptype_t xtype;
1179 size_t remote_len;
1180 int ret;
1181 zend_long mode=FTPTYPE_IMAGE, startpos=0;
1182 php_stream *stream;
1183 char *remote;
1184
1185 if (zend_parse_parameters(ZEND_NUM_ARGS(), "rsr|ll", &z_ftp, &remote, &remote_len, &z_file, &mode, &startpos) == FAILURE) {
1186 return;
1187 }
1188
1189 if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
1190 RETURN_FALSE;
1191 }
1192 php_stream_from_res(stream, Z_RES_P(z_file));
1193 XTYPE(xtype, mode);
1194
1195 /* ignore autoresume if autoseek is switched off */
1196 if (!ftp->autoseek && startpos == PHP_FTP_AUTORESUME) {
1197 startpos = 0;
1198 }
1199
1200 if (ftp->autoseek && startpos) {
1201 /* if autoresume is wanted ask for remote size */
1202 if (startpos == PHP_FTP_AUTORESUME) {
1203 startpos = ftp_size(ftp, remote, remote_len);
1204 if (startpos < 0) {
1205 startpos = 0;
1206 }
1207 }
1208 if (startpos) {
1209 php_stream_seek(stream, startpos, SEEK_SET);
1210 }
1211 }
1212
1213 /* configuration */
1214 ftp->direction = 1; /* send */
1215 ftp->closestream = 0; /* do not close */
1216
1217 if (((ret = ftp_nb_put(ftp, remote, remote_len, stream, xtype, startpos)) == PHP_FTP_FAILED)) {
1218 php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
1219 RETURN_LONG(ret);
1220 }
1221
1222 RETURN_LONG(ret);
1223 }
1224 /* }}} */
1225
1226
1227 /* {{{ proto bool ftp_put(resource stream, string remote_file, string local_file [, int mode [, int startpos]])
1228 Stores a file on the FTP server */
PHP_FUNCTION(ftp_put)1229 PHP_FUNCTION(ftp_put)
1230 {
1231 zval *z_ftp;
1232 ftpbuf_t *ftp;
1233 ftptype_t xtype;
1234 char *remote, *local;
1235 size_t remote_len, local_len;
1236 zend_long mode=FTPTYPE_IMAGE, startpos=0;
1237 php_stream *instream;
1238
1239 if (zend_parse_parameters(ZEND_NUM_ARGS(), "rpp|ll", &z_ftp, &remote, &remote_len, &local, &local_len, &mode, &startpos) == FAILURE) {
1240 return;
1241 }
1242
1243 if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
1244 RETURN_FALSE;
1245 }
1246 XTYPE(xtype, mode);
1247
1248 if (!(instream = php_stream_open_wrapper(local, mode == FTPTYPE_ASCII ? "rt" : "rb", REPORT_ERRORS, NULL))) {
1249 RETURN_FALSE;
1250 }
1251
1252 /* ignore autoresume if autoseek is switched off */
1253 if (!ftp->autoseek && startpos == PHP_FTP_AUTORESUME) {
1254 startpos = 0;
1255 }
1256
1257 if (ftp->autoseek && startpos) {
1258 /* if autoresume is wanted ask for remote size */
1259 if (startpos == PHP_FTP_AUTORESUME) {
1260 startpos = ftp_size(ftp, remote, remote_len);
1261 if (startpos < 0) {
1262 startpos = 0;
1263 }
1264 }
1265 if (startpos) {
1266 php_stream_seek(instream, startpos, SEEK_SET);
1267 }
1268 }
1269
1270 if (!ftp_put(ftp, remote, remote_len, instream, xtype, startpos)) {
1271 php_stream_close(instream);
1272 php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
1273 RETURN_FALSE;
1274 }
1275 php_stream_close(instream);
1276
1277 RETURN_TRUE;
1278 }
1279 /* }}} */
1280
1281 /* {{{ proto bool ftp_append(resource stream, string remote_file, string local_file [, int mode])
1282 Append content of a file a another file on the FTP server */
PHP_FUNCTION(ftp_append)1283 PHP_FUNCTION(ftp_append)
1284 {
1285 zval *z_ftp;
1286 ftpbuf_t *ftp;
1287 ftptype_t xtype;
1288 char *remote, *local;
1289 size_t remote_len, local_len;
1290 zend_long mode=FTPTYPE_IMAGE;
1291 php_stream *instream;
1292
1293 if (zend_parse_parameters(ZEND_NUM_ARGS(), "rpp|l", &z_ftp, &remote, &remote_len, &local, &local_len, &mode) == FAILURE) {
1294 return;
1295 }
1296
1297 if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
1298 RETURN_FALSE;
1299 }
1300 XTYPE(xtype, mode);
1301
1302 if (!(instream = php_stream_open_wrapper(local, mode == FTPTYPE_ASCII ? "rt" : "rb", REPORT_ERRORS, NULL))) {
1303 RETURN_FALSE;
1304 }
1305
1306 if (!ftp_append(ftp, remote, remote_len, instream, xtype)) {
1307 php_stream_close(instream);
1308 php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
1309 RETURN_FALSE;
1310 }
1311 php_stream_close(instream);
1312
1313 RETURN_TRUE;
1314 }
1315 /* }}} */
1316
1317 /* {{{ proto int ftp_nb_put(resource stream, string remote_file, string local_file [, int mode [, int startpos]])
1318 Stores a file on the FTP server */
PHP_FUNCTION(ftp_nb_put)1319 PHP_FUNCTION(ftp_nb_put)
1320 {
1321 zval *z_ftp;
1322 ftpbuf_t *ftp;
1323 ftptype_t xtype;
1324 char *remote, *local;
1325 size_t remote_len, local_len;
1326 zend_long mode=FTPTYPE_IMAGE, startpos=0, ret;
1327 php_stream *instream;
1328
1329 if (zend_parse_parameters(ZEND_NUM_ARGS(), "rpp|ll", &z_ftp, &remote, &remote_len, &local, &local_len, &mode, &startpos) == FAILURE) {
1330 return;
1331 }
1332
1333 if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
1334 RETURN_FALSE;
1335 }
1336 XTYPE(xtype, mode);
1337
1338 if (!(instream = php_stream_open_wrapper(local, mode == FTPTYPE_ASCII ? "rt" : "rb", REPORT_ERRORS, NULL))) {
1339 RETURN_FALSE;
1340 }
1341
1342 /* ignore autoresume if autoseek is switched off */
1343 if (!ftp->autoseek && startpos == PHP_FTP_AUTORESUME) {
1344 startpos = 0;
1345 }
1346
1347 if (ftp->autoseek && startpos) {
1348 /* if autoresume is wanted ask for remote size */
1349 if (startpos == PHP_FTP_AUTORESUME) {
1350 startpos = ftp_size(ftp, remote, remote_len);
1351 if (startpos < 0) {
1352 startpos = 0;
1353 }
1354 }
1355 if (startpos) {
1356 php_stream_seek(instream, startpos, SEEK_SET);
1357 }
1358 }
1359
1360 /* configuration */
1361 ftp->direction = 1; /* send */
1362 ftp->closestream = 1; /* do close */
1363
1364 ret = ftp_nb_put(ftp, remote, remote_len, instream, xtype, startpos);
1365
1366 if (ret != PHP_FTP_MOREDATA) {
1367 php_stream_close(instream);
1368 ftp->stream = NULL;
1369 }
1370
1371 if (ret == PHP_FTP_FAILED) {
1372 php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
1373 }
1374
1375 RETURN_LONG(ret);
1376 }
1377 /* }}} */
1378
1379 /* {{{ proto int ftp_size(resource stream, string filename)
1380 Returns the size of the file, or -1 on error */
PHP_FUNCTION(ftp_size)1381 PHP_FUNCTION(ftp_size)
1382 {
1383 zval *z_ftp;
1384 ftpbuf_t *ftp;
1385 char *file;
1386 size_t file_len;
1387
1388 if (zend_parse_parameters(ZEND_NUM_ARGS(), "rp", &z_ftp, &file, &file_len) == FAILURE) {
1389 return;
1390 }
1391
1392 if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
1393 RETURN_FALSE;
1394 }
1395
1396 /* get file size */
1397 RETURN_LONG(ftp_size(ftp, file, file_len));
1398 }
1399 /* }}} */
1400
1401 /* {{{ proto int ftp_mdtm(resource stream, string filename)
1402 Returns the last modification time of the file, or -1 on error */
PHP_FUNCTION(ftp_mdtm)1403 PHP_FUNCTION(ftp_mdtm)
1404 {
1405 zval *z_ftp;
1406 ftpbuf_t *ftp;
1407 char *file;
1408 size_t file_len;
1409
1410 if (zend_parse_parameters(ZEND_NUM_ARGS(), "rp", &z_ftp, &file, &file_len) == FAILURE) {
1411 return;
1412 }
1413
1414 if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
1415 RETURN_FALSE;
1416 }
1417
1418 /* get file mod time */
1419 RETURN_LONG(ftp_mdtm(ftp, file, file_len));
1420 }
1421 /* }}} */
1422
1423 /* {{{ proto bool ftp_rename(resource stream, string src, string dest)
1424 Renames the given file to a new path */
PHP_FUNCTION(ftp_rename)1425 PHP_FUNCTION(ftp_rename)
1426 {
1427 zval *z_ftp;
1428 ftpbuf_t *ftp;
1429 char *src, *dest;
1430 size_t src_len, dest_len;
1431
1432 if (zend_parse_parameters(ZEND_NUM_ARGS(), "rss", &z_ftp, &src, &src_len, &dest, &dest_len) == FAILURE) {
1433 return;
1434 }
1435
1436 if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
1437 RETURN_FALSE;
1438 }
1439
1440 /* rename the file */
1441 if (!ftp_rename(ftp, src, src_len, dest, dest_len)) {
1442 php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
1443 RETURN_FALSE;
1444 }
1445
1446 RETURN_TRUE;
1447 }
1448 /* }}} */
1449
1450 /* {{{ proto bool ftp_delete(resource stream, string file)
1451 Deletes a file */
PHP_FUNCTION(ftp_delete)1452 PHP_FUNCTION(ftp_delete)
1453 {
1454 zval *z_ftp;
1455 ftpbuf_t *ftp;
1456 char *file;
1457 size_t file_len;
1458
1459 if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs", &z_ftp, &file, &file_len) == FAILURE) {
1460 return;
1461 }
1462
1463 if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
1464 RETURN_FALSE;
1465 }
1466
1467 /* delete the file */
1468 if (!ftp_delete(ftp, file, file_len)) {
1469 php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
1470 RETURN_FALSE;
1471 }
1472
1473 RETURN_TRUE;
1474 }
1475 /* }}} */
1476
1477 /* {{{ proto bool ftp_site(resource stream, string cmd)
1478 Sends a SITE command to the server */
PHP_FUNCTION(ftp_site)1479 PHP_FUNCTION(ftp_site)
1480 {
1481 zval *z_ftp;
1482 ftpbuf_t *ftp;
1483 char *cmd;
1484 size_t cmd_len;
1485
1486 if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs", &z_ftp, &cmd, &cmd_len) == FAILURE) {
1487 return;
1488 }
1489
1490 if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
1491 RETURN_FALSE;
1492 }
1493
1494 /* send the site command */
1495 if (!ftp_site(ftp, cmd, cmd_len)) {
1496 php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
1497 RETURN_FALSE;
1498 }
1499
1500 RETURN_TRUE;
1501 }
1502 /* }}} */
1503
1504 /* {{{ proto bool ftp_close(resource stream)
1505 Closes the FTP stream */
PHP_FUNCTION(ftp_close)1506 PHP_FUNCTION(ftp_close)
1507 {
1508 zval *z_ftp;
1509 ftpbuf_t *ftp;
1510
1511 if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &z_ftp) == FAILURE) {
1512 return;
1513 }
1514
1515 if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
1516 RETURN_FALSE;
1517 }
1518
1519 ftp_quit(ftp);
1520
1521 RETURN_BOOL(zend_list_close(Z_RES_P(z_ftp)) == SUCCESS);
1522 }
1523 /* }}} */
1524
1525 /* {{{ proto bool ftp_set_option(resource stream, int option, mixed value)
1526 Sets an FTP option */
PHP_FUNCTION(ftp_set_option)1527 PHP_FUNCTION(ftp_set_option)
1528 {
1529 zval *z_ftp, *z_value;
1530 zend_long option;
1531 ftpbuf_t *ftp;
1532
1533 if (zend_parse_parameters(ZEND_NUM_ARGS(), "rlz", &z_ftp, &option, &z_value) == FAILURE) {
1534 return;
1535 }
1536
1537 if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
1538 RETURN_FALSE;
1539 }
1540
1541 switch (option) {
1542 case PHP_FTP_OPT_TIMEOUT_SEC:
1543 if (Z_TYPE_P(z_value) != IS_LONG) {
1544 php_error_docref(NULL, E_WARNING, "Option TIMEOUT_SEC expects value of type int, %s given",
1545 zend_zval_type_name(z_value));
1546 RETURN_FALSE;
1547 }
1548 if (Z_LVAL_P(z_value) <= 0) {
1549 php_error_docref(NULL, E_WARNING, "Timeout has to be greater than 0");
1550 RETURN_FALSE;
1551 }
1552 ftp->timeout_sec = Z_LVAL_P(z_value);
1553 RETURN_TRUE;
1554 break;
1555 case PHP_FTP_OPT_AUTOSEEK:
1556 if (Z_TYPE_P(z_value) != IS_TRUE && Z_TYPE_P(z_value) != IS_FALSE) {
1557 php_error_docref(NULL, E_WARNING, "Option AUTOSEEK expects value of type bool, %s given",
1558 zend_zval_type_name(z_value));
1559 RETURN_FALSE;
1560 }
1561 ftp->autoseek = Z_TYPE_P(z_value) == IS_TRUE ? 1 : 0;
1562 RETURN_TRUE;
1563 break;
1564 case PHP_FTP_OPT_USEPASVADDRESS:
1565 if (Z_TYPE_P(z_value) != IS_TRUE && Z_TYPE_P(z_value) != IS_FALSE) {
1566 php_error_docref(NULL, E_WARNING, "Option USEPASVADDRESS expects value of type bool, %s given",
1567 zend_zval_type_name(z_value));
1568 RETURN_FALSE;
1569 }
1570 ftp->usepasvaddress = Z_TYPE_P(z_value) == IS_TRUE ? 1 : 0;
1571 RETURN_TRUE;
1572 break;
1573 default:
1574 php_error_docref(NULL, E_WARNING, "Unknown option '" ZEND_LONG_FMT "'", option);
1575 RETURN_FALSE;
1576 break;
1577 }
1578 }
1579 /* }}} */
1580
1581 /* {{{ proto mixed ftp_get_option(resource stream, int option)
1582 Gets an FTP option */
PHP_FUNCTION(ftp_get_option)1583 PHP_FUNCTION(ftp_get_option)
1584 {
1585 zval *z_ftp;
1586 zend_long option;
1587 ftpbuf_t *ftp;
1588
1589 if (zend_parse_parameters(ZEND_NUM_ARGS(), "rl", &z_ftp, &option) == FAILURE) {
1590 return;
1591 }
1592
1593 if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
1594 RETURN_FALSE;
1595 }
1596
1597 switch (option) {
1598 case PHP_FTP_OPT_TIMEOUT_SEC:
1599 RETURN_LONG(ftp->timeout_sec);
1600 break;
1601 case PHP_FTP_OPT_AUTOSEEK:
1602 RETURN_BOOL(ftp->autoseek);
1603 break;
1604 case PHP_FTP_OPT_USEPASVADDRESS:
1605 RETURN_BOOL(ftp->usepasvaddress);
1606 break;
1607 default:
1608 php_error_docref(NULL, E_WARNING, "Unknown option '" ZEND_LONG_FMT "'", option);
1609 RETURN_FALSE;
1610 break;
1611 }
1612 }
1613 /* }}} */
1614
1615 #endif /* HAVE_FTP */
1616
1617 /*
1618 * Local variables:
1619 * tab-width: 4
1620 * c-basic-offset: 4
1621 * indent-tabs-mode: t
1622 * End:
1623 */
1624