diff options
author | Stefan Esser <sesser@php.net> | 2002-07-26 22:00:25 +0000 |
---|---|---|
committer | Stefan Esser <sesser@php.net> | 2002-07-26 22:00:25 +0000 |
commit | 80e9724ccccf48c477cd21c80406335b472c1cb4 (patch) | |
tree | f1a46a521a53d29e5910d63ecec41d1ba2cd6999 /ext/ftp/php_ftp.c | |
parent | 8b853592b156768708274b25e20b11c6c05e05ab (diff) | |
download | php-git-80e9724ccccf48c477cd21c80406335b472c1cb4.tar.gz |
[EXPERIMENTAL] Added functions for asynchronous FTP transfers
Diffstat (limited to 'ext/ftp/php_ftp.c')
-rw-r--r-- | ext/ftp/php_ftp.c | 270 |
1 files changed, 269 insertions, 1 deletions
diff --git a/ext/ftp/php_ftp.c b/ext/ftp/php_ftp.c index cc51a84ffe..1dac9e3443 100644 --- a/ext/ftp/php_ftp.c +++ b/ext/ftp/php_ftp.c @@ -61,6 +61,11 @@ function_entry php_ftp_functions[] = { PHP_FE(ftp_close, NULL) PHP_FE(ftp_set_option, NULL) PHP_FE(ftp_get_option, NULL) + PHP_FE(ftp_async_fget, NULL) + PHP_FE(ftp_async_get, NULL) + PHP_FE(ftp_async_continue, NULL) + PHP_FE(ftp_async_put, NULL) + PHP_FE(ftp_async_fput, NULL) PHP_FALIAS(ftp_quit, ftp_close, NULL) {NULL, NULL, NULL} }; @@ -99,6 +104,9 @@ PHP_MINIT_FUNCTION(ftp) REGISTER_LONG_CONSTANT("FTP_AUTORESUME", PHP_FTP_AUTORESUME, CONST_PERSISTENT | CONST_CS); REGISTER_LONG_CONSTANT("FTP_TIMEOUT_SEC", PHP_FTP_OPT_TIMEOUT_SEC, CONST_PERSISTENT | CONST_CS); REGISTER_LONG_CONSTANT("FTP_AUTOSEEK", PHP_FTP_OPT_AUTOSEEK, CONST_PERSISTENT | CONST_CS); + REGISTER_LONG_CONSTANT("FTP_FAILED", PHP_FTP_FAILED, CONST_PERSISTENT | CONST_CS); + REGISTER_LONG_CONSTANT("FTP_FINISHED", PHP_FTP_FINISHED, CONST_PERSISTENT | CONST_CS); + REGISTER_LONG_CONSTANT("FTP_MOREDATA", PHP_FTP_MOREDATA, CONST_PERSISTENT | CONST_CS); return SUCCESS; } @@ -448,6 +456,53 @@ PHP_FUNCTION(ftp_fget) } /* }}} */ +/* {{{ proto bool ftp_async_fget(resource stream, resource fp, string remote_file, int mode[, int resumepos]) + Retrieves a file from the FTP server asynchronly and writes it to an open file */ +PHP_FUNCTION(ftp_async_fget) +{ + zval *z_ftp, *z_file; + ftpbuf_t *ftp; + ftptype_t xtype; + php_stream *stream; + char *file; + int file_len, mode, resumepos=0, ret; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rrsl|l", &z_ftp, &z_file, &file, &file_len, &mode, &resumepos) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf); + ZEND_FETCH_RESOURCE(stream, php_stream*, &z_file, -1, "File-Handle", php_file_le_stream()); + XTYPE(xtype, mode); + + /* ignore autoresume if autoseek is switched off */ + if (!ftp->autoseek && resumepos == PHP_FTP_AUTORESUME) { + resumepos = 0; + } + + if (ftp->autoseek && resumepos) { + /* if autoresume is wanted seek to end */ + if (resumepos == PHP_FTP_AUTORESUME) { + php_stream_seek(stream, 0, SEEK_END); + resumepos = php_stream_tell(stream); + } else { + php_stream_seek(stream, resumepos, SEEK_SET); + } + } + + /* configuration */ + ftp->direction = 0; /* recv */ + ftp->closestream = 0; /* do not close */ + + if ((ret = ftp_async_get(ftp, stream, file, xtype, resumepos)) == PHP_FTP_FAILED || php_stream_error(stream)) { + php_error(E_WARNING, "%s(): %s", get_active_function_name(TSRMLS_C), ftp->inbuf); + RETURN_LONG(ret); + } + + RETURN_LONG(ret); +} +/* }}} */ + /* {{{ proto bool ftp_pasv(resource stream, bool pasv) Turns passive mode on or off */ PHP_FUNCTION(ftp_pasv) @@ -526,6 +581,107 @@ PHP_FUNCTION(ftp_get) } /* }}} */ +/* {{{ proto inf ftp_async_get(resource stream, string local_file, string remote_file, int mode[, int resume_pos]) + Retrieves a file from the FTP server asynchronly and writes it to a local file */ +PHP_FUNCTION(ftp_async_get) +{ + zval *z_ftp; + ftpbuf_t *ftp; + ftptype_t xtype; + php_stream *outstream; + char *local, *remote; + int local_len, remote_len, mode, resumepos=0, ret; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rssl|l", &z_ftp, &local, &local_len, &remote, &remote_len, &mode, &resumepos) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf); + XTYPE(xtype, mode); + + /* ignore autoresume if autoseek is switched off */ + if (!ftp->autoseek && resumepos == PHP_FTP_AUTORESUME) { + resumepos = 0; + } + + if (ftp->autoseek && resumepos) { + outstream = php_stream_fopen(local, "rb+", NULL); + if (outstream == NULL) { + outstream = php_stream_fopen(local, "wb", NULL); + } + if (outstream != NULL) { + /* if autoresume is wanted seek to end */ + if (resumepos == PHP_FTP_AUTORESUME) { + php_stream_seek(outstream, 0, SEEK_END); + resumepos = php_stream_tell(outstream); + } else { + php_stream_seek(outstream, resumepos, SEEK_SET); + } + } + } else { + outstream = php_stream_fopen(local, "wb", NULL); + } + + if (outstream == NULL) { + php_error(E_WARNING, "%s(): Error opening %s", get_active_function_name(TSRMLS_C), local); + RETURN_FALSE; + } + + /* configuration */ + ftp->direction = 0; /* recv */ + ftp->closestream = 1; /* do close */ + + if ((ret = ftp_async_get(ftp, outstream, remote, xtype, resumepos)) == PHP_FTP_FAILED || php_stream_error(outstream)) { + php_stream_close(outstream); + php_error(E_WARNING, "%s(): %s", get_active_function_name(TSRMLS_C), ftp->inbuf); + RETURN_LONG(PHP_FTP_FAILED); + } + + if (ret == PHP_FTP_FINISHED) { + php_stream_close(outstream); + } + + RETURN_LONG(ret); +} +/* }}} */ + +/* {{{ proto int ftp_async_continue(resource stream) + Continues retrieving/sending a file asyncronously */ +PHP_FUNCTION(ftp_async_continue) +{ + zval *z_ftp; + ftpbuf_t *ftp; + int ret; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &z_ftp) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf); + + if (!ftp->async) { + php_error(E_WARNING, "%s(): no asyncronous transfer to continue.", get_active_function_name(TSRMLS_C)); + RETURN_LONG(PHP_FTP_FAILED); + } + + if (ftp->direction) { + ret=ftp_async_continue_write(ftp); + } else { + ret=ftp_async_continue_read(ftp); + } + + if (ret != PHP_FTP_MOREDATA && ftp->closestream) { + php_stream_close(ftp->stream); + } + + if (ret == PHP_FTP_FAILED || php_stream_error(ftp->stream)) { + php_error(E_WARNING, "%s(): %s", get_active_function_name(TSRMLS_C), ftp->inbuf); + } + + RETURN_LONG(ret); +} +/* }}} */ + /* {{{ proto bool ftp_fput(resource stream, string remote_file, resource fp, int mode[, int startpos]) Stores a file from an open file to the FTP server */ PHP_FUNCTION(ftp_fput) @@ -572,6 +728,57 @@ PHP_FUNCTION(ftp_fput) } /* }}} */ +/* {{{ proto bool ftp_async_fput(resource stream, string remote_file, resource fp, int mode[, int startpos]) + Stores a file from an open file to the FTP server asyncronly */ +PHP_FUNCTION(ftp_async_fput) +{ + zval *z_ftp, *z_file; + ftpbuf_t *ftp; + ftptype_t xtype; + int mode, remote_len, startpos=0, ret; + php_stream *stream; + char *remote; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsrl|l", &z_ftp, &remote, &remote_len, &z_file, &mode, &startpos) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf); + ZEND_FETCH_RESOURCE(stream, php_stream*, &z_file, -1, "File-Handle", php_file_le_stream()); + XTYPE(xtype, mode); + + /* ignore autoresume if autoseek is switched off */ + if (!ftp->autoseek && startpos == PHP_FTP_AUTORESUME) { + startpos = 0; + } + + if (ftp->autoseek && startpos) { + /* if autoresume is wanted ask for remote size */ + if (startpos == PHP_FTP_AUTORESUME) { + startpos = ftp_size(ftp, remote); + if (startpos < 0) { + startpos = 0; + } + } + if (startpos) { + php_stream_seek(stream, startpos, SEEK_SET); + } + } + + /* configuration */ + ftp->direction = 1; /* send */ + ftp->closestream = 0; /* do not close */ + + if (((ret = ftp_async_put(ftp, remote, stream, xtype, startpos)) == PHP_FTP_FAILED) || php_stream_error(stream)) { + php_error(E_WARNING, "%s(): %s", get_active_function_name(TSRMLS_C), ftp->inbuf); + RETURN_LONG(ret); + } + + RETURN_LONG(ret); +} +/* }}} */ + + /* {{{ proto bool ftp_put(resource stream, string remote_file, string local_file, int mode[, int startpos]) Stores a file on the FTP server */ PHP_FUNCTION(ftp_put) @@ -580,7 +787,7 @@ PHP_FUNCTION(ftp_put) ftpbuf_t *ftp; ftptype_t xtype; char *remote, *local; - int remote_len, local_len, mode, startpos=0; + int remote_len, local_len, mode, startpos=0, ret; php_stream * instream; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rssl|l", &z_ftp, &remote, &remote_len, &local, &local_len, &mode, &startpos) == FAILURE) { @@ -625,6 +832,67 @@ PHP_FUNCTION(ftp_put) } /* }}} */ + +/* {{{ proto bool ftp_async_put(resource stream, string remote_file, string local_file, int mode[, int startpos]) + Stores a file on the FTP server */ +PHP_FUNCTION(ftp_async_put) +{ + zval *z_ftp; + ftpbuf_t *ftp; + ftptype_t xtype; + char *remote, *local; + int remote_len, local_len, mode, startpos=0, ret; + php_stream * instream; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rssl|l", &z_ftp, &remote, &remote_len, &local, &local_len, &mode, &startpos) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf); + XTYPE(xtype, mode); + + instream = php_stream_fopen(local, "rb", NULL); + + if (instream == NULL) { + RETURN_FALSE; + } + + /* ignore autoresume if autoseek is switched off */ + if (!ftp->autoseek && startpos == PHP_FTP_AUTORESUME) { + startpos = 0; + } + + if (ftp->autoseek && startpos) { + /* if autoresume is wanted ask for remote size */ + if (startpos == PHP_FTP_AUTORESUME) { + startpos = ftp_size(ftp, remote); + if (startpos < 0) { + startpos = 0; + } + } + if (startpos) { + php_stream_seek(instream, startpos, SEEK_SET); + } + } + + /* configuration */ + ftp->direction = 1; /* send */ + ftp->closestream = 1; /* do close */ + + ret = ftp_async_put(ftp, remote, instream, xtype, startpos); + + if (ret != PHP_FTP_MOREDATA) { + php_stream_close(instream); + } + + if (ret == PHP_FTP_FAILED || php_stream_error(instream)) { + php_error(E_WARNING, "%s(): %s", get_active_function_name(TSRMLS_C), ftp->inbuf); + } + + RETURN_LONG(ret); +} +/* }}} */ + /* {{{ proto int ftp_size(resource stream, string filename) Returns the size of the file, or -1 on error */ PHP_FUNCTION(ftp_size) |