1 /*
2 +----------------------------------------------------------------------+
3 | PHP Version 5 |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 1997-2016 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 #if HAVE_OPENSSL_EXT
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 #if HAVE_OPENSSL_EXT
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 #if HAVE_OPENSSL_EXT
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,
286 "ftp",
287 php_ftp_functions,
288 PHP_MINIT(ftp),
289 NULL,
290 NULL,
291 NULL,
292 PHP_MINFO(ftp),
293 NO_VERSION_YET,
294 STANDARD_MODULE_PROPERTIES
295 };
296
297 #if COMPILE_DL_FTP
ZEND_GET_MODULE(php_ftp)298 ZEND_GET_MODULE(php_ftp)
299 #endif
300
301 static void ftp_destructor_ftpbuf(zend_rsrc_list_entry *rsrc TSRMLS_DC)
302 {
303 ftpbuf_t *ftp = (ftpbuf_t *)rsrc->ptr;
304
305 ftp_close(ftp);
306 }
307
PHP_MINIT_FUNCTION(ftp)308 PHP_MINIT_FUNCTION(ftp)
309 {
310 le_ftpbuf = zend_register_list_destructors_ex(ftp_destructor_ftpbuf, NULL, le_ftpbuf_name, module_number);
311 REGISTER_LONG_CONSTANT("FTP_ASCII", FTPTYPE_ASCII, CONST_PERSISTENT | CONST_CS);
312 REGISTER_LONG_CONSTANT("FTP_TEXT", FTPTYPE_ASCII, CONST_PERSISTENT | CONST_CS);
313 REGISTER_LONG_CONSTANT("FTP_BINARY", FTPTYPE_IMAGE, CONST_PERSISTENT | CONST_CS);
314 REGISTER_LONG_CONSTANT("FTP_IMAGE", FTPTYPE_IMAGE, CONST_PERSISTENT | CONST_CS);
315 REGISTER_LONG_CONSTANT("FTP_AUTORESUME", PHP_FTP_AUTORESUME, CONST_PERSISTENT | CONST_CS);
316 REGISTER_LONG_CONSTANT("FTP_TIMEOUT_SEC", PHP_FTP_OPT_TIMEOUT_SEC, CONST_PERSISTENT | CONST_CS);
317 REGISTER_LONG_CONSTANT("FTP_AUTOSEEK", PHP_FTP_OPT_AUTOSEEK, CONST_PERSISTENT | CONST_CS);
318 REGISTER_LONG_CONSTANT("FTP_USEPASVADDRESS", PHP_FTP_OPT_USEPASVADDRESS, CONST_PERSISTENT | CONST_CS);
319 REGISTER_LONG_CONSTANT("FTP_FAILED", PHP_FTP_FAILED, CONST_PERSISTENT | CONST_CS);
320 REGISTER_LONG_CONSTANT("FTP_FINISHED", PHP_FTP_FINISHED, CONST_PERSISTENT | CONST_CS);
321 REGISTER_LONG_CONSTANT("FTP_MOREDATA", PHP_FTP_MOREDATA, CONST_PERSISTENT | CONST_CS);
322 return SUCCESS;
323 }
324
PHP_MINFO_FUNCTION(ftp)325 PHP_MINFO_FUNCTION(ftp)
326 {
327 php_info_print_table_start();
328 php_info_print_table_row(2, "FTP support", "enabled");
329 php_info_print_table_end();
330 }
331
332 #define XTYPE(xtype, mode) { \
333 if (mode != FTPTYPE_ASCII && mode != FTPTYPE_IMAGE) { \
334 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Mode must be FTP_ASCII or FTP_BINARY"); \
335 RETURN_FALSE; \
336 } \
337 xtype = mode; \
338 }
339
340
341 /* {{{ proto resource ftp_connect(string host [, int port [, int timeout]])
342 Opens a FTP stream */
PHP_FUNCTION(ftp_connect)343 PHP_FUNCTION(ftp_connect)
344 {
345 ftpbuf_t *ftp;
346 char *host;
347 int host_len;
348 long port = 0;
349 long timeout_sec = FTP_DEFAULT_TIMEOUT;
350
351 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ll", &host, &host_len, &port, &timeout_sec) == FAILURE) {
352 return;
353 }
354
355 if (timeout_sec <= 0) {
356 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Timeout has to be greater than 0");
357 RETURN_FALSE;
358 }
359
360 /* connect */
361 if (!(ftp = ftp_open(host, (short)port, timeout_sec TSRMLS_CC))) {
362 RETURN_FALSE;
363 }
364
365 /* autoseek for resuming */
366 ftp->autoseek = FTP_DEFAULT_AUTOSEEK;
367 ftp->usepasvaddress = FTP_DEFAULT_USEPASVADDRESS;
368 #if HAVE_OPENSSL_EXT
369 /* disable ssl */
370 ftp->use_ssl = 0;
371 #endif
372
373 ZEND_REGISTER_RESOURCE(return_value, ftp, le_ftpbuf);
374 }
375 /* }}} */
376
377 #if HAVE_OPENSSL_EXT
378 /* {{{ proto resource ftp_ssl_connect(string host [, int port [, int timeout]])
379 Opens a FTP-SSL stream */
PHP_FUNCTION(ftp_ssl_connect)380 PHP_FUNCTION(ftp_ssl_connect)
381 {
382 ftpbuf_t *ftp;
383 char *host;
384 int host_len;
385 long port = 0;
386 long timeout_sec = FTP_DEFAULT_TIMEOUT;
387
388 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ll", &host, &host_len, &port, &timeout_sec) == FAILURE) {
389 return;
390 }
391
392 if (timeout_sec <= 0) {
393 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Timeout has to be greater than 0");
394 RETURN_FALSE;
395 }
396
397 /* connect */
398 if (!(ftp = ftp_open(host, (short)port, timeout_sec TSRMLS_CC))) {
399 RETURN_FALSE;
400 }
401
402 /* autoseek for resuming */
403 ftp->autoseek = FTP_DEFAULT_AUTOSEEK;
404 ftp->usepasvaddress = FTP_DEFAULT_USEPASVADDRESS;
405 /* enable ssl */
406 ftp->use_ssl = 1;
407
408 ZEND_REGISTER_RESOURCE(return_value, ftp, le_ftpbuf);
409 }
410 /* }}} */
411 #endif
412
413 /* {{{ proto bool ftp_login(resource stream, string username, string password)
414 Logs into the FTP server */
PHP_FUNCTION(ftp_login)415 PHP_FUNCTION(ftp_login)
416 {
417 zval *z_ftp;
418 ftpbuf_t *ftp;
419 char *user, *pass;
420 int user_len, pass_len;
421
422 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rss", &z_ftp, &user, &user_len, &pass, &pass_len) == FAILURE) {
423 return;
424 }
425
426 ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
427
428 /* log in */
429 if (!ftp_login(ftp, user, pass TSRMLS_CC)) {
430 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ftp->inbuf);
431 RETURN_FALSE;
432 }
433
434 RETURN_TRUE;
435 }
436 /* }}} */
437
438 /* {{{ proto string ftp_pwd(resource stream)
439 Returns the present working directory */
PHP_FUNCTION(ftp_pwd)440 PHP_FUNCTION(ftp_pwd)
441 {
442 zval *z_ftp;
443 ftpbuf_t *ftp;
444 const char *pwd;
445
446 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &z_ftp) == FAILURE) {
447 return;
448 }
449
450 ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
451
452 if (!(pwd = ftp_pwd(ftp))) {
453 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ftp->inbuf);
454 RETURN_FALSE;
455 }
456
457 RETURN_STRING((char*) pwd, 1);
458 }
459 /* }}} */
460
461 /* {{{ proto bool ftp_cdup(resource stream)
462 Changes to the parent directory */
PHP_FUNCTION(ftp_cdup)463 PHP_FUNCTION(ftp_cdup)
464 {
465 zval *z_ftp;
466 ftpbuf_t *ftp;
467
468 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &z_ftp) == FAILURE) {
469 return;
470 }
471
472 ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
473
474 if (!ftp_cdup(ftp)) {
475 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ftp->inbuf);
476 RETURN_FALSE;
477 }
478
479 RETURN_TRUE;
480 }
481 /* }}} */
482
483 /* {{{ proto bool ftp_chdir(resource stream, string directory)
484 Changes directories */
PHP_FUNCTION(ftp_chdir)485 PHP_FUNCTION(ftp_chdir)
486 {
487 zval *z_ftp;
488 ftpbuf_t *ftp;
489 char *dir;
490 int dir_len;
491
492 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &z_ftp, &dir, &dir_len) == FAILURE) {
493 return;
494 }
495
496 ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
497
498 /* change directories */
499 if (!ftp_chdir(ftp, dir)) {
500 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ftp->inbuf);
501 RETURN_FALSE;
502 }
503
504 RETURN_TRUE;
505 }
506 /* }}} */
507
508 /* {{{ proto bool ftp_exec(resource stream, string command)
509 Requests execution of a program on the FTP server */
PHP_FUNCTION(ftp_exec)510 PHP_FUNCTION(ftp_exec)
511 {
512 zval *z_ftp;
513 ftpbuf_t *ftp;
514 char *cmd;
515 int cmd_len;
516
517 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &z_ftp, &cmd, &cmd_len) == FAILURE) {
518 return;
519 }
520
521 ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
522
523 /* execute serverside command */
524 if (!ftp_exec(ftp, cmd)) {
525 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ftp->inbuf);
526 RETURN_FALSE;
527 }
528
529 RETURN_TRUE;
530 }
531 /* }}} */
532
533 /* {{{ proto array ftp_raw(resource stream, string command)
534 Sends a literal command to the FTP server */
PHP_FUNCTION(ftp_raw)535 PHP_FUNCTION(ftp_raw)
536 {
537 zval *z_ftp;
538 ftpbuf_t *ftp;
539 char *cmd;
540 int cmd_len;
541
542 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &z_ftp, &cmd, &cmd_len) == FAILURE) {
543 return;
544 }
545
546 ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
547
548 /* execute arbitrary ftp command */
549 ftp_raw(ftp, cmd, return_value);
550 }
551 /* }}} */
552
553 /* {{{ proto string ftp_mkdir(resource stream, string directory)
554 Creates a directory and returns the absolute path for the new directory or false on error */
PHP_FUNCTION(ftp_mkdir)555 PHP_FUNCTION(ftp_mkdir)
556 {
557 zval *z_ftp;
558 ftpbuf_t *ftp;
559 char *dir, *tmp;
560 int dir_len;
561
562 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &z_ftp, &dir, &dir_len) == FAILURE) {
563 return;
564 }
565
566 ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
567
568 /* create directorie */
569 if (NULL == (tmp = ftp_mkdir(ftp, dir))) {
570 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ftp->inbuf);
571 RETURN_FALSE;
572 }
573
574 RETURN_STRING(tmp, 0);
575 }
576 /* }}} */
577
578 /* {{{ proto bool ftp_rmdir(resource stream, string directory)
579 Removes a directory */
PHP_FUNCTION(ftp_rmdir)580 PHP_FUNCTION(ftp_rmdir)
581 {
582 zval *z_ftp;
583 ftpbuf_t *ftp;
584 char *dir;
585 int dir_len;
586
587 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &z_ftp, &dir, &dir_len) == FAILURE) {
588 return;
589 }
590
591 ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
592
593 /* remove directorie */
594 if (!ftp_rmdir(ftp, dir)) {
595 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ftp->inbuf);
596 RETURN_FALSE;
597 }
598
599 RETURN_TRUE;
600 }
601 /* }}} */
602
603 /* {{{ proto int ftp_chmod(resource stream, int mode, string filename)
604 Sets permissions on a file */
PHP_FUNCTION(ftp_chmod)605 PHP_FUNCTION(ftp_chmod)
606 {
607 zval *z_ftp;
608 ftpbuf_t *ftp;
609 char *filename;
610 int filename_len;
611 long mode;
612
613 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rlp", &z_ftp, &mode, &filename, &filename_len) == FAILURE) {
614 RETURN_FALSE;
615 }
616
617 ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
618
619 if (!ftp_chmod(ftp, mode, filename, filename_len)) {
620 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ftp->inbuf);
621 RETURN_FALSE;
622 }
623
624 RETURN_LONG(mode);
625 }
626 /* }}} */
627
628 /* {{{ proto bool ftp_alloc(resource stream, int size[, &response])
629 Attempt to allocate space on the remote FTP server */
PHP_FUNCTION(ftp_alloc)630 PHP_FUNCTION(ftp_alloc)
631 {
632 zval *z_ftp, *zresponse = NULL;
633 ftpbuf_t *ftp;
634 long size, ret;
635 char *response = NULL;
636
637 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl|z", &z_ftp, &size, &zresponse) == FAILURE) {
638 RETURN_FALSE;
639 }
640
641 ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
642
643 ret = ftp_alloc(ftp, size, zresponse ? &response : NULL);
644 if (response) {
645 zval_dtor(zresponse);
646 ZVAL_STRING(zresponse, response, 0);
647 }
648
649 if (!ret) {
650 RETURN_FALSE;
651 }
652
653 RETURN_TRUE;
654 }
655 /* }}} */
656
657 /* {{{ proto array ftp_nlist(resource stream, string directory)
658 Returns an array of filenames in the given directory */
PHP_FUNCTION(ftp_nlist)659 PHP_FUNCTION(ftp_nlist)
660 {
661 zval *z_ftp;
662 ftpbuf_t *ftp;
663 char **nlist, **ptr, *dir;
664 int dir_len;
665
666 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rp", &z_ftp, &dir, &dir_len) == FAILURE) {
667 return;
668 }
669
670 ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
671
672 /* get list of files */
673 if (NULL == (nlist = ftp_nlist(ftp, dir TSRMLS_CC))) {
674 RETURN_FALSE;
675 }
676
677 array_init(return_value);
678 for (ptr = nlist; *ptr; ptr++) {
679 add_next_index_string(return_value, *ptr, 1);
680 }
681 efree(nlist);
682 }
683 /* }}} */
684
685 /* {{{ proto array ftp_rawlist(resource stream, string directory [, bool recursive])
686 Returns a detailed listing of a directory as an array of output lines */
PHP_FUNCTION(ftp_rawlist)687 PHP_FUNCTION(ftp_rawlist)
688 {
689 zval *z_ftp;
690 ftpbuf_t *ftp;
691 char **llist, **ptr, *dir;
692 int dir_len;
693 zend_bool recursive = 0;
694
695 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|b", &z_ftp, &dir, &dir_len, &recursive) == FAILURE) {
696 return;
697 }
698
699 ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
700
701 /* get raw directory listing */
702 if (NULL == (llist = ftp_list(ftp, dir, recursive TSRMLS_CC))) {
703 RETURN_FALSE;
704 }
705
706 array_init(return_value);
707 for (ptr = llist; *ptr; ptr++) {
708 add_next_index_string(return_value, *ptr, 1);
709 }
710 efree(llist);
711 }
712 /* }}} */
713
714 /* {{{ proto string ftp_systype(resource stream)
715 Returns the system type identifier */
PHP_FUNCTION(ftp_systype)716 PHP_FUNCTION(ftp_systype)
717 {
718 zval *z_ftp;
719 ftpbuf_t *ftp;
720 const char *syst;
721
722 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &z_ftp) == FAILURE) {
723 return;
724 }
725
726 ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
727
728 if (NULL == (syst = ftp_syst(ftp))) {
729 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ftp->inbuf);
730 RETURN_FALSE;
731 }
732
733 RETURN_STRING((char*) syst, 1);
734 }
735 /* }}} */
736
737 /* {{{ proto bool ftp_fget(resource stream, resource fp, string remote_file, int mode[, int resumepos])
738 Retrieves a file from the FTP server and writes it to an open file */
PHP_FUNCTION(ftp_fget)739 PHP_FUNCTION(ftp_fget)
740 {
741 zval *z_ftp, *z_file;
742 ftpbuf_t *ftp;
743 ftptype_t xtype;
744 php_stream *stream;
745 char *file;
746 int file_len;
747 long mode, resumepos=0;
748
749 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rrsl|l", &z_ftp, &z_file, &file, &file_len, &mode, &resumepos) == FAILURE) {
750 return;
751 }
752
753 ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
754 php_stream_from_zval(stream, &z_file);
755 XTYPE(xtype, mode);
756
757 /* ignore autoresume if autoseek is switched off */
758 if (!ftp->autoseek && resumepos == PHP_FTP_AUTORESUME) {
759 resumepos = 0;
760 }
761
762 if (ftp->autoseek && resumepos) {
763 /* if autoresume is wanted seek to end */
764 if (resumepos == PHP_FTP_AUTORESUME) {
765 php_stream_seek(stream, 0, SEEK_END);
766 resumepos = php_stream_tell(stream);
767 } else {
768 php_stream_seek(stream, resumepos, SEEK_SET);
769 }
770 }
771
772 if (!ftp_get(ftp, stream, file, xtype, resumepos TSRMLS_CC)) {
773 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ftp->inbuf);
774 RETURN_FALSE;
775 }
776
777 RETURN_TRUE;
778 }
779 /* }}} */
780
781 /* {{{ proto int ftp_nb_fget(resource stream, resource fp, string remote_file, int mode[, int resumepos])
782 Retrieves a file from the FTP server asynchronly and writes it to an open file */
PHP_FUNCTION(ftp_nb_fget)783 PHP_FUNCTION(ftp_nb_fget)
784 {
785 zval *z_ftp, *z_file;
786 ftpbuf_t *ftp;
787 ftptype_t xtype;
788 php_stream *stream;
789 char *file;
790 int file_len;
791 long mode, resumepos=0, ret;
792
793 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rrsl|l", &z_ftp, &z_file, &file, &file_len, &mode, &resumepos) == FAILURE) {
794 return;
795 }
796
797 ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
798 php_stream_from_zval(stream, &z_file);
799 XTYPE(xtype, mode);
800
801 /* ignore autoresume if autoseek is switched off */
802 if (!ftp->autoseek && resumepos == PHP_FTP_AUTORESUME) {
803 resumepos = 0;
804 }
805
806 if (ftp->autoseek && resumepos) {
807 /* if autoresume is wanted seek to end */
808 if (resumepos == PHP_FTP_AUTORESUME) {
809 php_stream_seek(stream, 0, SEEK_END);
810 resumepos = php_stream_tell(stream);
811 } else {
812 php_stream_seek(stream, resumepos, SEEK_SET);
813 }
814 }
815
816 /* configuration */
817 ftp->direction = 0; /* recv */
818 ftp->closestream = 0; /* do not close */
819
820 if ((ret = ftp_nb_get(ftp, stream, file, xtype, resumepos TSRMLS_CC)) == PHP_FTP_FAILED) {
821 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ftp->inbuf);
822 RETURN_LONG(ret);
823 }
824
825 RETURN_LONG(ret);
826 }
827 /* }}} */
828
829 /* {{{ proto bool ftp_pasv(resource stream, bool pasv)
830 Turns passive mode on or off */
PHP_FUNCTION(ftp_pasv)831 PHP_FUNCTION(ftp_pasv)
832 {
833 zval *z_ftp;
834 ftpbuf_t *ftp;
835 zend_bool pasv;
836
837 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rb", &z_ftp, &pasv) == FAILURE) {
838 return;
839 }
840
841 ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
842
843 if (!ftp_pasv(ftp, pasv ? 1 : 0)) {
844 RETURN_FALSE;
845 }
846
847 RETURN_TRUE;
848 }
849 /* }}} */
850
851 /* {{{ proto bool ftp_get(resource stream, string local_file, string remote_file, int mode[, int resume_pos])
852 Retrieves a file from the FTP server and writes it to a local file */
PHP_FUNCTION(ftp_get)853 PHP_FUNCTION(ftp_get)
854 {
855 zval *z_ftp;
856 ftpbuf_t *ftp;
857 ftptype_t xtype;
858 php_stream *outstream;
859 char *local, *remote;
860 int local_len, remote_len;
861 long mode, resumepos=0;
862
863 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rppl|l", &z_ftp, &local, &local_len, &remote, &remote_len, &mode, &resumepos) == FAILURE) {
864 return;
865 }
866
867 ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
868 XTYPE(xtype, mode);
869
870 /* ignore autoresume if autoseek is switched off */
871 if (!ftp->autoseek && resumepos == PHP_FTP_AUTORESUME) {
872 resumepos = 0;
873 }
874
875 #ifdef PHP_WIN32
876 mode = FTPTYPE_IMAGE;
877 #endif
878
879 if (ftp->autoseek && resumepos) {
880 outstream = php_stream_open_wrapper(local, mode == FTPTYPE_ASCII ? "rt+" : "rb+", REPORT_ERRORS, NULL);
881 if (outstream == NULL) {
882 outstream = php_stream_open_wrapper(local, mode == FTPTYPE_ASCII ? "wt" : "wb", REPORT_ERRORS, NULL);
883 }
884 if (outstream != NULL) {
885 /* if autoresume is wanted seek to end */
886 if (resumepos == PHP_FTP_AUTORESUME) {
887 php_stream_seek(outstream, 0, SEEK_END);
888 resumepos = php_stream_tell(outstream);
889 } else {
890 php_stream_seek(outstream, resumepos, SEEK_SET);
891 }
892 }
893 } else {
894 outstream = php_stream_open_wrapper(local, mode == FTPTYPE_ASCII ? "wt" : "wb", REPORT_ERRORS, NULL);
895 }
896
897 if (outstream == NULL) {
898 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error opening %s", local);
899 RETURN_FALSE;
900 }
901
902 if (!ftp_get(ftp, outstream, remote, xtype, resumepos TSRMLS_CC)) {
903 php_stream_close(outstream);
904 VCWD_UNLINK(local);
905 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ftp->inbuf);
906 RETURN_FALSE;
907 }
908
909 php_stream_close(outstream);
910 RETURN_TRUE;
911 }
912 /* }}} */
913
914 /* {{{ proto int ftp_nb_get(resource stream, string local_file, string remote_file, int mode[, int resume_pos])
915 Retrieves a file from the FTP server nbhronly and writes it to a local file */
PHP_FUNCTION(ftp_nb_get)916 PHP_FUNCTION(ftp_nb_get)
917 {
918 zval *z_ftp;
919 ftpbuf_t *ftp;
920 ftptype_t xtype;
921 php_stream *outstream;
922 char *local, *remote;
923 int local_len, remote_len, ret;
924 long mode, resumepos=0;
925
926 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rssl|l", &z_ftp, &local, &local_len, &remote, &remote_len, &mode, &resumepos) == FAILURE) {
927 return;
928 }
929
930 ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
931 XTYPE(xtype, mode);
932
933 /* ignore autoresume if autoseek is switched off */
934 if (!ftp->autoseek && resumepos == PHP_FTP_AUTORESUME) {
935 resumepos = 0;
936 }
937 #ifdef PHP_WIN32
938 mode = FTPTYPE_IMAGE;
939 #endif
940 if (ftp->autoseek && resumepos) {
941 outstream = php_stream_open_wrapper(local, mode == FTPTYPE_ASCII ? "rt+" : "rb+", REPORT_ERRORS, NULL);
942 if (outstream == NULL) {
943 outstream = php_stream_open_wrapper(local, mode == FTPTYPE_ASCII ? "wt" : "wb", REPORT_ERRORS, NULL);
944 }
945 if (outstream != NULL) {
946 /* if autoresume is wanted seek to end */
947 if (resumepos == PHP_FTP_AUTORESUME) {
948 php_stream_seek(outstream, 0, SEEK_END);
949 resumepos = php_stream_tell(outstream);
950 } else {
951 php_stream_seek(outstream, resumepos, SEEK_SET);
952 }
953 }
954 } else {
955 outstream = php_stream_open_wrapper(local, mode == FTPTYPE_ASCII ? "wt" : "wb", REPORT_ERRORS, NULL);
956 }
957
958 if (outstream == NULL) {
959 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error opening %s", local);
960 RETURN_FALSE;
961 }
962
963 /* configuration */
964 ftp->direction = 0; /* recv */
965 ftp->closestream = 1; /* do close */
966
967 if ((ret = ftp_nb_get(ftp, outstream, remote, xtype, resumepos TSRMLS_CC)) == PHP_FTP_FAILED) {
968 php_stream_close(outstream);
969 ftp->stream = NULL;
970 VCWD_UNLINK(local);
971 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ftp->inbuf);
972 RETURN_LONG(PHP_FTP_FAILED);
973 }
974
975 if (ret == PHP_FTP_FINISHED){
976 php_stream_close(outstream);
977 ftp->stream = NULL;
978 }
979
980 RETURN_LONG(ret);
981 }
982 /* }}} */
983
984 /* {{{ proto int ftp_nb_continue(resource stream)
985 Continues retrieving/sending a file nbronously */
PHP_FUNCTION(ftp_nb_continue)986 PHP_FUNCTION(ftp_nb_continue)
987 {
988 zval *z_ftp;
989 ftpbuf_t *ftp;
990 long ret;
991
992 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &z_ftp) == FAILURE) {
993 return;
994 }
995
996 ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
997
998 if (!ftp->nb) {
999 php_error_docref(NULL TSRMLS_CC, E_WARNING, "no nbronous transfer to continue.");
1000 RETURN_LONG(PHP_FTP_FAILED);
1001 }
1002
1003 if (ftp->direction) {
1004 ret=ftp_nb_continue_write(ftp TSRMLS_CC);
1005 } else {
1006 ret=ftp_nb_continue_read(ftp TSRMLS_CC);
1007 }
1008
1009 if (ret != PHP_FTP_MOREDATA && ftp->closestream) {
1010 php_stream_close(ftp->stream);
1011 ftp->stream = NULL;
1012 }
1013
1014 if (ret == PHP_FTP_FAILED) {
1015 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ftp->inbuf);
1016 }
1017
1018 RETURN_LONG(ret);
1019 }
1020 /* }}} */
1021
1022 /* {{{ proto bool ftp_fput(resource stream, string remote_file, resource fp, int mode[, int startpos])
1023 Stores a file from an open file to the FTP server */
PHP_FUNCTION(ftp_fput)1024 PHP_FUNCTION(ftp_fput)
1025 {
1026 zval *z_ftp, *z_file;
1027 ftpbuf_t *ftp;
1028 ftptype_t xtype;
1029 int remote_len;
1030 long mode, startpos=0;
1031 php_stream *stream;
1032 char *remote;
1033
1034 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsrl|l", &z_ftp, &remote, &remote_len, &z_file, &mode, &startpos) == FAILURE) {
1035 return;
1036 }
1037
1038 ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
1039 php_stream_from_zval(stream, &z_file);
1040 XTYPE(xtype, mode);
1041
1042 /* ignore autoresume if autoseek is switched off */
1043 if (!ftp->autoseek && startpos == PHP_FTP_AUTORESUME) {
1044 startpos = 0;
1045 }
1046
1047 if (ftp->autoseek && startpos) {
1048 /* if autoresume is wanted ask for remote size */
1049 if (startpos == PHP_FTP_AUTORESUME) {
1050 startpos = ftp_size(ftp, remote);
1051 if (startpos < 0) {
1052 startpos = 0;
1053 }
1054 }
1055 if (startpos) {
1056 php_stream_seek(stream, startpos, SEEK_SET);
1057 }
1058 }
1059
1060 if (!ftp_put(ftp, remote, stream, xtype, startpos TSRMLS_CC)) {
1061 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ftp->inbuf);
1062 RETURN_FALSE;
1063 }
1064
1065 RETURN_TRUE;
1066 }
1067 /* }}} */
1068
1069 /* {{{ proto int ftp_nb_fput(resource stream, string remote_file, resource fp, int mode[, int startpos])
1070 Stores a file from an open file to the FTP server nbronly */
PHP_FUNCTION(ftp_nb_fput)1071 PHP_FUNCTION(ftp_nb_fput)
1072 {
1073 zval *z_ftp, *z_file;
1074 ftpbuf_t *ftp;
1075 ftptype_t xtype;
1076 int remote_len, ret;
1077 long mode, startpos=0;
1078 php_stream *stream;
1079 char *remote;
1080
1081 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsrl|l", &z_ftp, &remote, &remote_len, &z_file, &mode, &startpos) == FAILURE) {
1082 return;
1083 }
1084
1085 ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
1086 php_stream_from_zval(stream, &z_file);
1087 XTYPE(xtype, mode);
1088
1089 /* ignore autoresume if autoseek is switched off */
1090 if (!ftp->autoseek && startpos == PHP_FTP_AUTORESUME) {
1091 startpos = 0;
1092 }
1093
1094 if (ftp->autoseek && startpos) {
1095 /* if autoresume is wanted ask for remote size */
1096 if (startpos == PHP_FTP_AUTORESUME) {
1097 startpos = ftp_size(ftp, remote);
1098 if (startpos < 0) {
1099 startpos = 0;
1100 }
1101 }
1102 if (startpos) {
1103 php_stream_seek(stream, startpos, SEEK_SET);
1104 }
1105 }
1106
1107 /* configuration */
1108 ftp->direction = 1; /* send */
1109 ftp->closestream = 0; /* do not close */
1110
1111 if (((ret = ftp_nb_put(ftp, remote, stream, xtype, startpos TSRMLS_CC)) == PHP_FTP_FAILED)) {
1112 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ftp->inbuf);
1113 RETURN_LONG(ret);
1114 }
1115
1116 RETURN_LONG(ret);
1117 }
1118 /* }}} */
1119
1120
1121 /* {{{ proto bool ftp_put(resource stream, string remote_file, string local_file, int mode[, int startpos])
1122 Stores a file on the FTP server */
PHP_FUNCTION(ftp_put)1123 PHP_FUNCTION(ftp_put)
1124 {
1125 zval *z_ftp;
1126 ftpbuf_t *ftp;
1127 ftptype_t xtype;
1128 char *remote, *local;
1129 long remote_len, local_len;
1130 long mode, startpos=0;
1131 php_stream *instream;
1132
1133 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rppl|l", &z_ftp, &remote, &remote_len, &local, &local_len, &mode, &startpos) == FAILURE) {
1134 return;
1135 }
1136
1137 ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
1138 XTYPE(xtype, mode);
1139
1140 if (!(instream = php_stream_open_wrapper(local, mode == FTPTYPE_ASCII ? "rt" : "rb", REPORT_ERRORS, NULL))) {
1141 RETURN_FALSE;
1142 }
1143
1144 /* ignore autoresume if autoseek is switched off */
1145 if (!ftp->autoseek && startpos == PHP_FTP_AUTORESUME) {
1146 startpos = 0;
1147 }
1148
1149 if (ftp->autoseek && startpos) {
1150 /* if autoresume is wanted ask for remote size */
1151 if (startpos == PHP_FTP_AUTORESUME) {
1152 startpos = ftp_size(ftp, remote);
1153 if (startpos < 0) {
1154 startpos = 0;
1155 }
1156 }
1157 if (startpos) {
1158 php_stream_seek(instream, startpos, SEEK_SET);
1159 }
1160 }
1161
1162 if (!ftp_put(ftp, remote, instream, xtype, startpos TSRMLS_CC)) {
1163 php_stream_close(instream);
1164 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ftp->inbuf);
1165 RETURN_FALSE;
1166 }
1167 php_stream_close(instream);
1168
1169 RETURN_TRUE;
1170 }
1171 /* }}} */
1172
1173
1174 /* {{{ proto int ftp_nb_put(resource stream, string remote_file, string local_file, int mode[, int startpos])
1175 Stores a file on the FTP server */
PHP_FUNCTION(ftp_nb_put)1176 PHP_FUNCTION(ftp_nb_put)
1177 {
1178 zval *z_ftp;
1179 ftpbuf_t *ftp;
1180 ftptype_t xtype;
1181 char *remote, *local;
1182 int remote_len, local_len;
1183 long mode, startpos=0, ret;
1184 php_stream *instream;
1185
1186 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rppl|l", &z_ftp, &remote, &remote_len, &local, &local_len, &mode, &startpos) == FAILURE) {
1187 return;
1188 }
1189
1190 ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
1191 XTYPE(xtype, mode);
1192
1193 if (!(instream = php_stream_open_wrapper(local, mode == FTPTYPE_ASCII ? "rt" : "rb", REPORT_ERRORS, NULL))) {
1194 RETURN_FALSE;
1195 }
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);
1206 if (startpos < 0) {
1207 startpos = 0;
1208 }
1209 }
1210 if (startpos) {
1211 php_stream_seek(instream, startpos, SEEK_SET);
1212 }
1213 }
1214
1215 /* configuration */
1216 ftp->direction = 1; /* send */
1217 ftp->closestream = 1; /* do close */
1218
1219 ret = ftp_nb_put(ftp, remote, instream, xtype, startpos TSRMLS_CC);
1220
1221 if (ret != PHP_FTP_MOREDATA) {
1222 php_stream_close(instream);
1223 ftp->stream = NULL;
1224 }
1225
1226 if (ret == PHP_FTP_FAILED) {
1227 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ftp->inbuf);
1228 }
1229
1230 RETURN_LONG(ret);
1231 }
1232 /* }}} */
1233
1234 /* {{{ proto int ftp_size(resource stream, string filename)
1235 Returns the size of the file, or -1 on error */
PHP_FUNCTION(ftp_size)1236 PHP_FUNCTION(ftp_size)
1237 {
1238 zval *z_ftp;
1239 ftpbuf_t *ftp;
1240 char *file;
1241 int file_len;
1242
1243 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rp", &z_ftp, &file, &file_len) == FAILURE) {
1244 return;
1245 }
1246
1247 ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
1248
1249 /* get file size */
1250 RETURN_LONG(ftp_size(ftp, file));
1251 }
1252 /* }}} */
1253
1254 /* {{{ proto int ftp_mdtm(resource stream, string filename)
1255 Returns the last modification time of the file, or -1 on error */
PHP_FUNCTION(ftp_mdtm)1256 PHP_FUNCTION(ftp_mdtm)
1257 {
1258 zval *z_ftp;
1259 ftpbuf_t *ftp;
1260 char *file;
1261 int file_len;
1262
1263 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rp", &z_ftp, &file, &file_len) == FAILURE) {
1264 return;
1265 }
1266
1267 ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
1268
1269 /* get file mod time */
1270 RETURN_LONG(ftp_mdtm(ftp, file));
1271 }
1272 /* }}} */
1273
1274 /* {{{ proto bool ftp_rename(resource stream, string src, string dest)
1275 Renames the given file to a new path */
PHP_FUNCTION(ftp_rename)1276 PHP_FUNCTION(ftp_rename)
1277 {
1278 zval *z_ftp;
1279 ftpbuf_t *ftp;
1280 char *src, *dest;
1281 int src_len, dest_len;
1282
1283 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rss", &z_ftp, &src, &src_len, &dest, &dest_len) == FAILURE) {
1284 return;
1285 }
1286
1287 ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
1288
1289 /* rename the file */
1290 if (!ftp_rename(ftp, src, dest)) {
1291 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ftp->inbuf);
1292 RETURN_FALSE;
1293 }
1294
1295 RETURN_TRUE;
1296 }
1297 /* }}} */
1298
1299 /* {{{ proto bool ftp_delete(resource stream, string file)
1300 Deletes a file */
PHP_FUNCTION(ftp_delete)1301 PHP_FUNCTION(ftp_delete)
1302 {
1303 zval *z_ftp;
1304 ftpbuf_t *ftp;
1305 char *file;
1306 int file_len;
1307
1308 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &z_ftp, &file, &file_len) == FAILURE) {
1309 return;
1310 }
1311
1312 ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
1313
1314 /* delete the file */
1315 if (!ftp_delete(ftp, file)) {
1316 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ftp->inbuf);
1317 RETURN_FALSE;
1318 }
1319
1320 RETURN_TRUE;
1321 }
1322 /* }}} */
1323
1324 /* {{{ proto bool ftp_site(resource stream, string cmd)
1325 Sends a SITE command to the server */
PHP_FUNCTION(ftp_site)1326 PHP_FUNCTION(ftp_site)
1327 {
1328 zval *z_ftp;
1329 ftpbuf_t *ftp;
1330 char *cmd;
1331 int cmd_len;
1332
1333 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &z_ftp, &cmd, &cmd_len) == FAILURE) {
1334 return;
1335 }
1336
1337 ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
1338
1339 /* send the site command */
1340 if (!ftp_site(ftp, cmd)) {
1341 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ftp->inbuf);
1342 RETURN_FALSE;
1343 }
1344
1345 RETURN_TRUE;
1346 }
1347 /* }}} */
1348
1349 /* {{{ proto bool ftp_close(resource stream)
1350 Closes the FTP stream */
PHP_FUNCTION(ftp_close)1351 PHP_FUNCTION(ftp_close)
1352 {
1353 zval *z_ftp;
1354 ftpbuf_t *ftp;
1355
1356 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &z_ftp) == FAILURE) {
1357 return;
1358 }
1359
1360 ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
1361
1362 ftp_quit(ftp);
1363
1364 RETURN_BOOL(zend_list_delete(Z_LVAL_P(z_ftp)) == SUCCESS);
1365 }
1366 /* }}} */
1367
1368 /* {{{ proto bool ftp_set_option(resource stream, int option, mixed value)
1369 Sets an FTP option */
PHP_FUNCTION(ftp_set_option)1370 PHP_FUNCTION(ftp_set_option)
1371 {
1372 zval *z_ftp, *z_value;
1373 long option;
1374 ftpbuf_t *ftp;
1375
1376 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rlz", &z_ftp, &option, &z_value) == FAILURE) {
1377 return;
1378 }
1379
1380 ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
1381
1382 switch (option) {
1383 case PHP_FTP_OPT_TIMEOUT_SEC:
1384 if (Z_TYPE_P(z_value) != IS_LONG) {
1385 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Option TIMEOUT_SEC expects value of type long, %s given",
1386 zend_zval_type_name(z_value));
1387 RETURN_FALSE;
1388 }
1389 if (Z_LVAL_P(z_value) <= 0) {
1390 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Timeout has to be greater than 0");
1391 RETURN_FALSE;
1392 }
1393 ftp->timeout_sec = Z_LVAL_P(z_value);
1394 RETURN_TRUE;
1395 break;
1396 case PHP_FTP_OPT_AUTOSEEK:
1397 if (Z_TYPE_P(z_value) != IS_BOOL) {
1398 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Option AUTOSEEK expects value of type boolean, %s given",
1399 zend_zval_type_name(z_value));
1400 RETURN_FALSE;
1401 }
1402 ftp->autoseek = Z_LVAL_P(z_value);
1403 RETURN_TRUE;
1404 break;
1405 case PHP_FTP_OPT_USEPASVADDRESS:
1406 if (Z_TYPE_P(z_value) != IS_BOOL) {
1407 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Option USEPASVADDRESS expects value of type boolean, %s given",
1408 zend_zval_type_name(z_value));
1409 RETURN_FALSE;
1410 }
1411 ftp->usepasvaddress = Z_LVAL_P(z_value);
1412 RETURN_TRUE;
1413 break;
1414 default:
1415 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown option '%ld'", option);
1416 RETURN_FALSE;
1417 break;
1418 }
1419 }
1420 /* }}} */
1421
1422 /* {{{ proto mixed ftp_get_option(resource stream, int option)
1423 Gets an FTP option */
PHP_FUNCTION(ftp_get_option)1424 PHP_FUNCTION(ftp_get_option)
1425 {
1426 zval *z_ftp;
1427 long option;
1428 ftpbuf_t *ftp;
1429
1430 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &z_ftp, &option) == FAILURE) {
1431 return;
1432 }
1433
1434 ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
1435
1436 switch (option) {
1437 case PHP_FTP_OPT_TIMEOUT_SEC:
1438 RETURN_LONG(ftp->timeout_sec);
1439 break;
1440 case PHP_FTP_OPT_AUTOSEEK:
1441 RETURN_BOOL(ftp->autoseek);
1442 break;
1443 case PHP_FTP_OPT_USEPASVADDRESS:
1444 RETURN_BOOL(ftp->usepasvaddress);
1445 break;
1446 default:
1447 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown option '%ld'", option);
1448 RETURN_FALSE;
1449 break;
1450 }
1451 }
1452 /* }}} */
1453
1454 #endif /* HAVE_FTP */
1455
1456 /*
1457 * Local variables:
1458 * tab-width: 4
1459 * c-basic-offset: 4
1460 * indent-tabs-mode: t
1461 * End:
1462 */
1463