1 /*
2 +----------------------------------------------------------------------+
3 | Copyright (c) The PHP Group |
4 +----------------------------------------------------------------------+
5 | This source file is subject to version 3.01 of the PHP license, |
6 | that is bundled with this package in the file LICENSE, and is |
7 | available through the world-wide-web at the following url: |
8 | https://www.php.net/license/3_01.txt |
9 | If you did not receive a copy of the PHP license and are unable to |
10 | obtain it through the world-wide-web, please send a note to |
11 | license@php.net so we can mail you a copy immediately. |
12 +----------------------------------------------------------------------+
13 | Authors: Andrew Skalski <askalski@chek.com> |
14 | Stefan Esser <sesser@php.net> (resume functions) |
15 +----------------------------------------------------------------------+
16 */
17
18 #ifdef HAVE_CONFIG_H
19 #include "config.h"
20 #endif
21
22 #include "php.h"
23
24 #ifdef HAVE_FTP_SSL
25 # include <openssl/ssl.h>
26 #endif
27
28 #ifdef HAVE_FTP
29
30 #include "ext/standard/info.h"
31 #include "ext/standard/file.h"
32 #include "Zend/zend_exceptions.h"
33
34 #include "php_ftp.h"
35 #include "ftp.h"
36 #include "ftp_arginfo.h"
37
38 static zend_class_entry *php_ftp_ce = NULL;
39 static zend_object_handlers ftp_object_handlers;
40
41 zend_module_entry php_ftp_module_entry = {
42 STANDARD_MODULE_HEADER_EX,
43 NULL,
44 NULL,
45 "ftp",
46 ext_functions,
47 PHP_MINIT(ftp),
48 NULL,
49 NULL,
50 NULL,
51 PHP_MINFO(ftp),
52 PHP_FTP_VERSION,
53 STANDARD_MODULE_PROPERTIES
54 };
55
56 #ifdef COMPILE_DL_FTP
57 ZEND_GET_MODULE(php_ftp)
58 #endif
59
60 typedef struct _php_ftp_object {
61 ftpbuf_t *ftp;
62 zend_object std;
63 } php_ftp_object;
64
ftp_object_to_zend_object(php_ftp_object * obj)65 static inline zend_object *ftp_object_to_zend_object(php_ftp_object *obj) {
66 return ((zend_object*)(obj + 1)) - 1;
67 }
68
ftp_object_from_zend_object(zend_object * zobj)69 static inline php_ftp_object *ftp_object_from_zend_object(zend_object *zobj) {
70 return ((php_ftp_object*)(zobj + 1)) - 1;
71 }
72
ftp_object_create(zend_class_entry * ce)73 static zend_object* ftp_object_create(zend_class_entry* ce) {
74 php_ftp_object *obj = zend_object_alloc(sizeof(php_ftp_object), ce);
75 zend_object *zobj = ftp_object_to_zend_object(obj);
76 obj->ftp = NULL;
77 zend_object_std_init(zobj, ce);
78 object_properties_init(zobj, ce);
79 zobj->handlers = &ftp_object_handlers;
80
81 return zobj;
82 }
83
ftp_object_get_constructor(zend_object * zobj)84 static zend_function *ftp_object_get_constructor(zend_object *zobj) {
85 zend_throw_error(NULL, "Cannot directly construct FTP\\Connection, use ftp_connect() or ftp_ssl_connect() instead");
86 return NULL;
87 }
88
ftp_object_destroy(zend_object * zobj)89 static void ftp_object_destroy(zend_object *zobj) {
90 php_ftp_object *obj = ftp_object_from_zend_object(zobj);
91
92 if (obj->ftp) {
93 ftp_close(obj->ftp);
94 }
95
96 zend_object_std_dtor(zobj);
97 }
98
PHP_MINIT_FUNCTION(ftp)99 PHP_MINIT_FUNCTION(ftp)
100 {
101 #ifdef HAVE_FTP_SSL
102 #if OPENSSL_VERSION_NUMBER < 0x10101000 && !defined(LIBRESSL_VERSION_NUMBER)
103 SSL_library_init();
104 OpenSSL_add_all_ciphers();
105 OpenSSL_add_all_digests();
106 OpenSSL_add_all_algorithms();
107
108 SSL_load_error_strings();
109 #endif
110 #endif
111
112 php_ftp_ce = register_class_FTP_Connection();
113 php_ftp_ce->create_object = ftp_object_create;
114
115 memcpy(&ftp_object_handlers, &std_object_handlers, sizeof(zend_object_handlers));
116 ftp_object_handlers.offset = XtOffsetOf(php_ftp_object, std);
117 ftp_object_handlers.get_constructor = ftp_object_get_constructor;
118 ftp_object_handlers.free_obj = ftp_object_destroy;
119 ftp_object_handlers.clone_obj = NULL;
120
121 REGISTER_LONG_CONSTANT("FTP_ASCII", FTPTYPE_ASCII, CONST_PERSISTENT | CONST_CS);
122 REGISTER_LONG_CONSTANT("FTP_TEXT", FTPTYPE_ASCII, CONST_PERSISTENT | CONST_CS);
123 REGISTER_LONG_CONSTANT("FTP_BINARY", FTPTYPE_IMAGE, CONST_PERSISTENT | CONST_CS);
124 REGISTER_LONG_CONSTANT("FTP_IMAGE", FTPTYPE_IMAGE, CONST_PERSISTENT | CONST_CS);
125 REGISTER_LONG_CONSTANT("FTP_AUTORESUME", PHP_FTP_AUTORESUME, CONST_PERSISTENT | CONST_CS);
126 REGISTER_LONG_CONSTANT("FTP_TIMEOUT_SEC", PHP_FTP_OPT_TIMEOUT_SEC, CONST_PERSISTENT | CONST_CS);
127 REGISTER_LONG_CONSTANT("FTP_AUTOSEEK", PHP_FTP_OPT_AUTOSEEK, CONST_PERSISTENT | CONST_CS);
128 REGISTER_LONG_CONSTANT("FTP_USEPASVADDRESS", PHP_FTP_OPT_USEPASVADDRESS, CONST_PERSISTENT | CONST_CS);
129 REGISTER_LONG_CONSTANT("FTP_FAILED", PHP_FTP_FAILED, CONST_PERSISTENT | CONST_CS);
130 REGISTER_LONG_CONSTANT("FTP_FINISHED", PHP_FTP_FINISHED, CONST_PERSISTENT | CONST_CS);
131 REGISTER_LONG_CONSTANT("FTP_MOREDATA", PHP_FTP_MOREDATA, CONST_PERSISTENT | CONST_CS);
132 return SUCCESS;
133 }
134
PHP_MINFO_FUNCTION(ftp)135 PHP_MINFO_FUNCTION(ftp)
136 {
137 php_info_print_table_start();
138 php_info_print_table_row(2, "FTP support", "enabled");
139 #ifdef HAVE_FTP_SSL
140 php_info_print_table_row(2, "FTPS support", "enabled");
141 #else
142 php_info_print_table_row(2, "FTPS support", "disabled");
143 #endif
144 php_info_print_table_end();
145 }
146
147 #define XTYPE(xtype, mode) { \
148 if (mode != FTPTYPE_ASCII && mode != FTPTYPE_IMAGE) { \
149 zend_argument_value_error(4, "must be either FTP_ASCII or FTP_BINARY"); \
150 RETURN_THROWS(); \
151 } \
152 xtype = mode; \
153 }
154
155
156 /* {{{ Opens a FTP stream */
PHP_FUNCTION(ftp_connect)157 PHP_FUNCTION(ftp_connect)
158 {
159 ftpbuf_t *ftp;
160 char *host;
161 size_t host_len;
162 zend_long port = 0;
163 zend_long timeout_sec = FTP_DEFAULT_TIMEOUT;
164
165 if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|ll", &host, &host_len, &port, &timeout_sec) == FAILURE) {
166 RETURN_THROWS();
167 }
168
169 if (timeout_sec <= 0) {
170 zend_argument_value_error(3, "must be greater than 0");
171 RETURN_THROWS();
172 }
173
174 /* connect */
175 if (!(ftp = ftp_open(host, (short)port, timeout_sec))) {
176 RETURN_FALSE;
177 }
178
179 /* autoseek for resuming */
180 ftp->autoseek = FTP_DEFAULT_AUTOSEEK;
181 ftp->usepasvaddress = FTP_DEFAULT_USEPASVADDRESS;
182 #ifdef HAVE_FTP_SSL
183 /* disable ssl */
184 ftp->use_ssl = 0;
185 #endif
186
187 object_init_ex(return_value, php_ftp_ce);
188 ftp_object_from_zend_object(Z_OBJ_P(return_value))->ftp = ftp;
189 }
190 /* }}} */
191
192 #ifdef HAVE_FTP_SSL
193 /* {{{ Opens a FTP-SSL stream */
PHP_FUNCTION(ftp_ssl_connect)194 PHP_FUNCTION(ftp_ssl_connect)
195 {
196 ftpbuf_t *ftp;
197 char *host;
198 size_t host_len;
199 zend_long port = 0;
200 zend_long timeout_sec = FTP_DEFAULT_TIMEOUT;
201
202 if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|ll", &host, &host_len, &port, &timeout_sec) == FAILURE) {
203 RETURN_THROWS();
204 }
205
206 if (timeout_sec <= 0) {
207 zend_argument_value_error(3, "must be greater than 0");
208 RETURN_THROWS();
209 }
210
211 /* connect */
212 if (!(ftp = ftp_open(host, (short)port, timeout_sec))) {
213 RETURN_FALSE;
214 }
215
216 /* autoseek for resuming */
217 ftp->autoseek = FTP_DEFAULT_AUTOSEEK;
218 ftp->usepasvaddress = FTP_DEFAULT_USEPASVADDRESS;
219 /* enable ssl */
220 ftp->use_ssl = 1;
221
222 object_init_ex(return_value, php_ftp_ce);
223 ftp_object_from_zend_object(Z_OBJ_P(return_value))->ftp = ftp;
224 }
225 /* }}} */
226 #endif
227
228 #define GET_FTPBUF(ftpbuf, zftp) \
229 ftpbuf = ftp_object_from_zend_object(Z_OBJ_P(zftp))->ftp; \
230 if (!ftpbuf) { \
231 zend_throw_exception(zend_ce_value_error, "FTP\\Connection is already closed", 0); \
232 RETURN_THROWS(); \
233 }
234
235 /* {{{ Logs into the FTP server */
PHP_FUNCTION(ftp_login)236 PHP_FUNCTION(ftp_login)
237 {
238 zval *z_ftp;
239 ftpbuf_t *ftp;
240 char *user, *pass;
241 size_t user_len, pass_len;
242
243 if (zend_parse_parameters(ZEND_NUM_ARGS(), "Oss", &z_ftp, php_ftp_ce, &user, &user_len, &pass, &pass_len) == FAILURE) {
244 RETURN_THROWS();
245 }
246 GET_FTPBUF(ftp, z_ftp);
247
248 /* log in */
249 if (!ftp_login(ftp, user, user_len, pass, pass_len)) {
250 if (*ftp->inbuf) {
251 php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
252 }
253 RETURN_FALSE;
254 }
255
256 RETURN_TRUE;
257 }
258 /* }}} */
259
260 /* {{{ Returns the present working directory */
PHP_FUNCTION(ftp_pwd)261 PHP_FUNCTION(ftp_pwd)
262 {
263 zval *z_ftp;
264 ftpbuf_t *ftp;
265 const char *pwd;
266
267 if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &z_ftp, php_ftp_ce) == FAILURE) {
268 RETURN_THROWS();
269 }
270 GET_FTPBUF(ftp, z_ftp);
271
272 if (!(pwd = ftp_pwd(ftp))) {
273 if (*ftp->inbuf) {
274 php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
275 }
276 RETURN_FALSE;
277 }
278
279 RETURN_STRING((char*) pwd);
280 }
281 /* }}} */
282
283 /* {{{ Changes to the parent directory */
PHP_FUNCTION(ftp_cdup)284 PHP_FUNCTION(ftp_cdup)
285 {
286 zval *z_ftp;
287 ftpbuf_t *ftp;
288
289 if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &z_ftp, php_ftp_ce) == FAILURE) {
290 RETURN_THROWS();
291 }
292 GET_FTPBUF(ftp, z_ftp);
293
294 if (!ftp_cdup(ftp)) {
295 if (*ftp->inbuf) {
296 php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
297 }
298 RETURN_FALSE;
299 }
300
301 RETURN_TRUE;
302 }
303 /* }}} */
304
305 /* {{{ Changes directories */
PHP_FUNCTION(ftp_chdir)306 PHP_FUNCTION(ftp_chdir)
307 {
308 zval *z_ftp;
309 ftpbuf_t *ftp;
310 char *dir;
311 size_t dir_len;
312
313 if (zend_parse_parameters(ZEND_NUM_ARGS(), "Os", &z_ftp, php_ftp_ce, &dir, &dir_len) == FAILURE) {
314 RETURN_THROWS();
315 }
316 GET_FTPBUF(ftp, z_ftp);
317
318 /* change directories */
319 if (!ftp_chdir(ftp, dir, dir_len)) {
320 if (*ftp->inbuf) {
321 php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
322 }
323 RETURN_FALSE;
324 }
325
326 RETURN_TRUE;
327 }
328 /* }}} */
329
330 /* {{{ Requests execution of a program on the FTP server */
PHP_FUNCTION(ftp_exec)331 PHP_FUNCTION(ftp_exec)
332 {
333 zval *z_ftp;
334 ftpbuf_t *ftp;
335 char *cmd;
336 size_t cmd_len;
337
338 if (zend_parse_parameters(ZEND_NUM_ARGS(), "Os", &z_ftp, php_ftp_ce, &cmd, &cmd_len) == FAILURE) {
339 RETURN_THROWS();
340 }
341 GET_FTPBUF(ftp, z_ftp);
342
343 /* execute serverside command */
344 if (!ftp_exec(ftp, cmd, cmd_len)) {
345 if (*ftp->inbuf) {
346 php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
347 }
348 RETURN_FALSE;
349 }
350
351 RETURN_TRUE;
352 }
353 /* }}} */
354
355 /* {{{ Sends a literal command to the FTP server */
PHP_FUNCTION(ftp_raw)356 PHP_FUNCTION(ftp_raw)
357 {
358 zval *z_ftp;
359 ftpbuf_t *ftp;
360 char *cmd;
361 size_t cmd_len;
362
363 if (zend_parse_parameters(ZEND_NUM_ARGS(), "Os", &z_ftp, php_ftp_ce, &cmd, &cmd_len) == FAILURE) {
364 RETURN_THROWS();
365 }
366 GET_FTPBUF(ftp, z_ftp);
367
368 /* execute arbitrary ftp command */
369 ftp_raw(ftp, cmd, cmd_len, return_value);
370 }
371 /* }}} */
372
373 /* {{{ Creates a directory and returns the absolute path for the new directory or false on error */
PHP_FUNCTION(ftp_mkdir)374 PHP_FUNCTION(ftp_mkdir)
375 {
376 zval *z_ftp;
377 ftpbuf_t *ftp;
378 char *dir;
379 zend_string *tmp;
380 size_t dir_len;
381
382 if (zend_parse_parameters(ZEND_NUM_ARGS(), "Os", &z_ftp, php_ftp_ce, &dir, &dir_len) == FAILURE) {
383 RETURN_THROWS();
384 }
385 GET_FTPBUF(ftp, z_ftp);
386
387 /* create directory */
388 if (NULL == (tmp = ftp_mkdir(ftp, dir, dir_len))) {
389 if (*ftp->inbuf) {
390 php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
391 }
392 RETURN_FALSE;
393 }
394
395 RETURN_STR(tmp);
396 }
397 /* }}} */
398
399 /* {{{ Removes a directory */
PHP_FUNCTION(ftp_rmdir)400 PHP_FUNCTION(ftp_rmdir)
401 {
402 zval *z_ftp;
403 ftpbuf_t *ftp;
404 char *dir;
405 size_t dir_len;
406
407 if (zend_parse_parameters(ZEND_NUM_ARGS(), "Os", &z_ftp, php_ftp_ce, &dir, &dir_len) == FAILURE) {
408 RETURN_THROWS();
409 }
410 GET_FTPBUF(ftp, z_ftp);
411
412 /* remove directorie */
413 if (!ftp_rmdir(ftp, dir, dir_len)) {
414 if (*ftp->inbuf) {
415 php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
416 }
417 RETURN_FALSE;
418 }
419
420 RETURN_TRUE;
421 }
422 /* }}} */
423
424 /* {{{ Sets permissions on a file */
PHP_FUNCTION(ftp_chmod)425 PHP_FUNCTION(ftp_chmod)
426 {
427 zval *z_ftp;
428 ftpbuf_t *ftp;
429 char *filename;
430 size_t filename_len;
431 zend_long mode;
432
433 if (zend_parse_parameters(ZEND_NUM_ARGS(), "Olp", &z_ftp, php_ftp_ce, &mode, &filename, &filename_len) == FAILURE) {
434 RETURN_THROWS();
435 }
436 GET_FTPBUF(ftp, z_ftp);
437
438 if (!ftp_chmod(ftp, mode, filename, filename_len)) {
439 if (*ftp->inbuf) {
440 php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
441 }
442 RETURN_FALSE;
443 }
444
445 RETURN_LONG(mode);
446 }
447 /* }}} */
448
449 /* {{{ Attempt to allocate space on the remote FTP server */
PHP_FUNCTION(ftp_alloc)450 PHP_FUNCTION(ftp_alloc)
451 {
452 zval *z_ftp, *zresponse = NULL;
453 ftpbuf_t *ftp;
454 zend_long size, ret;
455 zend_string *response = NULL;
456
457 if (zend_parse_parameters(ZEND_NUM_ARGS(), "Ol|z", &z_ftp, php_ftp_ce, &size, &zresponse) == FAILURE) {
458 RETURN_THROWS();
459 }
460 GET_FTPBUF(ftp, z_ftp);
461
462 ret = ftp_alloc(ftp, size, zresponse ? &response : NULL);
463
464 if (response) {
465 ZEND_TRY_ASSIGN_REF_STR(zresponse, response);
466 }
467
468 if (!ret) {
469 RETURN_FALSE;
470 }
471
472 RETURN_TRUE;
473 }
474 /* }}} */
475
476 /* {{{ Returns an array of filenames in the given directory */
PHP_FUNCTION(ftp_nlist)477 PHP_FUNCTION(ftp_nlist)
478 {
479 zval *z_ftp;
480 ftpbuf_t *ftp;
481 char **nlist, **ptr, *dir;
482 size_t dir_len;
483
484 if (zend_parse_parameters(ZEND_NUM_ARGS(), "Op", &z_ftp, php_ftp_ce, &dir, &dir_len) == FAILURE) {
485 RETURN_THROWS();
486 }
487 GET_FTPBUF(ftp, z_ftp);
488
489 /* get list of files */
490 if (NULL == (nlist = ftp_nlist(ftp, dir, dir_len))) {
491 RETURN_FALSE;
492 }
493
494 array_init(return_value);
495 for (ptr = nlist; *ptr; ptr++) {
496 add_next_index_string(return_value, *ptr);
497 }
498 efree(nlist);
499 }
500 /* }}} */
501
502 /* {{{ Returns a detailed listing of a directory as an array of output lines */
PHP_FUNCTION(ftp_rawlist)503 PHP_FUNCTION(ftp_rawlist)
504 {
505 zval *z_ftp;
506 ftpbuf_t *ftp;
507 char **llist, **ptr, *dir;
508 size_t dir_len;
509 bool recursive = 0;
510
511 if (zend_parse_parameters(ZEND_NUM_ARGS(), "Os|b", &z_ftp, php_ftp_ce, &dir, &dir_len, &recursive) == FAILURE) {
512 RETURN_THROWS();
513 }
514 GET_FTPBUF(ftp, z_ftp);
515
516 /* get raw directory listing */
517 if (NULL == (llist = ftp_list(ftp, dir, dir_len, recursive))) {
518 RETURN_FALSE;
519 }
520
521 array_init(return_value);
522 for (ptr = llist; *ptr; ptr++) {
523 add_next_index_string(return_value, *ptr);
524 }
525 efree(llist);
526 }
527 /* }}} */
528
529 /* {{{ Returns a detailed listing of a directory as an array of parsed output lines */
PHP_FUNCTION(ftp_mlsd)530 PHP_FUNCTION(ftp_mlsd)
531 {
532 zval *z_ftp;
533 ftpbuf_t *ftp;
534 char **llist, **ptr, *dir;
535 size_t dir_len;
536 zval entry;
537
538 if (zend_parse_parameters(ZEND_NUM_ARGS(), "Os", &z_ftp, php_ftp_ce, &dir, &dir_len) == FAILURE) {
539 RETURN_THROWS();
540 }
541 GET_FTPBUF(ftp, z_ftp);
542
543 /* get raw directory listing */
544 if (NULL == (llist = ftp_mlsd(ftp, dir, dir_len))) {
545 RETURN_FALSE;
546 }
547
548 array_init(return_value);
549 for (ptr = llist; *ptr; ptr++) {
550 array_init(&entry);
551 if (ftp_mlsd_parse_line(Z_ARRVAL_P(&entry), *ptr) == SUCCESS) {
552 zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &entry);
553 } else {
554 zval_ptr_dtor(&entry);
555 }
556 }
557
558 efree(llist);
559 }
560 /* }}} */
561
562 /* {{{ Returns the system type identifier */
PHP_FUNCTION(ftp_systype)563 PHP_FUNCTION(ftp_systype)
564 {
565 zval *z_ftp;
566 ftpbuf_t *ftp;
567 const char *syst;
568
569 if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &z_ftp, php_ftp_ce) == FAILURE) {
570 RETURN_THROWS();
571 }
572 GET_FTPBUF(ftp, z_ftp);
573
574 if (NULL == (syst = ftp_syst(ftp))) {
575 if (*ftp->inbuf) {
576 php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
577 }
578 RETURN_FALSE;
579 }
580
581 RETURN_STRING((char*) syst);
582 }
583 /* }}} */
584
585 /* {{{ Retrieves a file from the FTP server and writes it to an open file */
PHP_FUNCTION(ftp_fget)586 PHP_FUNCTION(ftp_fget)
587 {
588 zval *z_ftp, *z_file;
589 ftpbuf_t *ftp;
590 ftptype_t xtype;
591 php_stream *stream;
592 char *file;
593 size_t file_len;
594 zend_long mode=FTPTYPE_IMAGE, resumepos=0;
595
596 if (zend_parse_parameters(ZEND_NUM_ARGS(), "Ors|ll", &z_ftp, php_ftp_ce, &z_file, &file, &file_len, &mode, &resumepos) == FAILURE) {
597 RETURN_THROWS();
598 }
599 GET_FTPBUF(ftp, z_ftp);
600 php_stream_from_res(stream, Z_RES_P(z_file));
601 XTYPE(xtype, mode);
602
603 /* ignore autoresume if autoseek is switched off */
604 if (!ftp->autoseek && resumepos == PHP_FTP_AUTORESUME) {
605 resumepos = 0;
606 }
607
608 if (ftp->autoseek && resumepos) {
609 /* if autoresume is wanted seek to end */
610 if (resumepos == PHP_FTP_AUTORESUME) {
611 php_stream_seek(stream, 0, SEEK_END);
612 resumepos = php_stream_tell(stream);
613 } else {
614 php_stream_seek(stream, resumepos, SEEK_SET);
615 }
616 }
617
618 if (!ftp_get(ftp, stream, file, file_len, xtype, resumepos)) {
619 if (*ftp->inbuf) {
620 php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
621 }
622 RETURN_FALSE;
623 }
624
625 RETURN_TRUE;
626 }
627 /* }}} */
628
629 /* {{{ Retrieves a file from the FTP server asynchronly and writes it to an open file */
PHP_FUNCTION(ftp_nb_fget)630 PHP_FUNCTION(ftp_nb_fget)
631 {
632 zval *z_ftp, *z_file;
633 ftpbuf_t *ftp;
634 ftptype_t xtype;
635 php_stream *stream;
636 char *file;
637 size_t file_len;
638 zend_long mode=FTPTYPE_IMAGE, resumepos=0, ret;
639
640 if (zend_parse_parameters(ZEND_NUM_ARGS(), "Ors|ll", &z_ftp, php_ftp_ce, &z_file, &file, &file_len, &mode, &resumepos) == FAILURE) {
641 RETURN_THROWS();
642 }
643 GET_FTPBUF(ftp, z_ftp);
644 php_stream_from_res(stream, Z_RES_P(z_file));
645 XTYPE(xtype, mode);
646
647 /* ignore autoresume if autoseek is switched off */
648 if (!ftp->autoseek && resumepos == PHP_FTP_AUTORESUME) {
649 resumepos = 0;
650 }
651
652 if (ftp->autoseek && resumepos) {
653 /* if autoresume is wanted seek to end */
654 if (resumepos == PHP_FTP_AUTORESUME) {
655 php_stream_seek(stream, 0, SEEK_END);
656 resumepos = php_stream_tell(stream);
657 } else {
658 php_stream_seek(stream, resumepos, SEEK_SET);
659 }
660 }
661
662 /* configuration */
663 ftp->direction = 0; /* recv */
664 ftp->closestream = 0; /* do not close */
665
666 if ((ret = ftp_nb_get(ftp, stream, file, file_len, xtype, resumepos)) == PHP_FTP_FAILED) {
667 if (*ftp->inbuf) {
668 php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
669 }
670 RETURN_LONG(ret);
671 }
672
673 RETURN_LONG(ret);
674 }
675 /* }}} */
676
677 /* {{{ Turns passive mode on or off */
PHP_FUNCTION(ftp_pasv)678 PHP_FUNCTION(ftp_pasv)
679 {
680 zval *z_ftp;
681 ftpbuf_t *ftp;
682 bool pasv;
683
684 if (zend_parse_parameters(ZEND_NUM_ARGS(), "Ob", &z_ftp, php_ftp_ce, &pasv) == FAILURE) {
685 RETURN_THROWS();
686 }
687 GET_FTPBUF(ftp, z_ftp);
688
689 if (!ftp_pasv(ftp, pasv ? 1 : 0)) {
690 RETURN_FALSE;
691 }
692
693 RETURN_TRUE;
694 }
695 /* }}} */
696
697 /* {{{ Retrieves a file from the FTP server and writes it to a local file */
PHP_FUNCTION(ftp_get)698 PHP_FUNCTION(ftp_get)
699 {
700 zval *z_ftp;
701 ftpbuf_t *ftp;
702 ftptype_t xtype;
703 php_stream *outstream;
704 char *local, *remote;
705 size_t local_len, remote_len;
706 zend_long mode=FTPTYPE_IMAGE, resumepos=0;
707
708 if (zend_parse_parameters(ZEND_NUM_ARGS(), "Opp|ll", &z_ftp, php_ftp_ce, &local, &local_len, &remote, &remote_len, &mode, &resumepos) == FAILURE) {
709 RETURN_THROWS();
710 }
711 GET_FTPBUF(ftp, z_ftp);
712 XTYPE(xtype, mode);
713
714 /* ignore autoresume if autoseek is switched off */
715 if (!ftp->autoseek && resumepos == PHP_FTP_AUTORESUME) {
716 resumepos = 0;
717 }
718
719 #ifdef PHP_WIN32
720 mode = FTPTYPE_IMAGE;
721 #endif
722
723 if (ftp->autoseek && resumepos) {
724 outstream = php_stream_open_wrapper(local, mode == FTPTYPE_ASCII ? "rt+" : "rb+", REPORT_ERRORS, NULL);
725 if (outstream == NULL) {
726 outstream = php_stream_open_wrapper(local, mode == FTPTYPE_ASCII ? "wt" : "wb", REPORT_ERRORS, NULL);
727 }
728 if (outstream != NULL) {
729 /* if autoresume is wanted seek to end */
730 if (resumepos == PHP_FTP_AUTORESUME) {
731 php_stream_seek(outstream, 0, SEEK_END);
732 resumepos = php_stream_tell(outstream);
733 } else {
734 php_stream_seek(outstream, resumepos, SEEK_SET);
735 }
736 }
737 } else {
738 outstream = php_stream_open_wrapper(local, mode == FTPTYPE_ASCII ? "wt" : "wb", REPORT_ERRORS, NULL);
739 }
740
741 if (outstream == NULL) {
742 php_error_docref(NULL, E_WARNING, "Error opening %s", local);
743 RETURN_FALSE;
744 }
745
746 if (!ftp_get(ftp, outstream, remote, remote_len, xtype, resumepos)) {
747 php_stream_close(outstream);
748 VCWD_UNLINK(local);
749 if (*ftp->inbuf) {
750 php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
751 }
752 RETURN_FALSE;
753 }
754
755 php_stream_close(outstream);
756 RETURN_TRUE;
757 }
758 /* }}} */
759
760 /* {{{ Retrieves a file from the FTP server nbhronly and writes it to a local file */
PHP_FUNCTION(ftp_nb_get)761 PHP_FUNCTION(ftp_nb_get)
762 {
763 zval *z_ftp;
764 ftpbuf_t *ftp;
765 ftptype_t xtype;
766 php_stream *outstream;
767 char *local, *remote;
768 size_t local_len, remote_len;
769 int ret;
770 zend_long mode=FTPTYPE_IMAGE, resumepos=0;
771
772 if (zend_parse_parameters(ZEND_NUM_ARGS(), "Oss|ll", &z_ftp, php_ftp_ce, &local, &local_len, &remote, &remote_len, &mode, &resumepos) == FAILURE) {
773 RETURN_THROWS();
774 }
775 GET_FTPBUF(ftp, z_ftp);
776 XTYPE(xtype, mode);
777
778 /* ignore autoresume if autoseek is switched off */
779 if (!ftp->autoseek && resumepos == PHP_FTP_AUTORESUME) {
780 resumepos = 0;
781 }
782 #ifdef PHP_WIN32
783 mode = FTPTYPE_IMAGE;
784 #endif
785 if (ftp->autoseek && resumepos) {
786 outstream = php_stream_open_wrapper(local, mode == FTPTYPE_ASCII ? "rt+" : "rb+", REPORT_ERRORS, NULL);
787 if (outstream == NULL) {
788 outstream = php_stream_open_wrapper(local, mode == FTPTYPE_ASCII ? "wt" : "wb", REPORT_ERRORS, NULL);
789 }
790 if (outstream != NULL) {
791 /* if autoresume is wanted seek to end */
792 if (resumepos == PHP_FTP_AUTORESUME) {
793 php_stream_seek(outstream, 0, SEEK_END);
794 resumepos = php_stream_tell(outstream);
795 } else {
796 php_stream_seek(outstream, resumepos, SEEK_SET);
797 }
798 }
799 } else {
800 outstream = php_stream_open_wrapper(local, mode == FTPTYPE_ASCII ? "wt" : "wb", REPORT_ERRORS, NULL);
801 }
802
803 if (outstream == NULL) {
804 php_error_docref(NULL, E_WARNING, "Error opening %s", local);
805 RETURN_FALSE;
806 }
807
808 /* configuration */
809 ftp->direction = 0; /* recv */
810 ftp->closestream = 1; /* do close */
811
812 if ((ret = ftp_nb_get(ftp, outstream, remote, remote_len, xtype, resumepos)) == PHP_FTP_FAILED) {
813 php_stream_close(outstream);
814 ftp->stream = NULL;
815 VCWD_UNLINK(local);
816 if (*ftp->inbuf) {
817 php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
818 }
819 RETURN_LONG(PHP_FTP_FAILED);
820 }
821
822 if (ret == PHP_FTP_FINISHED){
823 php_stream_close(outstream);
824 ftp->stream = NULL;
825 }
826
827 RETURN_LONG(ret);
828 }
829 /* }}} */
830
831 /* {{{ Continues retrieving/sending a file nbronously */
PHP_FUNCTION(ftp_nb_continue)832 PHP_FUNCTION(ftp_nb_continue)
833 {
834 zval *z_ftp;
835 ftpbuf_t *ftp;
836 zend_long ret;
837
838 if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &z_ftp, php_ftp_ce) == FAILURE) {
839 RETURN_THROWS();
840 }
841 GET_FTPBUF(ftp, z_ftp);
842
843 if (!ftp->nb) {
844 php_error_docref(NULL, E_WARNING, "No nbronous transfer to continue");
845 RETURN_LONG(PHP_FTP_FAILED);
846 }
847
848 if (ftp->direction) {
849 ret=ftp_nb_continue_write(ftp);
850 } else {
851 ret=ftp_nb_continue_read(ftp);
852 }
853
854 if (ret != PHP_FTP_MOREDATA && ftp->closestream) {
855 php_stream_close(ftp->stream);
856 ftp->stream = NULL;
857 }
858
859 if (ret == PHP_FTP_FAILED) {
860 php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
861 }
862
863 RETURN_LONG(ret);
864 }
865 /* }}} */
866
867 /* {{{ Stores a file from an open file to the FTP server */
PHP_FUNCTION(ftp_fput)868 PHP_FUNCTION(ftp_fput)
869 {
870 zval *z_ftp, *z_file;
871 ftpbuf_t *ftp;
872 ftptype_t xtype;
873 size_t remote_len;
874 zend_long mode=FTPTYPE_IMAGE, startpos=0;
875 php_stream *stream;
876 char *remote;
877
878 if (zend_parse_parameters(ZEND_NUM_ARGS(), "Osr|ll", &z_ftp, php_ftp_ce, &remote, &remote_len, &z_file, &mode, &startpos) == FAILURE) {
879 RETURN_THROWS();
880 }
881 GET_FTPBUF(ftp, z_ftp);
882 php_stream_from_zval(stream, z_file);
883 XTYPE(xtype, mode);
884
885 /* ignore autoresume if autoseek is switched off */
886 if (!ftp->autoseek && startpos == PHP_FTP_AUTORESUME) {
887 startpos = 0;
888 }
889
890 if (ftp->autoseek && startpos) {
891 /* if autoresume is wanted ask for remote size */
892 if (startpos == PHP_FTP_AUTORESUME) {
893 startpos = ftp_size(ftp, remote, remote_len);
894 if (startpos < 0) {
895 startpos = 0;
896 }
897 }
898 if (startpos) {
899 php_stream_seek(stream, startpos, SEEK_SET);
900 }
901 }
902
903 if (!ftp_put(ftp, remote, remote_len, stream, xtype, startpos)) {
904 if (*ftp->inbuf) {
905 php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
906 }
907 RETURN_FALSE;
908 }
909
910 RETURN_TRUE;
911 }
912 /* }}} */
913
914 /* {{{ Stores a file from an open file to the FTP server nbronly */
PHP_FUNCTION(ftp_nb_fput)915 PHP_FUNCTION(ftp_nb_fput)
916 {
917 zval *z_ftp, *z_file;
918 ftpbuf_t *ftp;
919 ftptype_t xtype;
920 size_t remote_len;
921 int ret;
922 zend_long mode=FTPTYPE_IMAGE, startpos=0;
923 php_stream *stream;
924 char *remote;
925
926 if (zend_parse_parameters(ZEND_NUM_ARGS(), "Osr|ll", &z_ftp, php_ftp_ce, &remote, &remote_len, &z_file, &mode, &startpos) == FAILURE) {
927 RETURN_THROWS();
928 }
929 GET_FTPBUF(ftp, z_ftp);
930 php_stream_from_res(stream, Z_RES_P(z_file));
931 XTYPE(xtype, mode);
932
933 /* ignore autoresume if autoseek is switched off */
934 if (!ftp->autoseek && startpos == PHP_FTP_AUTORESUME) {
935 startpos = 0;
936 }
937
938 if (ftp->autoseek && startpos) {
939 /* if autoresume is wanted ask for remote size */
940 if (startpos == PHP_FTP_AUTORESUME) {
941 startpos = ftp_size(ftp, remote, remote_len);
942 if (startpos < 0) {
943 startpos = 0;
944 }
945 }
946 if (startpos) {
947 php_stream_seek(stream, startpos, SEEK_SET);
948 }
949 }
950
951 /* configuration */
952 ftp->direction = 1; /* send */
953 ftp->closestream = 0; /* do not close */
954
955 if (((ret = ftp_nb_put(ftp, remote, remote_len, stream, xtype, startpos)) == PHP_FTP_FAILED)) {
956 if (*ftp->inbuf) {
957 php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
958 }
959 RETURN_LONG(ret);
960 }
961
962 RETURN_LONG(ret);
963 }
964 /* }}} */
965
966
967 /* {{{ Stores a file on the FTP server */
PHP_FUNCTION(ftp_put)968 PHP_FUNCTION(ftp_put)
969 {
970 zval *z_ftp;
971 ftpbuf_t *ftp;
972 ftptype_t xtype;
973 char *remote, *local;
974 size_t remote_len, local_len;
975 zend_long mode=FTPTYPE_IMAGE, startpos=0;
976 php_stream *instream;
977
978 if (zend_parse_parameters(ZEND_NUM_ARGS(), "Opp|ll", &z_ftp, php_ftp_ce, &remote, &remote_len, &local, &local_len, &mode, &startpos) == FAILURE) {
979 RETURN_THROWS();
980 }
981 GET_FTPBUF(ftp, z_ftp);
982 XTYPE(xtype, mode);
983
984 if (!(instream = php_stream_open_wrapper(local, mode == FTPTYPE_ASCII ? "rt" : "rb", REPORT_ERRORS, NULL))) {
985 RETURN_FALSE;
986 }
987
988 /* ignore autoresume if autoseek is switched off */
989 if (!ftp->autoseek && startpos == PHP_FTP_AUTORESUME) {
990 startpos = 0;
991 }
992
993 if (ftp->autoseek && startpos) {
994 /* if autoresume is wanted ask for remote size */
995 if (startpos == PHP_FTP_AUTORESUME) {
996 startpos = ftp_size(ftp, remote, remote_len);
997 if (startpos < 0) {
998 startpos = 0;
999 }
1000 }
1001 if (startpos) {
1002 php_stream_seek(instream, startpos, SEEK_SET);
1003 }
1004 }
1005
1006 if (!ftp_put(ftp, remote, remote_len, instream, xtype, startpos)) {
1007 php_stream_close(instream);
1008 if (*ftp->inbuf) {
1009 php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
1010 }
1011 RETURN_FALSE;
1012 }
1013 php_stream_close(instream);
1014
1015 RETURN_TRUE;
1016 }
1017 /* }}} */
1018
1019 /* {{{ Append content of a file a another file on the FTP server */
PHP_FUNCTION(ftp_append)1020 PHP_FUNCTION(ftp_append)
1021 {
1022 zval *z_ftp;
1023 ftpbuf_t *ftp;
1024 ftptype_t xtype;
1025 char *remote, *local;
1026 size_t remote_len, local_len;
1027 zend_long mode=FTPTYPE_IMAGE;
1028 php_stream *instream;
1029
1030 if (zend_parse_parameters(ZEND_NUM_ARGS(), "Opp|l", &z_ftp, php_ftp_ce, &remote, &remote_len, &local, &local_len, &mode) == FAILURE) {
1031 RETURN_THROWS();
1032 }
1033 GET_FTPBUF(ftp, z_ftp);
1034 XTYPE(xtype, mode);
1035
1036 if (!(instream = php_stream_open_wrapper(local, mode == FTPTYPE_ASCII ? "rt" : "rb", REPORT_ERRORS, NULL))) {
1037 RETURN_FALSE;
1038 }
1039
1040 if (!ftp_append(ftp, remote, remote_len, instream, xtype)) {
1041 php_stream_close(instream);
1042 if (*ftp->inbuf) {
1043 php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
1044 }
1045 RETURN_FALSE;
1046 }
1047 php_stream_close(instream);
1048
1049 RETURN_TRUE;
1050 }
1051 /* }}} */
1052
1053 /* {{{ Stores a file on the FTP server */
PHP_FUNCTION(ftp_nb_put)1054 PHP_FUNCTION(ftp_nb_put)
1055 {
1056 zval *z_ftp;
1057 ftpbuf_t *ftp;
1058 ftptype_t xtype;
1059 char *remote, *local;
1060 size_t remote_len, local_len;
1061 zend_long mode=FTPTYPE_IMAGE, startpos=0, ret;
1062 php_stream *instream;
1063
1064 if (zend_parse_parameters(ZEND_NUM_ARGS(), "Opp|ll", &z_ftp, php_ftp_ce, &remote, &remote_len, &local, &local_len, &mode, &startpos) == FAILURE) {
1065 RETURN_THROWS();
1066 }
1067 GET_FTPBUF(ftp, z_ftp);
1068 XTYPE(xtype, mode);
1069
1070 if (!(instream = php_stream_open_wrapper(local, mode == FTPTYPE_ASCII ? "rt" : "rb", REPORT_ERRORS, NULL))) {
1071 RETURN_FALSE;
1072 }
1073
1074 /* ignore autoresume if autoseek is switched off */
1075 if (!ftp->autoseek && startpos == PHP_FTP_AUTORESUME) {
1076 startpos = 0;
1077 }
1078
1079 if (ftp->autoseek && startpos) {
1080 /* if autoresume is wanted ask for remote size */
1081 if (startpos == PHP_FTP_AUTORESUME) {
1082 startpos = ftp_size(ftp, remote, remote_len);
1083 if (startpos < 0) {
1084 startpos = 0;
1085 }
1086 }
1087 if (startpos) {
1088 php_stream_seek(instream, startpos, SEEK_SET);
1089 }
1090 }
1091
1092 /* configuration */
1093 ftp->direction = 1; /* send */
1094 ftp->closestream = 1; /* do close */
1095
1096 ret = ftp_nb_put(ftp, remote, remote_len, instream, xtype, startpos);
1097
1098 if (ret != PHP_FTP_MOREDATA) {
1099 php_stream_close(instream);
1100 ftp->stream = NULL;
1101 }
1102
1103 if (ret == PHP_FTP_FAILED) {
1104 php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
1105 }
1106
1107 RETURN_LONG(ret);
1108 }
1109 /* }}} */
1110
1111 /* {{{ Returns the size of the file, or -1 on error */
PHP_FUNCTION(ftp_size)1112 PHP_FUNCTION(ftp_size)
1113 {
1114 zval *z_ftp;
1115 ftpbuf_t *ftp;
1116 char *file;
1117 size_t file_len;
1118
1119 if (zend_parse_parameters(ZEND_NUM_ARGS(), "Op", &z_ftp, php_ftp_ce, &file, &file_len) == FAILURE) {
1120 RETURN_THROWS();
1121 }
1122 GET_FTPBUF(ftp, z_ftp);
1123
1124 /* get file size */
1125 RETURN_LONG(ftp_size(ftp, file, file_len));
1126 }
1127 /* }}} */
1128
1129 /* {{{ Returns the last modification time of the file, or -1 on error */
PHP_FUNCTION(ftp_mdtm)1130 PHP_FUNCTION(ftp_mdtm)
1131 {
1132 zval *z_ftp;
1133 ftpbuf_t *ftp;
1134 char *file;
1135 size_t file_len;
1136
1137 if (zend_parse_parameters(ZEND_NUM_ARGS(), "Op", &z_ftp, php_ftp_ce, &file, &file_len) == FAILURE) {
1138 RETURN_THROWS();
1139 }
1140 GET_FTPBUF(ftp, z_ftp);
1141
1142 /* get file mod time */
1143 RETURN_LONG(ftp_mdtm(ftp, file, file_len));
1144 }
1145 /* }}} */
1146
1147 /* {{{ Renames the given file to a new path */
PHP_FUNCTION(ftp_rename)1148 PHP_FUNCTION(ftp_rename)
1149 {
1150 zval *z_ftp;
1151 ftpbuf_t *ftp;
1152 char *src, *dest;
1153 size_t src_len, dest_len;
1154
1155 if (zend_parse_parameters(ZEND_NUM_ARGS(), "Oss", &z_ftp, php_ftp_ce, &src, &src_len, &dest, &dest_len) == FAILURE) {
1156 RETURN_THROWS();
1157 }
1158 GET_FTPBUF(ftp, z_ftp);
1159
1160 /* rename the file */
1161 if (!ftp_rename(ftp, src, src_len, dest, dest_len)) {
1162 if (*ftp->inbuf) {
1163 php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
1164 }
1165 RETURN_FALSE;
1166 }
1167
1168 RETURN_TRUE;
1169 }
1170 /* }}} */
1171
1172 /* {{{ Deletes a file */
PHP_FUNCTION(ftp_delete)1173 PHP_FUNCTION(ftp_delete)
1174 {
1175 zval *z_ftp;
1176 ftpbuf_t *ftp;
1177 char *file;
1178 size_t file_len;
1179
1180 if (zend_parse_parameters(ZEND_NUM_ARGS(), "Os", &z_ftp, php_ftp_ce, &file, &file_len) == FAILURE) {
1181 RETURN_THROWS();
1182 }
1183 GET_FTPBUF(ftp, z_ftp);
1184
1185 /* delete the file */
1186 if (!ftp_delete(ftp, file, file_len)) {
1187 if (*ftp->inbuf) {
1188 php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
1189 }
1190 RETURN_FALSE;
1191 }
1192
1193 RETURN_TRUE;
1194 }
1195 /* }}} */
1196
1197 /* {{{ Sends a SITE command to the server */
PHP_FUNCTION(ftp_site)1198 PHP_FUNCTION(ftp_site)
1199 {
1200 zval *z_ftp;
1201 ftpbuf_t *ftp;
1202 char *cmd;
1203 size_t cmd_len;
1204
1205 if (zend_parse_parameters(ZEND_NUM_ARGS(), "Os", &z_ftp, php_ftp_ce, &cmd, &cmd_len) == FAILURE) {
1206 RETURN_THROWS();
1207 }
1208 GET_FTPBUF(ftp, z_ftp);
1209
1210 /* send the site command */
1211 if (!ftp_site(ftp, cmd, cmd_len)) {
1212 if (*ftp->inbuf) {
1213 php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
1214 }
1215 RETURN_FALSE;
1216 }
1217
1218 RETURN_TRUE;
1219 }
1220 /* }}} */
1221
1222 /* {{{ Closes the FTP stream */
PHP_FUNCTION(ftp_close)1223 PHP_FUNCTION(ftp_close)
1224 {
1225 zval *z_ftp;
1226 php_ftp_object *obj;
1227 bool success = true;
1228
1229 if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &z_ftp, php_ftp_ce) == FAILURE) {
1230 RETURN_THROWS();
1231 }
1232
1233 obj = ftp_object_from_zend_object(Z_OBJ_P(z_ftp));
1234 if (obj->ftp) {
1235 success = ftp_quit(obj->ftp);
1236 ftp_close(obj->ftp);
1237 obj->ftp = NULL;
1238 }
1239
1240 RETURN_BOOL(success);
1241 }
1242 /* }}} */
1243
1244 /* {{{ Sets an FTP option */
PHP_FUNCTION(ftp_set_option)1245 PHP_FUNCTION(ftp_set_option)
1246 {
1247 zval *z_ftp, *z_value;
1248 zend_long option;
1249 ftpbuf_t *ftp;
1250
1251 if (zend_parse_parameters(ZEND_NUM_ARGS(), "Olz", &z_ftp, php_ftp_ce, &option, &z_value) == FAILURE) {
1252 RETURN_THROWS();
1253 }
1254 GET_FTPBUF(ftp, z_ftp);
1255
1256 switch (option) {
1257 case PHP_FTP_OPT_TIMEOUT_SEC:
1258 if (Z_TYPE_P(z_value) != IS_LONG) {
1259 zend_argument_type_error(3, "must be of type int for the FTP_TIMEOUT_SEC option, %s given", zend_zval_type_name(z_value));
1260 RETURN_THROWS();
1261 }
1262 if (Z_LVAL_P(z_value) <= 0) {
1263 zend_argument_value_error(3, "must be greater than 0 for the FTP_TIMEOUT_SEC option");
1264 RETURN_THROWS();
1265 }
1266 ftp->timeout_sec = Z_LVAL_P(z_value);
1267 RETURN_TRUE;
1268 break;
1269 case PHP_FTP_OPT_AUTOSEEK:
1270 if (Z_TYPE_P(z_value) != IS_TRUE && Z_TYPE_P(z_value) != IS_FALSE) {
1271 zend_argument_type_error(3, "must be of type bool for the FTP_AUTOSEEK option, %s given", zend_zval_type_name(z_value));
1272 RETURN_THROWS();
1273 }
1274 ftp->autoseek = Z_TYPE_P(z_value) == IS_TRUE ? 1 : 0;
1275 RETURN_TRUE;
1276 break;
1277 case PHP_FTP_OPT_USEPASVADDRESS:
1278 if (Z_TYPE_P(z_value) != IS_TRUE && Z_TYPE_P(z_value) != IS_FALSE) {
1279 zend_argument_type_error(3, "must be of type bool for the FTP_USEPASVADDRESS option, %s given", zend_zval_type_name(z_value));
1280 RETURN_THROWS();
1281 }
1282 ftp->usepasvaddress = Z_TYPE_P(z_value) == IS_TRUE ? 1 : 0;
1283 RETURN_TRUE;
1284 break;
1285 default:
1286 zend_argument_value_error(2, "must be one of FTP_TIMEOUT_SEC, FTP_AUTOSEEK, or FTP_USEPASVADDRESS");
1287 RETURN_THROWS();
1288 break;
1289 }
1290 }
1291 /* }}} */
1292
1293 /* {{{ Gets an FTP option */
PHP_FUNCTION(ftp_get_option)1294 PHP_FUNCTION(ftp_get_option)
1295 {
1296 zval *z_ftp;
1297 zend_long option;
1298 ftpbuf_t *ftp;
1299
1300 if (zend_parse_parameters(ZEND_NUM_ARGS(), "Ol", &z_ftp, php_ftp_ce, &option) == FAILURE) {
1301 RETURN_THROWS();
1302 }
1303 GET_FTPBUF(ftp, z_ftp);
1304
1305 switch (option) {
1306 case PHP_FTP_OPT_TIMEOUT_SEC:
1307 RETURN_LONG(ftp->timeout_sec);
1308 break;
1309 case PHP_FTP_OPT_AUTOSEEK:
1310 RETURN_BOOL(ftp->autoseek);
1311 break;
1312 case PHP_FTP_OPT_USEPASVADDRESS:
1313 RETURN_BOOL(ftp->usepasvaddress);
1314 break;
1315 default:
1316 zend_argument_value_error(2, "must be one of FTP_TIMEOUT_SEC, FTP_AUTOSEEK, or FTP_USEPASVADDRESS");
1317 RETURN_THROWS();
1318 }
1319 }
1320 /* }}} */
1321
1322 #endif /* HAVE_FTP */
1323