Annotation of embedaddon/php/ext/ftp/php_ftp.c, revision 1.1.1.2

1.1       misho       1: /*
                      2:    +----------------------------------------------------------------------+
                      3:    | PHP Version 5                                                        |
                      4:    +----------------------------------------------------------------------+
                      5:    | Copyright (c) 1997-2012 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: 
1.1.1.2 ! misho      20: /* $Id$ */
1.1       misho      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: 
1.1.1.2 ! misho      44: static int le_ftpbuf;
1.1       misho      45: #define le_ftpbuf_name "FTP Buffer"
                     46: 
                     47: /* {{{ arginfo */
                     48: ZEND_BEGIN_ARG_INFO_EX(arginfo_ftp_connect, 0, 0, 1)
                     49:        ZEND_ARG_INFO(0, host)
                     50:        ZEND_ARG_INFO(0, port)
                     51:        ZEND_ARG_INFO(0, timeout)
                     52: ZEND_END_ARG_INFO()
                     53: 
                     54: #if HAVE_OPENSSL_EXT
                     55: ZEND_BEGIN_ARG_INFO_EX(arginfo_ftp_ssl_connect, 0, 0, 1)
                     56:        ZEND_ARG_INFO(0, host)
                     57:        ZEND_ARG_INFO(0, port)
                     58:        ZEND_ARG_INFO(0, timeout)
                     59: ZEND_END_ARG_INFO()
                     60: #endif
                     61: 
                     62: ZEND_BEGIN_ARG_INFO(arginfo_ftp_login, 0)
                     63:        ZEND_ARG_INFO(0, ftp)
                     64:        ZEND_ARG_INFO(0, username)
                     65:        ZEND_ARG_INFO(0, password)
                     66: ZEND_END_ARG_INFO()
                     67: 
                     68: ZEND_BEGIN_ARG_INFO(arginfo_ftp_pwd, 0)
                     69:        ZEND_ARG_INFO(0, ftp)
                     70: ZEND_END_ARG_INFO()
                     71: 
                     72: ZEND_BEGIN_ARG_INFO(arginfo_ftp_cdup, 0)
                     73:        ZEND_ARG_INFO(0, ftp)
                     74: ZEND_END_ARG_INFO()
                     75: 
                     76: ZEND_BEGIN_ARG_INFO(arginfo_ftp_chdir, 0)
                     77:        ZEND_ARG_INFO(0, ftp)
                     78:        ZEND_ARG_INFO(0, directory)
                     79: ZEND_END_ARG_INFO()
                     80: 
                     81: ZEND_BEGIN_ARG_INFO(arginfo_ftp_exec, 0)
                     82:        ZEND_ARG_INFO(0, ftp)
                     83:        ZEND_ARG_INFO(0, command)
                     84: ZEND_END_ARG_INFO()
                     85: 
                     86: ZEND_BEGIN_ARG_INFO(arginfo_ftp_raw, 0)
                     87:        ZEND_ARG_INFO(0, ftp)
                     88:        ZEND_ARG_INFO(0, command)
                     89: ZEND_END_ARG_INFO()
                     90: 
                     91: ZEND_BEGIN_ARG_INFO(arginfo_ftp_mkdir, 0)
                     92:        ZEND_ARG_INFO(0, ftp)
                     93:        ZEND_ARG_INFO(0, directory)
                     94: ZEND_END_ARG_INFO()
                     95: 
                     96: ZEND_BEGIN_ARG_INFO(arginfo_ftp_rmdir, 0)
                     97:        ZEND_ARG_INFO(0, ftp)
                     98:        ZEND_ARG_INFO(0, directory)
                     99: ZEND_END_ARG_INFO()
                    100: 
                    101: ZEND_BEGIN_ARG_INFO(arginfo_ftp_chmod, 0)
                    102:        ZEND_ARG_INFO(0, ftp)
                    103:        ZEND_ARG_INFO(0, mode)
                    104:        ZEND_ARG_INFO(0, filename)
                    105: ZEND_END_ARG_INFO()
                    106: 
                    107: ZEND_BEGIN_ARG_INFO_EX(arginfo_ftp_alloc, 0, 0, 2)
                    108:        ZEND_ARG_INFO(0, ftp)
                    109:        ZEND_ARG_INFO(0, size)
                    110:        ZEND_ARG_INFO(1, response)
                    111: ZEND_END_ARG_INFO()
                    112: 
                    113: ZEND_BEGIN_ARG_INFO(arginfo_ftp_nlist, 0)
                    114:        ZEND_ARG_INFO(0, ftp)
                    115:        ZEND_ARG_INFO(0, directory)
                    116: ZEND_END_ARG_INFO()
                    117: 
                    118: ZEND_BEGIN_ARG_INFO_EX(arginfo_ftp_rawlist, 0, 0, 2)
                    119:        ZEND_ARG_INFO(0, ftp)
                    120:        ZEND_ARG_INFO(0, directory)
                    121:        ZEND_ARG_INFO(0, recursive)
                    122: ZEND_END_ARG_INFO()
                    123: 
                    124: ZEND_BEGIN_ARG_INFO(arginfo_ftp_systype, 0)
                    125:        ZEND_ARG_INFO(0, ftp)
                    126: ZEND_END_ARG_INFO()
                    127: 
                    128: ZEND_BEGIN_ARG_INFO_EX(arginfo_ftp_fget, 0, 0, 4)
                    129:        ZEND_ARG_INFO(0, ftp)
                    130:        ZEND_ARG_INFO(0, fp)
                    131:        ZEND_ARG_INFO(0, remote_file)
                    132:        ZEND_ARG_INFO(0, mode)
                    133:        ZEND_ARG_INFO(0, resumepos)
                    134: ZEND_END_ARG_INFO()
                    135: 
                    136: ZEND_BEGIN_ARG_INFO_EX(arginfo_ftp_nb_fget, 0, 0, 4)
                    137:        ZEND_ARG_INFO(0, ftp)
                    138:        ZEND_ARG_INFO(0, fp)
                    139:        ZEND_ARG_INFO(0, remote_file)
                    140:        ZEND_ARG_INFO(0, mode)
                    141:        ZEND_ARG_INFO(0, resumepos)
                    142: ZEND_END_ARG_INFO()
                    143: 
                    144: ZEND_BEGIN_ARG_INFO(arginfo_ftp_pasv, 0)
                    145:        ZEND_ARG_INFO(0, ftp)
                    146:        ZEND_ARG_INFO(0, pasv)
                    147: ZEND_END_ARG_INFO()
                    148: 
                    149: ZEND_BEGIN_ARG_INFO_EX(arginfo_ftp_get, 0, 0, 4)
                    150:        ZEND_ARG_INFO(0, ftp)
                    151:        ZEND_ARG_INFO(0, local_file)
                    152:        ZEND_ARG_INFO(0, remote_file)
                    153:        ZEND_ARG_INFO(0, mode)
                    154:        ZEND_ARG_INFO(0, resume_pos)
                    155: ZEND_END_ARG_INFO()
                    156: 
                    157: ZEND_BEGIN_ARG_INFO_EX(arginfo_ftp_nb_get, 0, 0, 4)
                    158:        ZEND_ARG_INFO(0, ftp)
                    159:        ZEND_ARG_INFO(0, local_file)
                    160:        ZEND_ARG_INFO(0, remote_file)
                    161:        ZEND_ARG_INFO(0, mode)
                    162:        ZEND_ARG_INFO(0, resume_pos)
                    163: ZEND_END_ARG_INFO()
                    164: 
                    165: ZEND_BEGIN_ARG_INFO(arginfo_ftp_nb_continue, 0)
                    166:        ZEND_ARG_INFO(0, ftp)
                    167: ZEND_END_ARG_INFO()
                    168: 
                    169: ZEND_BEGIN_ARG_INFO_EX(arginfo_ftp_fput, 0, 0, 4)
                    170:        ZEND_ARG_INFO(0, ftp)
                    171:        ZEND_ARG_INFO(0, remote_file)
                    172:        ZEND_ARG_INFO(0, fp)
                    173:        ZEND_ARG_INFO(0, mode)
                    174:        ZEND_ARG_INFO(0, startpos)
                    175: ZEND_END_ARG_INFO()
                    176: 
                    177: ZEND_BEGIN_ARG_INFO_EX(arginfo_ftp_nb_fput, 0, 0, 4)
                    178:        ZEND_ARG_INFO(0, ftp)
                    179:        ZEND_ARG_INFO(0, remote_file)
                    180:        ZEND_ARG_INFO(0, fp)
                    181:        ZEND_ARG_INFO(0, mode)
                    182:        ZEND_ARG_INFO(0, startpos)
                    183: ZEND_END_ARG_INFO()
                    184: 
                    185: ZEND_BEGIN_ARG_INFO_EX(arginfo_ftp_put, 0, 0, 4)
                    186:        ZEND_ARG_INFO(0, ftp)
                    187:        ZEND_ARG_INFO(0, remote_file)
                    188:        ZEND_ARG_INFO(0, local_file)
                    189:        ZEND_ARG_INFO(0, mode)
                    190:        ZEND_ARG_INFO(0, startpos)
                    191: ZEND_END_ARG_INFO()
                    192: 
                    193: ZEND_BEGIN_ARG_INFO_EX(arginfo_ftp_nb_put, 0, 0, 4)
                    194:        ZEND_ARG_INFO(0, ftp)
                    195:        ZEND_ARG_INFO(0, remote_file)
                    196:        ZEND_ARG_INFO(0, local_file)
                    197:        ZEND_ARG_INFO(0, mode)
                    198:        ZEND_ARG_INFO(0, startpos)
                    199: ZEND_END_ARG_INFO()
                    200: 
                    201: ZEND_BEGIN_ARG_INFO(arginfo_ftp_size, 0)
                    202:        ZEND_ARG_INFO(0, ftp)
                    203:        ZEND_ARG_INFO(0, filename)
                    204: ZEND_END_ARG_INFO()
                    205: 
                    206: ZEND_BEGIN_ARG_INFO(arginfo_ftp_mdtm, 0)
                    207:        ZEND_ARG_INFO(0, ftp)
                    208:        ZEND_ARG_INFO(0, filename)
                    209: ZEND_END_ARG_INFO()
                    210: 
                    211: ZEND_BEGIN_ARG_INFO(arginfo_ftp_rename, 0)
                    212:        ZEND_ARG_INFO(0, ftp)
                    213:        ZEND_ARG_INFO(0, src)
                    214:        ZEND_ARG_INFO(0, dest)
                    215: ZEND_END_ARG_INFO()
                    216: 
                    217: ZEND_BEGIN_ARG_INFO(arginfo_ftp_delete, 0)
                    218:        ZEND_ARG_INFO(0, ftp)
                    219:        ZEND_ARG_INFO(0, file)
                    220: ZEND_END_ARG_INFO()
                    221: 
                    222: ZEND_BEGIN_ARG_INFO(arginfo_ftp_site, 0)
                    223:        ZEND_ARG_INFO(0, ftp)
                    224:        ZEND_ARG_INFO(0, cmd)
                    225: ZEND_END_ARG_INFO()
                    226: 
                    227: ZEND_BEGIN_ARG_INFO(arginfo_ftp_close, 0)
                    228:        ZEND_ARG_INFO(0, ftp)
                    229: ZEND_END_ARG_INFO()
                    230: 
                    231: ZEND_BEGIN_ARG_INFO(arginfo_ftp_set_option, 0)
                    232:        ZEND_ARG_INFO(0, ftp)
                    233:        ZEND_ARG_INFO(0, option)
                    234:        ZEND_ARG_INFO(0, value)
                    235: ZEND_END_ARG_INFO()
                    236: 
                    237: ZEND_BEGIN_ARG_INFO(arginfo_ftp_get_option, 0)
                    238:        ZEND_ARG_INFO(0, ftp)
                    239:        ZEND_ARG_INFO(0, option)
                    240: ZEND_END_ARG_INFO()
                    241: 
                    242: /* }}} */
                    243: 
                    244: const zend_function_entry php_ftp_functions[] = {
                    245:        PHP_FE(ftp_connect,                     arginfo_ftp_connect)
                    246: #if HAVE_OPENSSL_EXT
                    247:        PHP_FE(ftp_ssl_connect,         arginfo_ftp_ssl_connect)
                    248: #endif 
                    249:        PHP_FE(ftp_login,                       arginfo_ftp_login)
                    250:        PHP_FE(ftp_pwd,                         arginfo_ftp_pwd)
                    251:        PHP_FE(ftp_cdup,                        arginfo_ftp_cdup)
                    252:        PHP_FE(ftp_chdir,                       arginfo_ftp_chdir)
                    253:        PHP_FE(ftp_exec,                        arginfo_ftp_exec)
                    254:        PHP_FE(ftp_raw,                         arginfo_ftp_raw)
                    255:        PHP_FE(ftp_mkdir,                       arginfo_ftp_mkdir)
                    256:        PHP_FE(ftp_rmdir,                       arginfo_ftp_rmdir)
                    257:        PHP_FE(ftp_chmod,                       arginfo_ftp_chmod)
                    258:        PHP_FE(ftp_alloc,                       arginfo_ftp_alloc)
                    259:        PHP_FE(ftp_nlist,                       arginfo_ftp_nlist)
                    260:        PHP_FE(ftp_rawlist,                     arginfo_ftp_rawlist)
                    261:        PHP_FE(ftp_systype,                     arginfo_ftp_systype)
                    262:        PHP_FE(ftp_pasv,                        arginfo_ftp_pasv)
                    263:        PHP_FE(ftp_get,                         arginfo_ftp_get)
                    264:        PHP_FE(ftp_fget,                        arginfo_ftp_fget)
                    265:        PHP_FE(ftp_put,                         arginfo_ftp_put)
                    266:        PHP_FE(ftp_fput,                        arginfo_ftp_fput)
                    267:        PHP_FE(ftp_size,                        arginfo_ftp_size)
                    268:        PHP_FE(ftp_mdtm,                        arginfo_ftp_mdtm)
                    269:        PHP_FE(ftp_rename,                      arginfo_ftp_rename)
                    270:        PHP_FE(ftp_delete,                      arginfo_ftp_delete)
                    271:        PHP_FE(ftp_site,                        arginfo_ftp_site)
                    272:        PHP_FE(ftp_close,                       arginfo_ftp_close)
                    273:        PHP_FE(ftp_set_option,          arginfo_ftp_set_option)
                    274:        PHP_FE(ftp_get_option,          arginfo_ftp_get_option)
                    275:        PHP_FE(ftp_nb_fget,                     arginfo_ftp_nb_fget)
                    276:        PHP_FE(ftp_nb_get,                      arginfo_ftp_nb_get)
                    277:        PHP_FE(ftp_nb_continue,         arginfo_ftp_nb_continue)
                    278:        PHP_FE(ftp_nb_put,                      arginfo_ftp_nb_put)
                    279:        PHP_FE(ftp_nb_fput,                     arginfo_ftp_nb_fput)
                    280:        PHP_FALIAS(ftp_quit, ftp_close, arginfo_ftp_close)
                    281:        PHP_FE_END
                    282: };
                    283: 
                    284: zend_module_entry php_ftp_module_entry = {
                    285:     STANDARD_MODULE_HEADER,
                    286:        "ftp",
                    287:        php_ftp_functions,
                    288:        PHP_MINIT(ftp),
                    289:        NULL,
                    290:        NULL,
                    291:        NULL,
                    292:        PHP_MINFO(ftp),
                    293:     NO_VERSION_YET,
                    294:        STANDARD_MODULE_PROPERTIES
                    295: };
                    296: 
                    297: #if COMPILE_DL_FTP
                    298: ZEND_GET_MODULE(php_ftp)
                    299: #endif
                    300: 
                    301: static void ftp_destructor_ftpbuf(zend_rsrc_list_entry *rsrc TSRMLS_DC)
                    302: {
                    303:        ftpbuf_t *ftp = (ftpbuf_t *)rsrc->ptr;
                    304: 
                    305:        ftp_close(ftp);
                    306: }
                    307: 
                    308: PHP_MINIT_FUNCTION(ftp)
                    309: {
                    310:        le_ftpbuf = zend_register_list_destructors_ex(ftp_destructor_ftpbuf, NULL, le_ftpbuf_name, module_number);
                    311:        REGISTER_LONG_CONSTANT("FTP_ASCII",  FTPTYPE_ASCII, CONST_PERSISTENT | CONST_CS);
                    312:        REGISTER_LONG_CONSTANT("FTP_TEXT",   FTPTYPE_ASCII, CONST_PERSISTENT | CONST_CS);
                    313:        REGISTER_LONG_CONSTANT("FTP_BINARY", FTPTYPE_IMAGE, CONST_PERSISTENT | CONST_CS);
                    314:        REGISTER_LONG_CONSTANT("FTP_IMAGE",  FTPTYPE_IMAGE, CONST_PERSISTENT | CONST_CS);
                    315:        REGISTER_LONG_CONSTANT("FTP_AUTORESUME", PHP_FTP_AUTORESUME, CONST_PERSISTENT | CONST_CS);
                    316:        REGISTER_LONG_CONSTANT("FTP_TIMEOUT_SEC", PHP_FTP_OPT_TIMEOUT_SEC, CONST_PERSISTENT | CONST_CS);
                    317:        REGISTER_LONG_CONSTANT("FTP_AUTOSEEK", PHP_FTP_OPT_AUTOSEEK, CONST_PERSISTENT | CONST_CS);
                    318:        REGISTER_LONG_CONSTANT("FTP_FAILED", PHP_FTP_FAILED, CONST_PERSISTENT | CONST_CS);
                    319:        REGISTER_LONG_CONSTANT("FTP_FINISHED", PHP_FTP_FINISHED, CONST_PERSISTENT | CONST_CS);
                    320:        REGISTER_LONG_CONSTANT("FTP_MOREDATA", PHP_FTP_MOREDATA, CONST_PERSISTENT | CONST_CS);
                    321:        return SUCCESS;
                    322: }
                    323: 
                    324: PHP_MINFO_FUNCTION(ftp)
                    325: {
                    326:        php_info_print_table_start();
                    327:        php_info_print_table_row(2, "FTP support", "enabled");
                    328:        php_info_print_table_end();
                    329: }
                    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: {
                    344:        ftpbuf_t        *ftp;
                    345:        char            *host;
                    346:        int             host_len;
                    347:        long            port = 0;
                    348:        long            timeout_sec = FTP_DEFAULT_TIMEOUT;
                    349: 
                    350:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ll", &host, &host_len, &port, &timeout_sec) == FAILURE) {
                    351:                return;
                    352:        }
                    353: 
                    354:        if (timeout_sec <= 0) {
                    355:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Timeout has to be greater than 0");
                    356:                RETURN_FALSE;
                    357:        }
                    358: 
                    359:        /* connect */
                    360:        if (!(ftp = ftp_open(host, (short)port, timeout_sec TSRMLS_CC))) {
                    361:                RETURN_FALSE;
                    362:        }
                    363: 
                    364:        /* autoseek for resuming */
                    365:        ftp->autoseek = FTP_DEFAULT_AUTOSEEK;
                    366: #if HAVE_OPENSSL_EXT
                    367:        /* disable ssl */
                    368:        ftp->use_ssl = 0;
                    369: #endif
                    370: 
                    371:        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: {
                    380:        ftpbuf_t        *ftp;
                    381:        char            *host;
                    382:        int             host_len;
                    383:        long            port = 0;
                    384:        long            timeout_sec = FTP_DEFAULT_TIMEOUT;
                    385: 
                    386:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ll", &host, &host_len, &port, &timeout_sec) == FAILURE) {
                    387:                return;
                    388:        }
                    389: 
                    390:        if (timeout_sec <= 0) {
                    391:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Timeout has to be greater than 0");
                    392:                RETURN_FALSE;
                    393:        }
                    394: 
                    395:        /* connect */
                    396:        if (!(ftp = ftp_open(host, (short)port, timeout_sec TSRMLS_CC))) {
                    397:                RETURN_FALSE;
                    398:        }
                    399: 
                    400:        /* autoseek for resuming */
                    401:        ftp->autoseek = FTP_DEFAULT_AUTOSEEK;
                    402:        /* enable ssl */
                    403:        ftp->use_ssl = 1;
                    404: 
                    405:        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: {
                    414:        zval            *z_ftp;
                    415:        ftpbuf_t        *ftp;
                    416:        char *user, *pass;
                    417:        int user_len, pass_len;
                    418: 
                    419:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rss", &z_ftp, &user, &user_len, &pass, &pass_len) == FAILURE) {
                    420:                return;
                    421:        }
                    422: 
                    423:        ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
                    424: 
                    425:        /* log in */
                    426:        if (!ftp_login(ftp, user, pass TSRMLS_CC)) {
                    427:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ftp->inbuf);
                    428:                RETURN_FALSE;
                    429:        }
                    430: 
                    431:        RETURN_TRUE;
                    432: }
                    433: /* }}} */
                    434: 
                    435: /* {{{ proto string ftp_pwd(resource stream)
                    436:    Returns the present working directory */
                    437: PHP_FUNCTION(ftp_pwd)
                    438: {
                    439:        zval            *z_ftp;
                    440:        ftpbuf_t        *ftp;
                    441:        const char      *pwd;
                    442: 
                    443:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &z_ftp) == FAILURE) {
                    444:                return;
                    445:        }
                    446: 
                    447:        ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
                    448: 
                    449:        if (!(pwd = ftp_pwd(ftp))) {
                    450:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ftp->inbuf);
                    451:                RETURN_FALSE;
                    452:        }
                    453: 
                    454:        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: {
                    462:        zval            *z_ftp;
                    463:        ftpbuf_t        *ftp;
                    464: 
                    465:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &z_ftp) == FAILURE) {
                    466:                return;
                    467:        }
                    468: 
                    469:        ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
                    470: 
                    471:        if (!ftp_cdup(ftp)) {
                    472:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ftp->inbuf);
                    473:                RETURN_FALSE;
                    474:        }
                    475: 
                    476:        RETURN_TRUE;
                    477: }
                    478: /* }}} */
                    479: 
                    480: /* {{{ proto bool ftp_chdir(resource stream, string directory)
                    481:    Changes directories */
                    482: PHP_FUNCTION(ftp_chdir)
                    483: {
                    484:        zval            *z_ftp;
                    485:        ftpbuf_t        *ftp;
                    486:        char            *dir;
                    487:        int                     dir_len;
                    488: 
                    489:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &z_ftp, &dir, &dir_len) == FAILURE) {
                    490:                return;
                    491:        }
                    492: 
                    493:        ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
                    494: 
                    495:        /* change directories */
                    496:        if (!ftp_chdir(ftp, dir)) {
                    497:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ftp->inbuf);
                    498:                RETURN_FALSE;
                    499:        }
                    500: 
                    501:        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: {
                    509:        zval            *z_ftp;
                    510:        ftpbuf_t        *ftp;
                    511:        char            *cmd;
                    512:        int                     cmd_len;
                    513: 
                    514:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &z_ftp, &cmd, &cmd_len) == FAILURE) {
                    515:                return;
                    516:        }
                    517: 
                    518:        ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
                    519: 
                    520:        /* execute serverside command */
                    521:        if (!ftp_exec(ftp, cmd)) {
                    522:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ftp->inbuf);
                    523:                RETURN_FALSE;
                    524:        }
                    525: 
                    526:        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: {
                    534:        zval            *z_ftp;
                    535:        ftpbuf_t        *ftp;
                    536:        char            *cmd;
                    537:        int                     cmd_len;
                    538: 
                    539:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &z_ftp, &cmd, &cmd_len) == FAILURE) {
                    540:                return;
                    541:        }
                    542: 
                    543:        ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
                    544: 
                    545:        /* execute arbitrary ftp command */
                    546:        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: {
                    554:        zval            *z_ftp;
                    555:        ftpbuf_t        *ftp;
                    556:        char            *dir, *tmp;
                    557:        int             dir_len;
                    558: 
                    559:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &z_ftp, &dir, &dir_len) == FAILURE) {
                    560:                return;
                    561:        }
                    562: 
                    563:        ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
                    564: 
                    565:        /* create directorie */
                    566:        if (NULL == (tmp = ftp_mkdir(ftp, dir))) {
                    567:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ftp->inbuf);
                    568:                RETURN_FALSE;
                    569:        }
                    570: 
                    571:        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: {
                    579:        zval            *z_ftp;
                    580:        ftpbuf_t        *ftp;
                    581:        char            *dir;
                    582:        int             dir_len;
                    583: 
                    584:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &z_ftp, &dir, &dir_len) == FAILURE) {
                    585:                return;
                    586:        }
                    587: 
                    588:        ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
                    589: 
                    590:        /* remove directorie */
                    591:        if (!ftp_rmdir(ftp, dir)) {
                    592:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ftp->inbuf);
                    593:                RETURN_FALSE;
                    594:        }
                    595: 
                    596:        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: {
                    604:        zval            *z_ftp;
                    605:        ftpbuf_t        *ftp;
                    606:        char            *filename;
                    607:        int             filename_len;
                    608:        long            mode;
                    609: 
1.1.1.2 ! misho     610:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rlp", &z_ftp, &mode, &filename, &filename_len) == FAILURE) {
1.1       misho     611:                RETURN_FALSE;
                    612:        }
                    613: 
                    614:        ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
                    615: 
                    616:        if (!ftp_chmod(ftp, mode, filename, filename_len)) {
                    617:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ftp->inbuf);
                    618:                RETURN_FALSE;
                    619:        }
                    620: 
                    621:        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: {
                    629:        zval            *z_ftp, *zresponse = NULL;
                    630:        ftpbuf_t        *ftp;
                    631:        long            size, ret;
                    632:        char            *response = NULL;
                    633: 
                    634:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl|z", &z_ftp, &size, &zresponse) == FAILURE) {
                    635:                RETURN_FALSE;
                    636:        }
                    637: 
                    638:        ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
                    639: 
                    640:        ret = ftp_alloc(ftp, size, zresponse ? &response : NULL);
                    641:        if (response) {
                    642:                zval_dtor(zresponse);
                    643:                ZVAL_STRING(zresponse, response, 0);
                    644:        }
                    645: 
                    646:        if (!ret) {
                    647:                RETURN_FALSE;
                    648:        }
                    649: 
                    650:        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: {
                    658:        zval            *z_ftp;
                    659:        ftpbuf_t        *ftp;
                    660:        char            **nlist, **ptr, *dir;
                    661:        int             dir_len;
                    662: 
1.1.1.2 ! misho     663:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rp", &z_ftp, &dir, &dir_len) == FAILURE) {
1.1       misho     664:                return;
                    665:        }
                    666: 
                    667:        ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
                    668: 
                    669:        /* get list of files */
                    670:        if (NULL == (nlist = ftp_nlist(ftp, dir TSRMLS_CC))) {
                    671:                RETURN_FALSE;
                    672:        }
                    673: 
                    674:        array_init(return_value);
                    675:        for (ptr = nlist; *ptr; ptr++) {
                    676:                add_next_index_string(return_value, *ptr, 1);
                    677:        }
                    678:        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: {
                    686:        zval            *z_ftp;
                    687:        ftpbuf_t        *ftp;
                    688:        char            **llist, **ptr, *dir;
                    689:        int             dir_len;
                    690:        zend_bool       recursive = 0;
                    691: 
                    692:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|b", &z_ftp, &dir, &dir_len, &recursive) == FAILURE) {
                    693:                return;
                    694:        }
                    695: 
                    696:        ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
                    697: 
                    698:        /* get raw directory listing */
                    699:        if (NULL == (llist = ftp_list(ftp, dir, recursive TSRMLS_CC))) {
                    700:                RETURN_FALSE;
                    701:        }
                    702: 
                    703:        array_init(return_value);
                    704:        for (ptr = llist; *ptr; ptr++) {
                    705:                add_next_index_string(return_value, *ptr, 1);
                    706:        }
                    707:        efree(llist);
                    708: }
                    709: /* }}} */
                    710: 
                    711: /* {{{ proto string ftp_systype(resource stream)
                    712:    Returns the system type identifier */
                    713: PHP_FUNCTION(ftp_systype)
                    714: {
                    715:        zval            *z_ftp;
                    716:        ftpbuf_t        *ftp;
                    717:        const char      *syst;
                    718: 
                    719:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &z_ftp) == FAILURE) {
                    720:                return;
                    721:        }
                    722: 
                    723:        ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
                    724: 
                    725:        if (NULL == (syst = ftp_syst(ftp))) {
                    726:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ftp->inbuf);
                    727:                RETURN_FALSE;
                    728:        }
                    729: 
                    730:        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: {
                    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:        long            mode, resumepos=0;
                    745: 
                    746:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rrsl|l", &z_ftp, &z_file, &file, &file_len, &mode, &resumepos) == FAILURE) {
                    747:                return;
                    748:        }
                    749: 
                    750:        ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
                    751:        php_stream_from_zval(stream, &z_file);
                    752:        XTYPE(xtype, mode);
                    753: 
                    754:        /* ignore autoresume if autoseek is switched off */
                    755:        if (!ftp->autoseek && resumepos == PHP_FTP_AUTORESUME) {
                    756:                resumepos = 0;
                    757:        }
                    758: 
                    759:        if (ftp->autoseek && resumepos) {
                    760:                /* if autoresume is wanted seek to end */
                    761:                if (resumepos == PHP_FTP_AUTORESUME) {
                    762:                        php_stream_seek(stream, 0, SEEK_END);
                    763:                        resumepos = php_stream_tell(stream);
                    764:                } else {
                    765:                        php_stream_seek(stream, resumepos, SEEK_SET);
                    766:                }
                    767:        }
                    768: 
                    769:        if (!ftp_get(ftp, stream, file, xtype, resumepos TSRMLS_CC)) {
                    770:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ftp->inbuf);
                    771:                RETURN_FALSE;
                    772:        }
                    773: 
                    774:        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: {
                    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:        long            mode, resumepos=0;
                    789: 
                    790:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rrsl|l", &z_ftp, &z_file, &file, &file_len, &mode, &resumepos) == FAILURE) {
                    791:                return;
                    792:        }
                    793: 
                    794:        ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
                    795:        php_stream_from_zval(stream, &z_file);
                    796:        XTYPE(xtype, mode);
                    797: 
                    798:        /* ignore autoresume if autoseek is switched off */
                    799:        if (!ftp->autoseek && resumepos == PHP_FTP_AUTORESUME) {
                    800:                resumepos = 0;
                    801:        }
                    802: 
                    803:        if (ftp->autoseek && resumepos) {
                    804:                /* if autoresume is wanted seek to end */
                    805:                if (resumepos == PHP_FTP_AUTORESUME) {
                    806:                        php_stream_seek(stream, 0, SEEK_END);
                    807:                        resumepos = php_stream_tell(stream);
                    808:                } else {
                    809:                        php_stream_seek(stream, resumepos, SEEK_SET);
                    810:                }
                    811:        }
                    812: 
                    813:        /* configuration */
                    814:        ftp->direction = 0;   /* recv */
                    815:        ftp->closestream = 0; /* do not close */
                    816: 
                    817:        if ((ret = ftp_nb_get(ftp, stream, file, xtype, resumepos TSRMLS_CC)) == PHP_FTP_FAILED) {
                    818:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ftp->inbuf);
                    819:                RETURN_LONG(ret);
                    820:        }
                    821: 
                    822:        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: {
                    830:        zval            *z_ftp;
                    831:        ftpbuf_t        *ftp;
                    832:        zend_bool       pasv;
                    833: 
                    834:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rb", &z_ftp, &pasv) == FAILURE) {
                    835:                return;
                    836:        }
                    837: 
                    838:        ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
                    839: 
                    840:        if (!ftp_pasv(ftp, pasv ? 1 : 0)) {
                    841:                RETURN_FALSE;
                    842:        }
                    843: 
                    844:        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: {
                    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:        long            mode, resumepos=0;
                    859: 
1.1.1.2 ! misho     860:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rppl|l", &z_ftp, &local, &local_len, &remote, &remote_len, &mode, &resumepos) == FAILURE) {
1.1       misho     861:                return;
                    862:        }
                    863: 
                    864:        ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
                    865:        XTYPE(xtype, mode);
                    866: 
                    867:        /* ignore autoresume if autoseek is switched off */
                    868:        if (!ftp->autoseek && resumepos == PHP_FTP_AUTORESUME) {
                    869:                resumepos = 0;
                    870:        }
                    871: 
                    872: #ifdef PHP_WIN32
                    873:        mode = FTPTYPE_IMAGE;
                    874: #endif
                    875: 
                    876:        if (ftp->autoseek && resumepos) {
1.1.1.2 ! misho     877:                outstream = php_stream_open_wrapper(local, mode == FTPTYPE_ASCII ? "rt+" : "rb+", REPORT_ERRORS, NULL);
1.1       misho     878:                if (outstream == NULL) {
1.1.1.2 ! misho     879:                        outstream = php_stream_open_wrapper(local, mode == FTPTYPE_ASCII ? "wt" : "wb", REPORT_ERRORS, NULL);
1.1       misho     880:                }
                    881:                if (outstream != NULL) {
                    882:                        /* if autoresume is wanted seek to end */
                    883:                        if (resumepos == PHP_FTP_AUTORESUME) {
                    884:                                php_stream_seek(outstream, 0, SEEK_END);
                    885:                                resumepos = php_stream_tell(outstream);
                    886:                        } else {
                    887:                                php_stream_seek(outstream, resumepos, SEEK_SET);
                    888:                        }
                    889:                }
                    890:        } else {
1.1.1.2 ! misho     891:                outstream = php_stream_open_wrapper(local, mode == FTPTYPE_ASCII ? "wt" : "wb", REPORT_ERRORS, NULL);
1.1       misho     892:        }
                    893: 
                    894:        if (outstream == NULL)  {
                    895:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error opening %s", local);
                    896:                RETURN_FALSE;
                    897:        }
                    898: 
                    899:        if (!ftp_get(ftp, outstream, remote, xtype, resumepos TSRMLS_CC)) {
                    900:                php_stream_close(outstream);
                    901:                VCWD_UNLINK(local);
                    902:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ftp->inbuf);
                    903:                RETURN_FALSE;
                    904:        }
                    905: 
                    906:        php_stream_close(outstream);
                    907:        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: {
                    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:        long            mode, resumepos=0;
                    922: 
                    923:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rssl|l", &z_ftp, &local, &local_len, &remote, &remote_len, &mode, &resumepos) == FAILURE) {
                    924:                return;
                    925:        }
                    926: 
                    927:        ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
                    928:        XTYPE(xtype, mode);
                    929: 
                    930:        /* ignore autoresume if autoseek is switched off */
                    931:        if (!ftp->autoseek && resumepos == PHP_FTP_AUTORESUME) {
                    932:                resumepos = 0;
                    933:        }
                    934: #ifdef PHP_WIN32
                    935:        mode = FTPTYPE_IMAGE;
                    936: #endif
                    937:        if (ftp->autoseek && resumepos) {
1.1.1.2 ! misho     938:                outstream = php_stream_open_wrapper(local, mode == FTPTYPE_ASCII ? "rt+" : "rb+", REPORT_ERRORS, NULL);
1.1       misho     939:                if (outstream == NULL) {
1.1.1.2 ! misho     940:                        outstream = php_stream_open_wrapper(local, mode == FTPTYPE_ASCII ? "wt" : "wb", REPORT_ERRORS, NULL);
1.1       misho     941:                }
                    942:                if (outstream != NULL) {
                    943:                        /* if autoresume is wanted seek to end */
                    944:                        if (resumepos == PHP_FTP_AUTORESUME) {
                    945:                                php_stream_seek(outstream, 0, SEEK_END);
                    946:                                resumepos = php_stream_tell(outstream);
                    947:                        } else {
                    948:                                php_stream_seek(outstream, resumepos, SEEK_SET);
                    949:                        }
                    950:                }
                    951:        } else {
1.1.1.2 ! misho     952:                outstream = php_stream_open_wrapper(local, mode == FTPTYPE_ASCII ? "wt" : "wb", REPORT_ERRORS, NULL);
1.1       misho     953:        }
                    954: 
                    955:        if (outstream == NULL)  {
                    956:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error opening %s", local);
                    957:                RETURN_FALSE;
                    958:        }
                    959: 
                    960:        /* configuration */
                    961:        ftp->direction = 0;   /* recv */
                    962:        ftp->closestream = 1; /* do close */
                    963: 
                    964:        if ((ret = ftp_nb_get(ftp, outstream, remote, xtype, resumepos TSRMLS_CC)) == PHP_FTP_FAILED) {
                    965:                php_stream_close(outstream);
                    966:                VCWD_UNLINK(local);
                    967:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ftp->inbuf);
                    968:                RETURN_LONG(PHP_FTP_FAILED);
                    969:        }
                    970: 
                    971:        if (ret == PHP_FTP_FINISHED) {
                    972:                php_stream_close(outstream);
                    973:        }
                    974: 
                    975:        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: {
                    983:        zval            *z_ftp;
                    984:        ftpbuf_t        *ftp;
                    985:        int             ret;
                    986: 
                    987:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &z_ftp) == FAILURE) {
                    988:                return;
                    989:        }
                    990: 
                    991:        ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
                    992: 
                    993:        if (!ftp->nb) {
                    994:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "no nbronous transfer to continue.");
                    995:                RETURN_LONG(PHP_FTP_FAILED);
                    996:        }
                    997: 
                    998:        if (ftp->direction) {
                    999:                ret=ftp_nb_continue_write(ftp TSRMLS_CC);
                   1000:        } else {
                   1001:                ret=ftp_nb_continue_read(ftp TSRMLS_CC);
                   1002:        }
                   1003: 
                   1004:        if (ret != PHP_FTP_MOREDATA && ftp->closestream) {
                   1005:                php_stream_close(ftp->stream);
                   1006:        }
                   1007: 
                   1008:        if (ret == PHP_FTP_FAILED) {
                   1009:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ftp->inbuf);
                   1010:        }
                   1011: 
                   1012:        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: {
                   1020:        zval            *z_ftp, *z_file;
                   1021:        ftpbuf_t        *ftp;
                   1022:        ftptype_t       xtype;
                   1023:        int             remote_len;
                   1024:        long            mode, startpos=0;
                   1025:        php_stream      *stream;
                   1026:        char            *remote;
                   1027: 
                   1028:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsrl|l", &z_ftp, &remote, &remote_len, &z_file, &mode, &startpos) == FAILURE) {
                   1029:                return;
                   1030:        }
                   1031: 
                   1032:        ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
                   1033:        php_stream_from_zval(stream, &z_file);
                   1034:        XTYPE(xtype, mode);
                   1035: 
                   1036:        /* ignore autoresume if autoseek is switched off */
                   1037:        if (!ftp->autoseek && startpos == PHP_FTP_AUTORESUME) {
                   1038:                startpos = 0;
                   1039:        }
                   1040: 
                   1041:        if (ftp->autoseek && startpos) {
                   1042:                /* if autoresume is wanted ask for remote size */
                   1043:                if (startpos == PHP_FTP_AUTORESUME) {
                   1044:                        startpos = ftp_size(ftp, remote);
                   1045:                        if (startpos < 0) {
                   1046:                                startpos = 0;
                   1047:                        }
                   1048:                }
                   1049:                if (startpos) {
                   1050:                        php_stream_seek(stream, startpos, SEEK_SET);
                   1051:                }
                   1052:        }
                   1053: 
                   1054:        if (!ftp_put(ftp, remote, stream, xtype, startpos TSRMLS_CC)) {
                   1055:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ftp->inbuf);
                   1056:                RETURN_FALSE;
                   1057:        }
                   1058: 
                   1059:        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: {
                   1067:        zval            *z_ftp, *z_file;
                   1068:        ftpbuf_t        *ftp;
                   1069:        ftptype_t       xtype;
                   1070:        int             remote_len, ret;
                   1071:        long            mode, startpos=0;
                   1072:        php_stream      *stream;
                   1073:        char            *remote;
                   1074: 
                   1075:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsrl|l", &z_ftp, &remote, &remote_len, &z_file, &mode, &startpos) == FAILURE) {
                   1076:                return;
                   1077:        }
                   1078: 
                   1079:        ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
                   1080:        php_stream_from_zval(stream, &z_file);
                   1081:        XTYPE(xtype, mode);
                   1082: 
                   1083:        /* ignore autoresume if autoseek is switched off */
                   1084:        if (!ftp->autoseek && startpos == PHP_FTP_AUTORESUME) {
                   1085:                startpos = 0;
                   1086:        }
                   1087: 
                   1088:        if (ftp->autoseek && startpos) {
                   1089:                /* if autoresume is wanted ask for remote size */
                   1090:                if (startpos == PHP_FTP_AUTORESUME) {
                   1091:                        startpos = ftp_size(ftp, remote);
                   1092:                        if (startpos < 0) {
                   1093:                                startpos = 0;
                   1094:                        }
                   1095:                }
                   1096:                if (startpos) {
                   1097:                        php_stream_seek(stream, startpos, SEEK_SET);
                   1098:                }
                   1099:        }
                   1100: 
                   1101:        /* configuration */
                   1102:        ftp->direction = 1;   /* send */
                   1103:        ftp->closestream = 0; /* do not close */
                   1104: 
                   1105:        if (((ret = ftp_nb_put(ftp, remote, stream, xtype, startpos TSRMLS_CC)) == PHP_FTP_FAILED)) {
                   1106:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ftp->inbuf);
                   1107:                RETURN_LONG(ret);
                   1108:        }
                   1109: 
                   1110:        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: {
                   1119:        zval            *z_ftp;
                   1120:        ftpbuf_t        *ftp;
                   1121:        ftptype_t       xtype;
                   1122:        char            *remote, *local;
                   1123:        int             remote_len, local_len;
                   1124:        long            mode, startpos=0;
                   1125:        php_stream      *instream;
                   1126: 
1.1.1.2 ! misho    1127:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rppl|l", &z_ftp, &remote, &remote_len, &local, &local_len, &mode, &startpos) == FAILURE) {
1.1       misho    1128:                return;
                   1129:        }
                   1130: 
                   1131:        ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
                   1132:        XTYPE(xtype, mode);
                   1133: 
