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