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