1.1.1.2 ! misho    1134:        if (!(instream = php_stream_open_wrapper(local, mode == FTPTYPE_ASCII ? "rt" : "rb", REPORT_ERRORS, NULL))) {
1.1       misho    1135:                RETURN_FALSE;
                   1136:        }
                   1137: 
                   1138:        /* ignore autoresume if autoseek is switched off */
                   1139:        if (!ftp->autoseek && startpos == PHP_FTP_AUTORESUME) {
                   1140:                startpos = 0;
                   1141:        }
                   1142: 
                   1143:        if (ftp->autoseek && startpos) {
                   1144:                /* if autoresume is wanted ask for remote size */
                   1145:                if (startpos == PHP_FTP_AUTORESUME) {
                   1146:                        startpos = ftp_size(ftp, remote);
                   1147:                        if (startpos < 0) {
                   1148:                                startpos = 0;
                   1149:                        }
                   1150:                }
                   1151:                if (startpos) {
                   1152:                        php_stream_seek(instream, startpos, SEEK_SET);
                   1153:                }
                   1154:        }
                   1155: 
                   1156:        if (!ftp_put(ftp, remote, instream, xtype, startpos TSRMLS_CC)) {
                   1157:                php_stream_close(instream);
                   1158:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ftp->inbuf);
                   1159:                RETURN_FALSE;
                   1160:        }
                   1161:        php_stream_close(instream);
                   1162: 
                   1163:        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: {
                   1172:        zval            *z_ftp;
                   1173:        ftpbuf_t        *ftp;
                   1174:        ftptype_t       xtype;
                   1175:        char            *remote, *local;
                   1176:        int             remote_len, local_len, ret;
                   1177:        long            mode, startpos=0;
                   1178:        php_stream      *instream;
                   1179: 
1.1.1.2 ! misho    1180:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rppl|l", &z_ftp, &remote, &remote_len, &local, &local_len, &mode, &startpos) == FAILURE) {
1.1       misho    1181:                return;
                   1182:        }
                   1183: 
                   1184:        ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
                   1185:        XTYPE(xtype, mode);
                   1186: 
