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