Back to index

php5  5.3.10
php_ftp.c
Go to the documentation of this file.
00001 /*
00002    +----------------------------------------------------------------------+
00003    | PHP Version 5                                                        |
00004    +----------------------------------------------------------------------+
00005    | Copyright (c) 1997-2012 The PHP Group                                |
00006    +----------------------------------------------------------------------+
00007    | This source file is subject to version 3.01 of the PHP license,      |
00008    | that is bundled with this package in the file LICENSE, and is        |
00009    | available through the world-wide-web at the following url:           |
00010    | http://www.php.net/license/3_01.txt                                  |
00011    | If you did not receive a copy of the PHP license and are unable to   |
00012    | obtain it through the world-wide-web, please send a note to          |
00013    | license@php.net so we can mail you a copy immediately.               |
00014    +----------------------------------------------------------------------+
00015    | Authors: Andrew Skalski <askalski@chek.com>                          |
00016    |          Stefan Esser <sesser@php.net> (resume functions)            |
00017    +----------------------------------------------------------------------+
00018  */
00019 
00020 /* $Id: php_ftp.c 321634 2012-01-01 13:15:04Z felipe $ */
00021 
00022 #ifdef HAVE_CONFIG_H
00023 #include "config.h"
00024 #endif
00025 
00026 #include "php.h"
00027 
00028 #if defined(NETWARE) && defined(USE_WINSOCK)
00029 #include <novsock2.h>
00030 #endif
00031 
00032 #if HAVE_OPENSSL_EXT
00033 # include <openssl/ssl.h>
00034 #endif
00035 
00036 #if HAVE_FTP
00037 
00038 #include "ext/standard/info.h"
00039 #include "ext/standard/file.h"
00040 
00041 #include "php_ftp.h"
00042 #include "ftp.h"
00043 
00044 static int    le_ftpbuf;
00045 #define le_ftpbuf_name "FTP Buffer"
00046 
00047 /* {{{ arginfo */
00048 ZEND_BEGIN_ARG_INFO_EX(arginfo_ftp_connect, 0, 0, 1)
00049        ZEND_ARG_INFO(0, host)
00050        ZEND_ARG_INFO(0, port)
00051        ZEND_ARG_INFO(0, timeout)
00052 ZEND_END_ARG_INFO()
00053 
00054 #if HAVE_OPENSSL_EXT
00055 ZEND_BEGIN_ARG_INFO_EX(arginfo_ftp_ssl_connect, 0, 0, 1)
00056        ZEND_ARG_INFO(0, host)
00057        ZEND_ARG_INFO(0, port)
00058        ZEND_ARG_INFO(0, timeout)
00059 ZEND_END_ARG_INFO()
00060 #endif
00061 
00062 ZEND_BEGIN_ARG_INFO(arginfo_ftp_login, 0)
00063        ZEND_ARG_INFO(0, ftp)
00064        ZEND_ARG_INFO(0, username)
00065        ZEND_ARG_INFO(0, password)
00066 ZEND_END_ARG_INFO()
00067 
00068 ZEND_BEGIN_ARG_INFO(arginfo_ftp_pwd, 0)
00069        ZEND_ARG_INFO(0, ftp)
00070 ZEND_END_ARG_INFO()
00071 
00072 ZEND_BEGIN_ARG_INFO(arginfo_ftp_cdup, 0)
00073        ZEND_ARG_INFO(0, ftp)
00074 ZEND_END_ARG_INFO()
00075 
00076 ZEND_BEGIN_ARG_INFO(arginfo_ftp_chdir, 0)
00077        ZEND_ARG_INFO(0, ftp)
00078        ZEND_ARG_INFO(0, directory)
00079 ZEND_END_ARG_INFO()
00080 
00081 ZEND_BEGIN_ARG_INFO(arginfo_ftp_exec, 0)
00082        ZEND_ARG_INFO(0, ftp)
00083        ZEND_ARG_INFO(0, command)
00084 ZEND_END_ARG_INFO()
00085 
00086 ZEND_BEGIN_ARG_INFO(arginfo_ftp_raw, 0)
00087        ZEND_ARG_INFO(0, ftp)
00088        ZEND_ARG_INFO(0, command)
00089 ZEND_END_ARG_INFO()
00090 
00091 ZEND_BEGIN_ARG_INFO(arginfo_ftp_mkdir, 0)
00092        ZEND_ARG_INFO(0, ftp)
00093        ZEND_ARG_INFO(0, directory)
00094 ZEND_END_ARG_INFO()
00095 
00096 ZEND_BEGIN_ARG_INFO(arginfo_ftp_rmdir, 0)
00097        ZEND_ARG_INFO(0, ftp)
00098        ZEND_ARG_INFO(0, directory)
00099 ZEND_END_ARG_INFO()
00100 
00101 ZEND_BEGIN_ARG_INFO(arginfo_ftp_chmod, 0)
00102        ZEND_ARG_INFO(0, ftp)
00103        ZEND_ARG_INFO(0, mode)
00104        ZEND_ARG_INFO(0, filename)
00105 ZEND_END_ARG_INFO()
00106 
00107 ZEND_BEGIN_ARG_INFO_EX(arginfo_ftp_alloc, 0, 0, 2)
00108        ZEND_ARG_INFO(0, ftp)
00109        ZEND_ARG_INFO(0, size)
00110        ZEND_ARG_INFO(1, response)
00111 ZEND_END_ARG_INFO()
00112 
00113 ZEND_BEGIN_ARG_INFO(arginfo_ftp_nlist, 0)
00114        ZEND_ARG_INFO(0, ftp)
00115        ZEND_ARG_INFO(0, directory)
00116 ZEND_END_ARG_INFO()
00117 
00118 ZEND_BEGIN_ARG_INFO_EX(arginfo_ftp_rawlist, 0, 0, 2)
00119        ZEND_ARG_INFO(0, ftp)
00120        ZEND_ARG_INFO(0, directory)
00121        ZEND_ARG_INFO(0, recursive)
00122 ZEND_END_ARG_INFO()
00123 
00124 ZEND_BEGIN_ARG_INFO(arginfo_ftp_systype, 0)
00125        ZEND_ARG_INFO(0, ftp)
00126 ZEND_END_ARG_INFO()
00127 
00128 ZEND_BEGIN_ARG_INFO_EX(arginfo_ftp_fget, 0, 0, 4)
00129        ZEND_ARG_INFO(0, ftp)
00130        ZEND_ARG_INFO(0, fp)
00131        ZEND_ARG_INFO(0, remote_file)
00132        ZEND_ARG_INFO(0, mode)
00133        ZEND_ARG_INFO(0, resumepos)
00134 ZEND_END_ARG_INFO()
00135 
00136 ZEND_BEGIN_ARG_INFO_EX(arginfo_ftp_nb_fget, 0, 0, 4)
00137        ZEND_ARG_INFO(0, ftp)
00138        ZEND_ARG_INFO(0, fp)
00139        ZEND_ARG_INFO(0, remote_file)
00140        ZEND_ARG_INFO(0, mode)
00141        ZEND_ARG_INFO(0, resumepos)
00142 ZEND_END_ARG_INFO()
00143 
00144 ZEND_BEGIN_ARG_INFO(arginfo_ftp_pasv, 0)
00145        ZEND_ARG_INFO(0, ftp)
00146        ZEND_ARG_INFO(0, pasv)
00147 ZEND_END_ARG_INFO()
00148 
00149 ZEND_BEGIN_ARG_INFO_EX(arginfo_ftp_get, 0, 0, 4)
00150        ZEND_ARG_INFO(0, ftp)
00151        ZEND_ARG_INFO(0, local_file)
00152        ZEND_ARG_INFO(0, remote_file)
00153        ZEND_ARG_INFO(0, mode)
00154        ZEND_ARG_INFO(0, resume_pos)
00155 ZEND_END_ARG_INFO()
00156 
00157 ZEND_BEGIN_ARG_INFO_EX(arginfo_ftp_nb_get, 0, 0, 4)
00158        ZEND_ARG_INFO(0, ftp)
00159        ZEND_ARG_INFO(0, local_file)
00160        ZEND_ARG_INFO(0, remote_file)
00161        ZEND_ARG_INFO(0, mode)
00162        ZEND_ARG_INFO(0, resume_pos)
00163 ZEND_END_ARG_INFO()
00164 
00165 ZEND_BEGIN_ARG_INFO(arginfo_ftp_nb_continue, 0)
00166        ZEND_ARG_INFO(0, ftp)
00167 ZEND_END_ARG_INFO()
00168 
00169 ZEND_BEGIN_ARG_INFO_EX(arginfo_ftp_fput, 0, 0, 4)
00170        ZEND_ARG_INFO(0, ftp)
00171        ZEND_ARG_INFO(0, remote_file)
00172        ZEND_ARG_INFO(0, fp)
00173        ZEND_ARG_INFO(0, mode)
00174        ZEND_ARG_INFO(0, startpos)
00175 ZEND_END_ARG_INFO()
00176 
00177 ZEND_BEGIN_ARG_INFO_EX(arginfo_ftp_nb_fput, 0, 0, 4)
00178        ZEND_ARG_INFO(0, ftp)
00179        ZEND_ARG_INFO(0, remote_file)
00180        ZEND_ARG_INFO(0, fp)
00181        ZEND_ARG_INFO(0, mode)
00182        ZEND_ARG_INFO(0, startpos)
00183 ZEND_END_ARG_INFO()
00184 
00185 ZEND_BEGIN_ARG_INFO_EX(arginfo_ftp_put, 0, 0, 4)
00186        ZEND_ARG_INFO(0, ftp)
00187        ZEND_ARG_INFO(0, remote_file)
00188        ZEND_ARG_INFO(0, local_file)
00189        ZEND_ARG_INFO(0, mode)
00190        ZEND_ARG_INFO(0, startpos)
00191 ZEND_END_ARG_INFO()
00192 
00193 ZEND_BEGIN_ARG_INFO_EX(arginfo_ftp_nb_put, 0, 0, 4)
00194        ZEND_ARG_INFO(0, ftp)
00195        ZEND_ARG_INFO(0, remote_file)
00196        ZEND_ARG_INFO(0, local_file)
00197        ZEND_ARG_INFO(0, mode)
00198        ZEND_ARG_INFO(0, startpos)
00199 ZEND_END_ARG_INFO()
00200 
00201 ZEND_BEGIN_ARG_INFO(arginfo_ftp_size, 0)
00202        ZEND_ARG_INFO(0, ftp)
00203        ZEND_ARG_INFO(0, filename)
00204 ZEND_END_ARG_INFO()
00205 
00206 ZEND_BEGIN_ARG_INFO(arginfo_ftp_mdtm, 0)
00207        ZEND_ARG_INFO(0, ftp)
00208        ZEND_ARG_INFO(0, filename)
00209 ZEND_END_ARG_INFO()
00210 
00211 ZEND_BEGIN_ARG_INFO(arginfo_ftp_rename, 0)
00212        ZEND_ARG_INFO(0, ftp)
00213        ZEND_ARG_INFO(0, src)
00214        ZEND_ARG_INFO(0, dest)
00215 ZEND_END_ARG_INFO()
00216 
00217 ZEND_BEGIN_ARG_INFO(arginfo_ftp_delete, 0)
00218        ZEND_ARG_INFO(0, ftp)
00219        ZEND_ARG_INFO(0, file)
00220 ZEND_END_ARG_INFO()
00221 
00222 ZEND_BEGIN_ARG_INFO(arginfo_ftp_site, 0)
00223        ZEND_ARG_INFO(0, ftp)
00224        ZEND_ARG_INFO(0, cmd)
00225 ZEND_END_ARG_INFO()
00226 
00227 ZEND_BEGIN_ARG_INFO(arginfo_ftp_close, 0)
00228        ZEND_ARG_INFO(0, ftp)
00229 ZEND_END_ARG_INFO()
00230 
00231 ZEND_BEGIN_ARG_INFO(arginfo_ftp_set_option, 0)
00232        ZEND_ARG_INFO(0, ftp)
00233        ZEND_ARG_INFO(0, option)
00234        ZEND_ARG_INFO(0, value)
00235 ZEND_END_ARG_INFO()
00236 
00237 ZEND_BEGIN_ARG_INFO(arginfo_ftp_get_option, 0)
00238        ZEND_ARG_INFO(0, ftp)
00239        ZEND_ARG_INFO(0, option)
00240 ZEND_END_ARG_INFO()
00241 
00242 /* }}} */
00243 
00244 const zend_function_entry php_ftp_functions[] = {
00245        PHP_FE(ftp_connect,                arginfo_ftp_connect)
00246 #if HAVE_OPENSSL_EXT
00247        PHP_FE(ftp_ssl_connect,            arginfo_ftp_ssl_connect)
00248 #endif 
00249        PHP_FE(ftp_login,                  arginfo_ftp_login)
00250        PHP_FE(ftp_pwd,                           arginfo_ftp_pwd)
00251        PHP_FE(ftp_cdup,                   arginfo_ftp_cdup)
00252        PHP_FE(ftp_chdir,                  arginfo_ftp_chdir)
00253        PHP_FE(ftp_exec,                   arginfo_ftp_exec)
00254        PHP_FE(ftp_raw,                           arginfo_ftp_raw)
00255        PHP_FE(ftp_mkdir,                  arginfo_ftp_mkdir)
00256        PHP_FE(ftp_rmdir,                  arginfo_ftp_rmdir)
00257        PHP_FE(ftp_chmod,                  arginfo_ftp_chmod)
00258        PHP_FE(ftp_alloc,                  arginfo_ftp_alloc)
00259        PHP_FE(ftp_nlist,                  arginfo_ftp_nlist)
00260        PHP_FE(ftp_rawlist,                arginfo_ftp_rawlist)
00261        PHP_FE(ftp_systype,                arginfo_ftp_systype)
00262        PHP_FE(ftp_pasv,                   arginfo_ftp_pasv)
00263        PHP_FE(ftp_get,                           arginfo_ftp_get)
00264        PHP_FE(ftp_fget,                   arginfo_ftp_fget)
00265        PHP_FE(ftp_put,                           arginfo_ftp_put)
00266        PHP_FE(ftp_fput,                   arginfo_ftp_fput)
00267        PHP_FE(ftp_size,                   arginfo_ftp_size)
00268        PHP_FE(ftp_mdtm,                   arginfo_ftp_mdtm)
00269        PHP_FE(ftp_rename,                 arginfo_ftp_rename)
00270        PHP_FE(ftp_delete,                 arginfo_ftp_delete)
00271        PHP_FE(ftp_site,                   arginfo_ftp_site)
00272        PHP_FE(ftp_close,                  arginfo_ftp_close)
00273        PHP_FE(ftp_set_option,             arginfo_ftp_set_option)
00274        PHP_FE(ftp_get_option,             arginfo_ftp_get_option)
00275        PHP_FE(ftp_nb_fget,                arginfo_ftp_nb_fget)
00276        PHP_FE(ftp_nb_get,                 arginfo_ftp_nb_get)
00277        PHP_FE(ftp_nb_continue,            arginfo_ftp_nb_continue)
00278        PHP_FE(ftp_nb_put,                 arginfo_ftp_nb_put)
00279        PHP_FE(ftp_nb_fput,                arginfo_ftp_nb_fput)
00280        PHP_FALIAS(ftp_quit, ftp_close, arginfo_ftp_close)
00281        PHP_FE_END
00282 };
00283 
00284 zend_module_entry php_ftp_module_entry = {
00285     STANDARD_MODULE_HEADER,
00286        "ftp",
00287        php_ftp_functions,
00288        PHP_MINIT(ftp),
00289        NULL,
00290        NULL,
00291        NULL,
00292        PHP_MINFO(ftp),
00293     NO_VERSION_YET,
00294        STANDARD_MODULE_PROPERTIES
00295 };
00296 
00297 #if COMPILE_DL_FTP
00298 ZEND_GET_MODULE(php_ftp)
00299 #endif
00300 
00301 static void ftp_destructor_ftpbuf(zend_rsrc_list_entry *rsrc TSRMLS_DC)
00302 {
00303        ftpbuf_t *ftp = (ftpbuf_t *)rsrc->ptr;
00304 
00305        ftp_close(ftp);
00306 }
00307 
00308 PHP_MINIT_FUNCTION(ftp)
00309 {
00310        le_ftpbuf = zend_register_list_destructors_ex(ftp_destructor_ftpbuf, NULL, le_ftpbuf_name, module_number);
00311        REGISTER_LONG_CONSTANT("FTP_ASCII",  FTPTYPE_ASCII, CONST_PERSISTENT | CONST_CS);
00312        REGISTER_LONG_CONSTANT("FTP_TEXT",   FTPTYPE_ASCII, CONST_PERSISTENT | CONST_CS);
00313        REGISTER_LONG_CONSTANT("FTP_BINARY", FTPTYPE_IMAGE, CONST_PERSISTENT | CONST_CS);
00314        REGISTER_LONG_CONSTANT("FTP_IMAGE",  FTPTYPE_IMAGE, CONST_PERSISTENT | CONST_CS);
00315        REGISTER_LONG_CONSTANT("FTP_AUTORESUME", PHP_FTP_AUTORESUME, CONST_PERSISTENT | CONST_CS);
00316        REGISTER_LONG_CONSTANT("FTP_TIMEOUT_SEC", PHP_FTP_OPT_TIMEOUT_SEC, CONST_PERSISTENT | CONST_CS);
00317        REGISTER_LONG_CONSTANT("FTP_AUTOSEEK", PHP_FTP_OPT_AUTOSEEK, CONST_PERSISTENT | CONST_CS);
00318        REGISTER_LONG_CONSTANT("FTP_FAILED", PHP_FTP_FAILED, CONST_PERSISTENT | CONST_CS);
00319        REGISTER_LONG_CONSTANT("FTP_FINISHED", PHP_FTP_FINISHED, CONST_PERSISTENT | CONST_CS);
00320        REGISTER_LONG_CONSTANT("FTP_MOREDATA", PHP_FTP_MOREDATA, CONST_PERSISTENT | CONST_CS);
00321        return SUCCESS;
00322 }
00323 
00324 PHP_MINFO_FUNCTION(ftp)
00325 {
00326        php_info_print_table_start();
00327        php_info_print_table_row(2, "FTP support", "enabled");
00328        php_info_print_table_end();
00329 }
00330 
00331 #define       XTYPE(xtype, mode)   { \
00332                                                         if (mode != FTPTYPE_ASCII && mode != FTPTYPE_IMAGE) { \
00333                                                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Mode must be FTP_ASCII or FTP_BINARY"); \
00334                                                                RETURN_FALSE; \
00335                                                         } \
00336                                                         xtype = mode; \
00337                                                  }
00338 
00339 
00340 /* {{{ proto resource ftp_connect(string host [, int port [, int timeout]])
00341    Opens a FTP stream */
00342 PHP_FUNCTION(ftp_connect)
00343 {
00344        ftpbuf_t      *ftp;
00345        char          *host;
00346        int           host_len;
00347        long          port = 0;
00348        long          timeout_sec = FTP_DEFAULT_TIMEOUT;
00349 
00350        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ll", &host, &host_len, &port, &timeout_sec) == FAILURE) {
00351               return;
00352        }
00353 
00354        if (timeout_sec <= 0) {
00355               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Timeout has to be greater than 0");
00356               RETURN_FALSE;
00357        }
00358 
00359        /* connect */
00360        if (!(ftp = ftp_open(host, (short)port, timeout_sec TSRMLS_CC))) {
00361               RETURN_FALSE;
00362        }
00363 
00364        /* autoseek for resuming */
00365        ftp->autoseek = FTP_DEFAULT_AUTOSEEK;
00366 #if HAVE_OPENSSL_EXT
00367        /* disable ssl */
00368        ftp->use_ssl = 0;
00369 #endif
00370 
00371        ZEND_REGISTER_RESOURCE(return_value, ftp, le_ftpbuf);
00372 }
00373 /* }}} */
00374 
00375 #if HAVE_OPENSSL_EXT
00376 /* {{{ proto resource ftp_ssl_connect(string host [, int port [, int timeout]])
00377    Opens a FTP-SSL stream */
00378 PHP_FUNCTION(ftp_ssl_connect)
00379 {
00380        ftpbuf_t      *ftp;
00381        char          *host;
00382        int           host_len;
00383        long          port = 0;
00384        long          timeout_sec = FTP_DEFAULT_TIMEOUT;
00385 
00386        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ll", &host, &host_len, &port, &timeout_sec) == FAILURE) {
00387               return;
00388        }
00389 
00390        if (timeout_sec <= 0) {
00391               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Timeout has to be greater than 0");
00392               RETURN_FALSE;
00393        }
00394 
00395        /* connect */
00396        if (!(ftp = ftp_open(host, (short)port, timeout_sec TSRMLS_CC))) {
00397               RETURN_FALSE;
00398        }
00399 
00400        /* autoseek for resuming */
00401        ftp->autoseek = FTP_DEFAULT_AUTOSEEK;
00402        /* enable ssl */
00403        ftp->use_ssl = 1;
00404 
00405        ZEND_REGISTER_RESOURCE(return_value, ftp, le_ftpbuf);
00406 }
00407 /* }}} */
00408 #endif
00409 
00410 /* {{{ proto bool ftp_login(resource stream, string username, string password)
00411    Logs into the FTP server */
00412 PHP_FUNCTION(ftp_login)
00413 {
00414        zval          *z_ftp;
00415        ftpbuf_t      *ftp;
00416        char *user, *pass;
00417        int user_len, pass_len;
00418 
00419        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rss", &z_ftp, &user, &user_len, &pass, &pass_len) == FAILURE) {
00420               return;
00421        }
00422 
00423        ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
00424 
00425        /* log in */
00426        if (!ftp_login(ftp, user, pass TSRMLS_CC)) {
00427               php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ftp->inbuf);
00428               RETURN_FALSE;
00429        }
00430 
00431        RETURN_TRUE;
00432 }
00433 /* }}} */
00434 
00435 /* {{{ proto string ftp_pwd(resource stream)
00436    Returns the present working directory */
00437 PHP_FUNCTION(ftp_pwd)
00438 {
00439        zval          *z_ftp;
00440        ftpbuf_t      *ftp;
00441        const char    *pwd;
00442 
00443        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &z_ftp) == FAILURE) {
00444               return;
00445        }
00446 
00447        ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
00448 
00449        if (!(pwd = ftp_pwd(ftp))) {
00450               php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ftp->inbuf);
00451               RETURN_FALSE;
00452        }
00453 
00454        RETURN_STRING((char*) pwd, 1);
00455 }
00456 /* }}} */
00457 
00458 /* {{{ proto bool ftp_cdup(resource stream)
00459    Changes to the parent directory */
00460 PHP_FUNCTION(ftp_cdup)
00461 {
00462        zval          *z_ftp;
00463        ftpbuf_t      *ftp;
00464 
00465        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &z_ftp) == FAILURE) {
00466               return;
00467        }
00468 
00469        ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
00470 
00471        if (!ftp_cdup(ftp)) {
00472               php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ftp->inbuf);
00473               RETURN_FALSE;
00474        }
00475 
00476        RETURN_TRUE;
00477 }
00478 /* }}} */
00479 
00480 /* {{{ proto bool ftp_chdir(resource stream, string directory)
00481    Changes directories */
00482 PHP_FUNCTION(ftp_chdir)
00483 {
00484        zval          *z_ftp;
00485        ftpbuf_t      *ftp;
00486        char          *dir;
00487        int                  dir_len;
00488 
00489        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &z_ftp, &dir, &dir_len) == FAILURE) {
00490               return;
00491        }
00492 
00493        ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
00494 
00495        /* change directories */
00496        if (!ftp_chdir(ftp, dir)) {
00497               php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ftp->inbuf);
00498               RETURN_FALSE;
00499        }
00500 
00501        RETURN_TRUE;
00502 }
00503 /* }}} */
00504 
00505 /* {{{ proto bool ftp_exec(resource stream, string command)
00506    Requests execution of a program on the FTP server */
00507 PHP_FUNCTION(ftp_exec)
00508 {
00509        zval          *z_ftp;
00510        ftpbuf_t      *ftp;
00511        char          *cmd;
00512        int                  cmd_len;
00513 
00514        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &z_ftp, &cmd, &cmd_len) == FAILURE) {
00515               return;
00516        }
00517 
00518        ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
00519 
00520        /* execute serverside command */
00521        if (!ftp_exec(ftp, cmd)) {
00522               php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ftp->inbuf);
00523               RETURN_FALSE;
00524        }
00525 
00526        RETURN_TRUE;
00527 }
00528 /* }}} */
00529 
00530 /* {{{ proto array ftp_raw(resource stream, string command)
00531    Sends a literal command to the FTP server */
00532 PHP_FUNCTION(ftp_raw)
00533 {
00534        zval          *z_ftp;
00535        ftpbuf_t      *ftp;
00536        char          *cmd;
00537        int                  cmd_len;
00538 
00539        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &z_ftp, &cmd, &cmd_len) == FAILURE) {
00540               return;
00541        }
00542 
00543        ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
00544 
00545        /* execute arbitrary ftp command */
00546        ftp_raw(ftp, cmd, return_value);
00547 }
00548 /* }}} */
00549 
00550 /* {{{ proto string ftp_mkdir(resource stream, string directory)
00551    Creates a directory and returns the absolute path for the new directory or false on error */
00552 PHP_FUNCTION(ftp_mkdir)
00553 {
00554        zval          *z_ftp;
00555        ftpbuf_t      *ftp;
00556        char          *dir, *tmp;
00557        int           dir_len;
00558 
00559        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &z_ftp, &dir, &dir_len) == FAILURE) {
00560               return;
00561        }
00562 
00563        ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
00564 
00565        /* create directorie */
00566        if (NULL == (tmp = ftp_mkdir(ftp, dir))) {
00567               php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ftp->inbuf);
00568               RETURN_FALSE;
00569        }
00570 
00571        RETURN_STRING(tmp, 0);
00572 }
00573 /* }}} */
00574 
00575 /* {{{ proto bool ftp_rmdir(resource stream, string directory)
00576    Removes a directory */
00577 PHP_FUNCTION(ftp_rmdir)
00578 {
00579        zval          *z_ftp;
00580        ftpbuf_t      *ftp;
00581        char          *dir;
00582        int           dir_len;
00583 
00584        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &z_ftp, &dir, &dir_len) == FAILURE) {
00585               return;
00586        }
00587 
00588        ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
00589 
00590        /* remove directorie */
00591        if (!ftp_rmdir(ftp, dir)) {
00592               php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ftp->inbuf);
00593               RETURN_FALSE;
00594        }
00595 
00596        RETURN_TRUE;
00597 }
00598 /* }}} */
00599 
00600 /* {{{ proto int ftp_chmod(resource stream, int mode, string filename)
00601    Sets permissions on a file */
00602 PHP_FUNCTION(ftp_chmod)
00603 {
00604        zval          *z_ftp;
00605        ftpbuf_t      *ftp;
00606        char          *filename;
00607        int           filename_len;
00608        long          mode;
00609 
00610        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rls", &z_ftp, &mode, &filename, &filename_len) == FAILURE) {
00611               RETURN_FALSE;
00612        }
00613 
00614        ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
00615 
00616        if (!ftp_chmod(ftp, mode, filename, filename_len)) {
00617               php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ftp->inbuf);
00618               RETURN_FALSE;
00619        }
00620 
00621        RETURN_LONG(mode);
00622 }
00623 /* }}} */
00624 
00625 /* {{{ proto bool ftp_alloc(resource stream, int size[, &response])
00626    Attempt to allocate space on the remote FTP server */
00627 PHP_FUNCTION(ftp_alloc)
00628 {
00629        zval          *z_ftp, *zresponse = NULL;
00630        ftpbuf_t      *ftp;
00631        long          size, ret;
00632        char          *response = NULL;
00633 
00634        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl|z", &z_ftp, &size, &zresponse) == FAILURE) {
00635               RETURN_FALSE;
00636        }
00637 
00638        ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
00639 
00640        ret = ftp_alloc(ftp, size, zresponse ? &response : NULL);
00641        if (response) {
00642               zval_dtor(zresponse);
00643               ZVAL_STRING(zresponse, response, 0);
00644        }
00645 
00646        if (!ret) {
00647               RETURN_FALSE;
00648        }
00649 
00650        RETURN_TRUE;
00651 }
00652 /* }}} */
00653 
00654 /* {{{ proto array ftp_nlist(resource stream, string directory)
00655    Returns an array of filenames in the given directory */
00656 PHP_FUNCTION(ftp_nlist)
00657 {
00658        zval          *z_ftp;
00659        ftpbuf_t      *ftp;
00660        char          **nlist, **ptr, *dir;
00661        int           dir_len;
00662 
00663        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &z_ftp, &dir, &dir_len) == FAILURE) {
00664               return;
00665        }
00666 
00667        ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
00668 
00669        /* get list of files */
00670        if (NULL == (nlist = ftp_nlist(ftp, dir TSRMLS_CC))) {
00671               RETURN_FALSE;
00672        }
00673 
00674        array_init(return_value);
00675        for (ptr = nlist; *ptr; ptr++) {
00676               add_next_index_string(return_value, *ptr, 1);
00677        }
00678        efree(nlist);
00679 }
00680 /* }}} */
00681 
00682 /* {{{ proto array ftp_rawlist(resource stream, string directory [, bool recursive])
00683    Returns a detailed listing of a directory as an array of output lines */
00684 PHP_FUNCTION(ftp_rawlist)
00685 {
00686        zval          *z_ftp;
00687        ftpbuf_t      *ftp;
00688        char          **llist, **ptr, *dir;
00689        int           dir_len;
00690        zend_bool     recursive = 0;
00691 
00692        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|b", &z_ftp, &dir, &dir_len, &recursive) == FAILURE) {
00693               return;
00694        }
00695 
00696        ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
00697 
00698        /* get raw directory listing */
00699        if (NULL == (llist = ftp_list(ftp, dir, recursive TSRMLS_CC))) {
00700               RETURN_FALSE;
00701        }
00702 
00703        array_init(return_value);
00704        for (ptr = llist; *ptr; ptr++) {
00705               add_next_index_string(return_value, *ptr, 1);
00706        }
00707        efree(llist);
00708 }
00709 /* }}} */
00710 
00711 /* {{{ proto string ftp_systype(resource stream)
00712    Returns the system type identifier */
00713 PHP_FUNCTION(ftp_systype)
00714 {
00715        zval          *z_ftp;
00716        ftpbuf_t      *ftp;
00717        const char    *syst;
00718 
00719        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &z_ftp) == FAILURE) {
00720               return;
00721        }
00722 
00723        ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
00724 
00725        if (NULL == (syst = ftp_syst(ftp))) {
00726               php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ftp->inbuf);
00727               RETURN_FALSE;
00728        }
00729 
00730        RETURN_STRING((char*) syst, 1);
00731 }
00732 /* }}} */
00733 
00734 /* {{{ proto bool ftp_fget(resource stream, resource fp, string remote_file, int mode[, int resumepos])
00735    Retrieves a file from the FTP server and writes it to an open file */
00736 PHP_FUNCTION(ftp_fget)
00737 {
00738        zval          *z_ftp, *z_file;
00739        ftpbuf_t      *ftp;
00740        ftptype_t     xtype;
00741        php_stream    *stream;
00742        char          *file;
00743        int           file_len;
00744        long          mode, resumepos=0;
00745 
00746        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rrsl|l", &z_ftp, &z_file, &file, &file_len, &mode, &resumepos) == FAILURE) {
00747               return;
00748        }
00749 
00750        ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
00751        php_stream_from_zval(stream, &z_file);
00752        XTYPE(xtype, mode);
00753 
00754        /* ignore autoresume if autoseek is switched off */
00755        if (!ftp->autoseek && resumepos == PHP_FTP_AUTORESUME) {
00756               resumepos = 0;
00757        }
00758 
00759        if (ftp->autoseek && resumepos) {
00760               /* if autoresume is wanted seek to end */
00761               if (resumepos == PHP_FTP_AUTORESUME) {
00762                      php_stream_seek(stream, 0, SEEK_END);
00763                      resumepos = php_stream_tell(stream);
00764               } else {
00765                      php_stream_seek(stream, resumepos, SEEK_SET);
00766               }
00767        }
00768 
00769        if (!ftp_get(ftp, stream, file, xtype, resumepos TSRMLS_CC)) {
00770               php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ftp->inbuf);
00771               RETURN_FALSE;
00772        }
00773 
00774        RETURN_TRUE;
00775 }
00776 /* }}} */
00777 
00778 /* {{{ proto int ftp_nb_fget(resource stream, resource fp, string remote_file, int mode[, int resumepos])
00779    Retrieves a file from the FTP server asynchronly and writes it to an open file */
00780 PHP_FUNCTION(ftp_nb_fget)
00781 {
00782        zval          *z_ftp, *z_file;
00783        ftpbuf_t      *ftp;
00784        ftptype_t     xtype;
00785        php_stream    *stream;
00786        char          *file;
00787        int           file_len, ret;
00788        long          mode, resumepos=0;
00789 
00790        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rrsl|l", &z_ftp, &z_file, &file, &file_len, &mode, &resumepos) == FAILURE) {
00791               return;
00792        }
00793 
00794        ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
00795        php_stream_from_zval(stream, &z_file);
00796        XTYPE(xtype, mode);
00797 
00798        /* ignore autoresume if autoseek is switched off */
00799        if (!ftp->autoseek && resumepos == PHP_FTP_AUTORESUME) {
00800               resumepos = 0;
00801        }
00802 
00803        if (ftp->autoseek && resumepos) {
00804               /* if autoresume is wanted seek to end */
00805               if (resumepos == PHP_FTP_AUTORESUME) {
00806                      php_stream_seek(stream, 0, SEEK_END);
00807                      resumepos = php_stream_tell(stream);
00808               } else {
00809                      php_stream_seek(stream, resumepos, SEEK_SET);
00810               }
00811        }
00812 
00813        /* configuration */
00814        ftp->direction = 0;   /* recv */
00815        ftp->closestream = 0; /* do not close */
00816 
00817        if ((ret = ftp_nb_get(ftp, stream, file, xtype, resumepos TSRMLS_CC)) == PHP_FTP_FAILED) {
00818               php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ftp->inbuf);
00819               RETURN_LONG(ret);
00820        }
00821 
00822        RETURN_LONG(ret);
00823 }
00824 /* }}} */
00825 
00826 /* {{{ proto bool ftp_pasv(resource stream, bool pasv)
00827    Turns passive mode on or off */
00828 PHP_FUNCTION(ftp_pasv)
00829 {
00830        zval          *z_ftp;
00831        ftpbuf_t      *ftp;
00832        zend_bool     pasv;
00833 
00834        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rb", &z_ftp, &pasv) == FAILURE) {
00835               return;
00836        }
00837 
00838        ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
00839 
00840        if (!ftp_pasv(ftp, pasv ? 1 : 0)) {
00841               RETURN_FALSE;
00842        }
00843 
00844        RETURN_TRUE;
00845 }
00846 /* }}} */
00847 
00848 /* {{{ proto bool ftp_get(resource stream, string local_file, string remote_file, int mode[, int resume_pos])
00849    Retrieves a file from the FTP server and writes it to a local file */
00850 PHP_FUNCTION(ftp_get)
00851 {
00852        zval          *z_ftp;
00853        ftpbuf_t      *ftp;
00854        ftptype_t     xtype;
00855        php_stream    *outstream;
00856        char          *local, *remote;
00857        int           local_len, remote_len;
00858        long          mode, resumepos=0;
00859 
00860        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rssl|l", &z_ftp, &local, &local_len, &remote, &remote_len, &mode, &resumepos) == FAILURE) {
00861               return;
00862        }
00863 
00864        ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
00865        XTYPE(xtype, mode);
00866 
00867        /* ignore autoresume if autoseek is switched off */
00868        if (!ftp->autoseek && resumepos == PHP_FTP_AUTORESUME) {
00869               resumepos = 0;
00870        }
00871 
00872 #ifdef PHP_WIN32
00873        mode = FTPTYPE_IMAGE;
00874 #endif
00875 
00876        if (ftp->autoseek && resumepos) {
00877               outstream = php_stream_open_wrapper(local, mode == FTPTYPE_ASCII ? "rt+" : "rb+", ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL);
00878               if (outstream == NULL) {
00879                      outstream = php_stream_open_wrapper(local, mode == FTPTYPE_ASCII ? "wt" : "wb", ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL);
00880               }
00881               if (outstream != NULL) {
00882                      /* if autoresume is wanted seek to end */
00883                      if (resumepos == PHP_FTP_AUTORESUME) {
00884                             php_stream_seek(outstream, 0, SEEK_END);
00885                             resumepos = php_stream_tell(outstream);
00886                      } else {
00887                             php_stream_seek(outstream, resumepos, SEEK_SET);
00888                      }
00889               }
00890        } else {
00891               outstream = php_stream_open_wrapper(local, mode == FTPTYPE_ASCII ? "wt" : "wb", ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL);
00892        }
00893 
00894        if (outstream == NULL)      {
00895               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error opening %s", local);
00896               RETURN_FALSE;
00897        }
00898 
00899        if (!ftp_get(ftp, outstream, remote, xtype, resumepos TSRMLS_CC)) {
00900               php_stream_close(outstream);
00901               VCWD_UNLINK(local);
00902               php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ftp->inbuf);
00903               RETURN_FALSE;
00904        }
00905 
00906        php_stream_close(outstream);
00907        RETURN_TRUE;
00908 }
00909 /* }}} */
00910 
00911 /* {{{ proto int ftp_nb_get(resource stream, string local_file, string remote_file, int mode[, int resume_pos])
00912    Retrieves a file from the FTP server nbhronly and writes it to a local file */
00913 PHP_FUNCTION(ftp_nb_get)
00914 {
00915        zval          *z_ftp;
00916        ftpbuf_t      *ftp;
00917        ftptype_t     xtype;
00918        php_stream    *outstream;
00919        char          *local, *remote;
00920        int           local_len, remote_len, ret;
00921        long          mode, resumepos=0;
00922 
00923        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rssl|l", &z_ftp, &local, &local_len, &remote, &remote_len, &mode, &resumepos) == FAILURE) {
00924               return;
00925        }
00926 
00927        ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
00928        XTYPE(xtype, mode);
00929 
00930        /* ignore autoresume if autoseek is switched off */
00931        if (!ftp->autoseek && resumepos == PHP_FTP_AUTORESUME) {
00932               resumepos = 0;
00933        }
00934 #ifdef PHP_WIN32
00935        mode = FTPTYPE_IMAGE;
00936 #endif
00937        if (ftp->autoseek && resumepos) {
00938               outstream = php_stream_open_wrapper(local, mode == FTPTYPE_ASCII ? "rt+" : "rb+", ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL);
00939               if (outstream == NULL) {
00940                      outstream = php_stream_open_wrapper(local, mode == FTPTYPE_ASCII ? "wt" : "wb", ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL);
00941               }
00942               if (outstream != NULL) {
00943                      /* if autoresume is wanted seek to end */
00944                      if (resumepos == PHP_FTP_AUTORESUME) {
00945                             php_stream_seek(outstream, 0, SEEK_END);
00946                             resumepos = php_stream_tell(outstream);
00947                      } else {
00948                             php_stream_seek(outstream, resumepos, SEEK_SET);
00949                      }
00950               }
00951        } else {
00952               outstream = php_stream_open_wrapper(local, mode == FTPTYPE_ASCII ? "wt" : "wb", ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL);
00953        }
00954 
00955        if (outstream == NULL)      {
00956               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error opening %s", local);
00957               RETURN_FALSE;
00958        }
00959 
00960        /* configuration */
00961        ftp->direction = 0;   /* recv */
00962        ftp->closestream = 1; /* do close */
00963 
00964        if ((ret = ftp_nb_get(ftp, outstream, remote, xtype, resumepos TSRMLS_CC)) == PHP_FTP_FAILED) {
00965               php_stream_close(outstream);
00966               VCWD_UNLINK(local);
00967               php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ftp->inbuf);
00968               RETURN_LONG(PHP_FTP_FAILED);
00969        }
00970 
00971        if (ret == PHP_FTP_FINISHED) {
00972               php_stream_close(outstream);
00973        }
00974 
00975        RETURN_LONG(ret);
00976 }
00977 /* }}} */
00978 
00979 /* {{{ proto int ftp_nb_continue(resource stream)
00980    Continues retrieving/sending a file nbronously */
00981 PHP_FUNCTION(ftp_nb_continue)
00982 {
00983        zval          *z_ftp;
00984        ftpbuf_t      *ftp;
00985        int           ret;
00986 
00987        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &z_ftp) == FAILURE) {
00988               return;
00989        }
00990 
00991        ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
00992 
00993        if (!ftp->nb) {
00994               php_error_docref(NULL TSRMLS_CC, E_WARNING, "no nbronous transfer to continue.");
00995               RETURN_LONG(PHP_FTP_FAILED);
00996        }
00997 
00998        if (ftp->direction) {
00999               ret=ftp_nb_continue_write(ftp TSRMLS_CC);
01000        } else {
01001               ret=ftp_nb_continue_read(ftp TSRMLS_CC);
01002        }
01003 
01004        if (ret != PHP_FTP_MOREDATA && ftp->closestream) {
01005               php_stream_close(ftp->stream);
01006        }
01007 
01008        if (ret == PHP_FTP_FAILED) {
01009               php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ftp->inbuf);
01010        }
01011 
01012        RETURN_LONG(ret);
01013 }
01014 /* }}} */
01015 
01016 /* {{{ proto bool ftp_fput(resource stream, string remote_file, resource fp, int mode[, int startpos])
01017    Stores a file from an open file to the FTP server */
01018 PHP_FUNCTION(ftp_fput)
01019 {
01020        zval          *z_ftp, *z_file;
01021        ftpbuf_t      *ftp;
01022        ftptype_t     xtype;
01023        int           remote_len;
01024        long          mode, startpos=0;
01025        php_stream    *stream;
01026        char          *remote;
01027 
01028        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsrl|l", &z_ftp, &remote, &remote_len, &z_file, &mode, &startpos) == FAILURE) {
01029               return;
01030        }
01031 
01032        ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
01033        php_stream_from_zval(stream, &z_file);
01034        XTYPE(xtype, mode);
01035 
01036        /* ignore autoresume if autoseek is switched off */
01037        if (!ftp->autoseek && startpos == PHP_FTP_AUTORESUME) {
01038               startpos = 0;
01039        }
01040 
01041        if (ftp->autoseek && startpos) {
01042               /* if autoresume is wanted ask for remote size */
01043               if (startpos == PHP_FTP_AUTORESUME) {
01044                      startpos = ftp_size(ftp, remote);
01045                      if (startpos < 0) {
01046                             startpos = 0;
01047                      }
01048               }
01049               if (startpos) {
01050                      php_stream_seek(stream, startpos, SEEK_SET);
01051               }
01052        }
01053 
01054        if (!ftp_put(ftp, remote, stream, xtype, startpos TSRMLS_CC)) {
01055               php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ftp->inbuf);
01056               RETURN_FALSE;
01057        }
01058 
01059        RETURN_TRUE;
01060 }
01061 /* }}} */
01062 
01063 /* {{{ proto int ftp_nb_fput(resource stream, string remote_file, resource fp, int mode[, int startpos])
01064    Stores a file from an open file to the FTP server nbronly */
01065 PHP_FUNCTION(ftp_nb_fput)
01066 {
01067        zval          *z_ftp, *z_file;
01068        ftpbuf_t      *ftp;
01069        ftptype_t     xtype;
01070        int           remote_len, ret;
01071        long          mode, startpos=0;
01072        php_stream    *stream;
01073        char          *remote;
01074 
01075        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsrl|l", &z_ftp, &remote, &remote_len, &z_file, &mode, &startpos) == FAILURE) {
01076               return;
01077        }
01078 
01079        ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
01080        php_stream_from_zval(stream, &z_file);
01081        XTYPE(xtype, mode);
01082 
01083        /* ignore autoresume if autoseek is switched off */
01084        if (!ftp->autoseek && startpos == PHP_FTP_AUTORESUME) {
01085               startpos = 0;
01086        }
01087 
01088        if (ftp->autoseek && startpos) {
01089               /* if autoresume is wanted ask for remote size */
01090               if (startpos == PHP_FTP_AUTORESUME) {
01091                      startpos = ftp_size(ftp, remote);
01092                      if (startpos < 0) {
01093                             startpos = 0;
01094                      }
01095               }
01096               if (startpos) {
01097                      php_stream_seek(stream, startpos, SEEK_SET);
01098               }
01099        }
01100 
01101        /* configuration */
01102        ftp->direction = 1;   /* send */
01103        ftp->closestream = 0; /* do not close */
01104 
01105        if (((ret = ftp_nb_put(ftp, remote, stream, xtype, startpos TSRMLS_CC)) == PHP_FTP_FAILED)) {
01106               php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ftp->inbuf);
01107               RETURN_LONG(ret);
01108        }
01109 
01110        RETURN_LONG(ret);
01111 }
01112 /* }}} */
01113 
01114 
01115 /* {{{ proto bool ftp_put(resource stream, string remote_file, string local_file, int mode[, int startpos])
01116    Stores a file on the FTP server */
01117 PHP_FUNCTION(ftp_put)
01118 {
01119        zval          *z_ftp;
01120        ftpbuf_t      *ftp;
01121        ftptype_t     xtype;
01122        char          *remote, *local;
01123        int           remote_len, local_len;
01124        long          mode, startpos=0;
01125        php_stream    *instream;
01126 
01127        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rssl|l", &z_ftp, &remote, &remote_len, &local, &local_len, &mode, &startpos) == FAILURE) {
01128               return;
01129        }
01130 
01131        ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
01132        XTYPE(xtype, mode);
01133 
01134        if (!(instream = php_stream_open_wrapper(local, mode == FTPTYPE_ASCII ? "rt" : "rb", ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL))) {
01135               RETURN_FALSE;
01136        }
01137 
01138        /* ignore autoresume if autoseek is switched off */
01139        if (!ftp->autoseek && startpos == PHP_FTP_AUTORESUME) {
01140               startpos = 0;
01141        }
01142 
01143        if (ftp->autoseek && startpos) {
01144               /* if autoresume is wanted ask for remote size */
01145               if (startpos == PHP_FTP_AUTORESUME) {
01146                      startpos = ftp_size(ftp, remote);
01147                      if (startpos < 0) {
01148                             startpos = 0;
01149                      }
01150               }
01151               if (startpos) {
01152                      php_stream_seek(instream, startpos, SEEK_SET);
01153               }
01154        }
01155 
01156        if (!ftp_put(ftp, remote, instream, xtype, startpos TSRMLS_CC)) {
01157               php_stream_close(instream);
01158               php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ftp->inbuf);
01159               RETURN_FALSE;
01160        }
01161        php_stream_close(instream);
01162 
01163        RETURN_TRUE;
01164 }
01165 /* }}} */
01166 
01167 
01168 /* {{{ proto int ftp_nb_put(resource stream, string remote_file, string local_file, int mode[, int startpos])
01169    Stores a file on the FTP server */
01170 PHP_FUNCTION(ftp_nb_put)
01171 {
01172        zval          *z_ftp;
01173        ftpbuf_t      *ftp;
01174        ftptype_t     xtype;
01175        char          *remote, *local;
01176        int           remote_len, local_len, ret;
01177        long          mode, startpos=0;
01178        php_stream    *instream;
01179 
01180        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rssl|l", &z_ftp, &remote, &remote_len, &local, &local_len, &mode, &startpos) == FAILURE) {
01181               return;
01182        }
01183 
01184        ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
01185        XTYPE(xtype, mode);
01186 
01187        if (!(instream = php_stream_open_wrapper(local, mode == FTPTYPE_ASCII ? "rt" : "rb", ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL))) {
01188               RETURN_FALSE;
01189        }
01190 
01191        /* ignore autoresume if autoseek is switched off */
01192        if (!ftp->autoseek && startpos == PHP_FTP_AUTORESUME) {
01193               startpos = 0;
01194        }
01195 
01196        if (ftp->autoseek && startpos) {
01197               /* if autoresume is wanted ask for remote size */
01198               if (startpos == PHP_FTP_AUTORESUME) {
01199                      startpos = ftp_size(ftp, remote);
01200                      if (startpos < 0) {
01201                             startpos = 0;
01202                      }
01203               }
01204               if (startpos) {
01205                      php_stream_seek(instream, startpos, SEEK_SET);
01206               }
01207        }
01208 
01209        /* configuration */
01210        ftp->direction = 1;   /* send */
01211        ftp->closestream = 1; /* do close */
01212 
01213        ret = ftp_nb_put(ftp, remote, instream, xtype, startpos TSRMLS_CC);
01214 
01215        if (ret != PHP_FTP_MOREDATA) {
01216               php_stream_close(instream);
01217        }
01218 
01219        if (ret == PHP_FTP_FAILED) {
01220               php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ftp->inbuf);
01221        }
01222 
01223        RETURN_LONG(ret);
01224 }
01225 /* }}} */
01226 
01227 /* {{{ proto int ftp_size(resource stream, string filename)
01228    Returns the size of the file, or -1 on error */
01229 PHP_FUNCTION(ftp_size)
01230 {
01231        zval          *z_ftp;
01232        ftpbuf_t      *ftp;
01233        char          *file;
01234        int           file_len;
01235 
01236        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &z_ftp, &file, &file_len) == FAILURE) {
01237               return;
01238        }
01239 
01240        ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
01241 
01242        /* get file size */
01243        RETURN_LONG(ftp_size(ftp, file));
01244 }
01245 /* }}} */
01246 
01247 /* {{{ proto int ftp_mdtm(resource stream, string filename)
01248    Returns the last modification time of the file, or -1 on error */
01249 PHP_FUNCTION(ftp_mdtm)
01250 {
01251        zval          *z_ftp;
01252        ftpbuf_t      *ftp;
01253        char          *file;
01254        int           file_len;
01255 
01256        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &z_ftp, &file, &file_len) == FAILURE) {
01257               return;
01258        }
01259 
01260        ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
01261 
01262        /* get file mod time */
01263        RETURN_LONG(ftp_mdtm(ftp, file));
01264 }
01265 /* }}} */
01266 
01267 /* {{{ proto bool ftp_rename(resource stream, string src, string dest)
01268    Renames the given file to a new path */
01269 PHP_FUNCTION(ftp_rename)
01270 {
01271        zval          *z_ftp;
01272        ftpbuf_t      *ftp;
01273        char          *src, *dest;
01274        int           src_len, dest_len;
01275 
01276        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rss", &z_ftp, &src, &src_len, &dest, &dest_len) == FAILURE) {
01277               return;
01278        }
01279 
01280        ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
01281 
01282        /* rename the file */
01283        if (!ftp_rename(ftp, src, dest)) {
01284               php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ftp->inbuf);
01285               RETURN_FALSE;
01286        }
01287 
01288        RETURN_TRUE;
01289 }
01290 /* }}} */
01291 
01292 /* {{{ proto bool ftp_delete(resource stream, string file)
01293    Deletes a file */
01294 PHP_FUNCTION(ftp_delete)
01295 {
01296        zval          *z_ftp;
01297        ftpbuf_t      *ftp;
01298        char          *file;
01299        int           file_len;
01300 
01301        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &z_ftp, &file, &file_len) == FAILURE) {
01302               return;
01303        }
01304 
01305        ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
01306 
01307        /* delete the file */
01308        if (!ftp_delete(ftp, file)) {
01309               php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ftp->inbuf);
01310               RETURN_FALSE;
01311        }
01312 
01313        RETURN_TRUE;
01314 }
01315 /* }}} */
01316 
01317 /* {{{ proto bool ftp_site(resource stream, string cmd)
01318    Sends a SITE command to the server */
01319 PHP_FUNCTION(ftp_site)
01320 {
01321        zval          *z_ftp;
01322        ftpbuf_t      *ftp;
01323        char          *cmd;
01324        int           cmd_len;
01325 
01326        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &z_ftp, &cmd, &cmd_len) == FAILURE) {
01327               return;
01328        }
01329 
01330        ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
01331 
01332        /* send the site command */
01333        if (!ftp_site(ftp, cmd)) {
01334               php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ftp->inbuf);
01335               RETURN_FALSE;
01336        }
01337 
01338        RETURN_TRUE;
01339 }
01340 /* }}} */
01341 
01342 /* {{{ proto bool ftp_close(resource stream)
01343    Closes the FTP stream */
01344 PHP_FUNCTION(ftp_close)
01345 {
01346        zval          *z_ftp;
01347        ftpbuf_t      *ftp;
01348 
01349        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &z_ftp) == FAILURE) {
01350               return;
01351        }
01352 
01353        ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
01354 
01355        ftp_quit(ftp);
01356 
01357        RETURN_BOOL(zend_list_delete(Z_LVAL_P(z_ftp)) == SUCCESS);
01358 }
01359 /* }}} */
01360 
01361 /* {{{ proto bool ftp_set_option(resource stream, int option, mixed value)
01362    Sets an FTP option */
01363 PHP_FUNCTION(ftp_set_option)
01364 {
01365        zval          *z_ftp, *z_value;
01366        long          option;
01367        ftpbuf_t      *ftp;
01368 
01369        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rlz", &z_ftp, &option, &z_value) == FAILURE) {
01370               return;
01371        }
01372 
01373        ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
01374 
01375        switch (option) {
01376               case PHP_FTP_OPT_TIMEOUT_SEC:
01377                      if (Z_TYPE_P(z_value) != IS_LONG) {
01378                             php_error_docref(NULL TSRMLS_CC, E_WARNING, "Option TIMEOUT_SEC expects value of type long, %s given",
01379                                    zend_zval_type_name(z_value));
01380                             RETURN_FALSE;
01381                      }
01382                      if (Z_LVAL_P(z_value) <= 0) {
01383                             php_error_docref(NULL TSRMLS_CC, E_WARNING, "Timeout has to be greater than 0");
01384                             RETURN_FALSE;
01385                      }
01386                      ftp->timeout_sec = Z_LVAL_P(z_value);
01387                      RETURN_TRUE;
01388                      break;
01389               case PHP_FTP_OPT_AUTOSEEK:
01390                      if (Z_TYPE_P(z_value) != IS_BOOL) {
01391                             php_error_docref(NULL TSRMLS_CC, E_WARNING, "Option AUTOSEEK expects value of type boolean, %s given",
01392                                    zend_zval_type_name(z_value));
01393                             RETURN_FALSE;
01394                      }
01395                      ftp->autoseek = Z_LVAL_P(z_value);
01396                      RETURN_TRUE;
01397                      break;
01398               default:
01399                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown option '%ld'", option);
01400                      RETURN_FALSE;
01401                      break;
01402        }
01403 }
01404 /* }}} */
01405 
01406 /* {{{ proto mixed ftp_get_option(resource stream, int option)
01407    Gets an FTP option */
01408 PHP_FUNCTION(ftp_get_option)
01409 {
01410        zval          *z_ftp;
01411        long          option;
01412        ftpbuf_t      *ftp;
01413 
01414        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &z_ftp, &option) == FAILURE) {
01415               return;
01416        }
01417 
01418        ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
01419 
01420        switch (option) {
01421               case PHP_FTP_OPT_TIMEOUT_SEC:
01422                      RETURN_LONG(ftp->timeout_sec);
01423                      break;
01424               case PHP_FTP_OPT_AUTOSEEK:
01425                      RETURN_BOOL(ftp->autoseek);
01426                      break;
01427               default:
01428                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown option '%ld'", option);
01429                      RETURN_FALSE;
01430                      break;
01431        }
01432 }
01433 /* }}} */
01434 
01435 #endif /* HAVE_FTP */
01436 
01437 /*
01438  * Local variables:
01439  * tab-width: 4
01440  * c-basic-offset: 4
01441  * indent-tabs-mode: t
01442  * End:
01443  */