~ubuntu-branches/ubuntu/hardy/php5/hardy-updates

« back to all changes in this revision

Viewing changes to ext/ftp/php_ftp.c

  • Committer: Bazaar Package Importer
  • Author(s): Adam Conrad
  • Date: 2005-10-09 03:14:32 UTC
  • Revision ID: james.westby@ubuntu.com-20051009031432-kspik3lobxstafv9
Tags: upstream-5.0.5
ImportĀ upstreamĀ versionĀ 5.0.5

Show diffs side-by-side

added added

removed removed

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