1.1.1.2 ! misho    1187:        if (!(instream = php_stream_open_wrapper(local, mode == FTPTYPE_ASCII ? "rt" : "rb", REPORT_ERRORS, NULL))) {
1.1       misho    1188:                RETURN_FALSE;
                   1189:        }
                   1190: 
                   1191:        /* ignore autoresume if autoseek is switched off */
                   1192:        if (!ftp->autoseek && startpos == PHP_FTP_AUTORESUME) {
                   1193:                startpos = 0;
                   1194:        }
                   1195: 
                   1196:        if (ftp->autoseek && startpos) {
                   1197:                /* if autoresume is wanted ask for remote size */
                   1198:                if (startpos == PHP_FTP_AUTORESUME) {
                   1199:                        startpos = ftp_size(ftp, remote);
                   1200:                        if (startpos < 0) {
                   1201:                                startpos = 0;
                   1202:                        }
                   1203:                }
                   1204:                if (startpos) {
                   1205:                        php_stream_seek(instream, startpos, SEEK_SET);
                   1206:                }
                   1207:        }
                   1208: 
                   1209:        /* configuration */
                   1210:        ftp->direction = 1;   /* send */
                   1211:        ftp->closestream = 1; /* do close */
                   1212: 
                   1213:        ret = ftp_nb_put(ftp, remote, instream, xtype, startpos TSRMLS_CC);
                   1214: 
                   1215:        if (ret != PHP_FTP_MOREDATA) {
                   1216:                php_stream_close(instream);
                   1217:        }
                   1218: 
                   1219:        if (ret == PHP_FTP_FAILED) {
                   1220:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ftp->inbuf);
                   1221:        }
                   1222: 
                   1223:        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: {
                   1231:        zval            *z_ftp;
                   1232:        ftpbuf_t        *ftp;
                   1233:        char            *file;
                   1234:        int             file_len;
                   1235: 
1.1.1.2 ! misho    1236:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rp", &z_ftp, &file, &file_len) == FAILURE) {
1.1       misho    1237:                return;
                   1238:        }
                   1239: 
                   1240:        ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
                   1241: 
                   1242:        /* get file size */
                   1243:        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: {
                   1251:        zval            *z_ftp;
                   1252:        ftpbuf_t        *ftp;
                   1253:        char            *file;
                   1254:        int             file_len;
                   1255: 
1.1.1.2 ! misho    1256:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rp", &z_ftp, &file, &file_len) == FAILURE) {
1.1       misho    1257:                return;
                   1258:        }
                   1259: 
                   1260:        ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
                   1261: 
                   1262:        /* get file mod time */
                   1263:        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: {
                   1271:        zval            *z_ftp;
                   1272:        ftpbuf_t        *ftp;
                   1273:        char            *src, *dest;
                   1274:        int             src_len, dest_len;
                   1275: 
                   1276:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rss", &z_ftp, &src, &src_len, &dest, &dest_len) == FAILURE) {
                   1277:                return;
                   1278:        }
                   1279: 
                   1280:        ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
                   1281: 
                   1282:        /* rename the file */
                   1283:        if (!ftp_rename(ftp, src, dest)) {
                   1284:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ftp->inbuf);
                   1285:                RETURN_FALSE;
                   1286:        }
                   1287: 
                   1288:        RETURN_TRUE;
                   1289: }
                   1290: /* }}} */
                   1291: 
                   1292: /* {{{ proto bool ftp_delete(resource stream, string file)
                   1293:    Deletes a file */
                   1294: PHP_FUNCTION(ftp_delete)
                   1295: {
                   1296:        zval            *z_ftp;
                   1297:        ftpbuf_t        *ftp;
                   1298:        char            *file;
                   1299:        int             file_len;
                   1300: 
                   1301:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &z_ftp, &file, &file_len) == FAILURE) {
                   1302:                return;
                   1303:        }
                   1304: 
                   1305:        ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
                   1306: 
                   1307:        /* delete the file */
                   1308:        if (!ftp_delete(ftp, file)) {
                   1309:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ftp->inbuf);
                   1310:                RETURN_FALSE;
                   1311:        }
                   1312: 
                   1313:        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: {
                   1321:        zval            *z_ftp;
                   1322:        ftpbuf_t        *ftp;
                   1323:        char            *cmd;
                   1324:        int             cmd_len;
                   1325: 
                   1326:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &z_ftp, &cmd, &cmd_len) == FAILURE) {
                   1327:                return;
                   1328:        }
                   1329: 
                   1330:        ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
                   1331: 
                   1332:        /* send the site command */
                   1333:        if (!ftp_site(ftp, cmd)) {
                   1334:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ftp->inbuf);
                   1335:                RETURN_FALSE;
                   1336:        }
                   1337: 
                   1338:        RETURN_TRUE;
                   1339: }
                   1340: /* }}} */
                   1341: 
                   1342: /* {{{ proto bool ftp_close(resource stream)
                   1343:    Closes the FTP stream */
                   1344: PHP_FUNCTION(ftp_close)
                   1345: {
                   1346:        zval            *z_ftp;
                   1347:        ftpbuf_t        *ftp;
                   1348: 
                   1349:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &z_ftp) == FAILURE) {
                   1350:                return;
                   1351:        }
                   1352: 
                   1353:        ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
                   1354: 
                   1355:        ftp_quit(ftp);
                   1356: 
                   1357:        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: {
                   1365:        zval            *z_ftp, *z_value;
                   1366:        long            option;
                   1367:        ftpbuf_t        *ftp;
                   1368: 
                   1369:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rlz", &z_ftp, &option, &z_value) == FAILURE) {
                   1370:                return;
                   1371:        }
                   1372: 
                   1373:        ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
                   1374: 
                   1375:        switch (option) {
                   1376:                case PHP_FTP_OPT_TIMEOUT_SEC:
                   1377:                        if (Z_TYPE_P(z_value) != IS_LONG) {
                   1378:                                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:                                RETURN_FALSE;
                   1381:                        }
                   1382:                        if (Z_LVAL_P(z_value) <= 0) {
                   1383:                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Timeout has to be greater than 0");
                   1384:                                RETURN_FALSE;
                   1385:                        }
                   1386:                        ftp->timeout_sec = Z_LVAL_P(z_value);
                   1387:                        RETURN_TRUE;
                   1388:                        break;
                   1389:                case PHP_FTP_OPT_AUTOSEEK:
                   1390:                        if (Z_TYPE_P(z_value) != IS_BOOL) {
                   1391:                                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:                                RETURN_FALSE;
                   1394:                        }
                   1395:                        ftp->autoseek = Z_LVAL_P(z_value);
                   1396:                        RETURN_TRUE;
                   1397:                        break;
                   1398:                default:
                   1399:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown option '%ld'", option);
                   1400:                        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: {
                   1410:        zval            *z_ftp;
                   1411:        long            option;
                   1412:        ftpbuf_t        *ftp;
                   1413: 
                   1414:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &z_ftp, &option) == FAILURE) {
                   1415:                return;
                   1416:        }
                   1417: 
                   1418:        ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
                   1419: 
                   1420:        switch (option) {
                   1421:                case PHP_FTP_OPT_TIMEOUT_SEC:
                   1422:                        RETURN_LONG(ftp->timeout_sec);
                   1423:                        break;
                   1424:                case PHP_FTP_OPT_AUTOSEEK:
                   1425:                        RETURN_BOOL(ftp->autoseek);
                   1426:                        break;
                   1427:                default:
                   1428:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown option '%ld'", option);
                   1429:                        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:  */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>