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