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