summaryrefslogtreecommitdiff
path: root/ext/ftp/php_ftp.c
diff options
context:
space:
mode:
authorStefan Esser <sesser@php.net>2002-07-26 22:00:25 +0000
committerStefan Esser <sesser@php.net>2002-07-26 22:00:25 +0000
commit80e9724ccccf48c477cd21c80406335b472c1cb4 (patch)
treef1a46a521a53d29e5910d63ecec41d1ba2cd6999 /ext/ftp/php_ftp.c
parent8b853592b156768708274b25e20b11c6c05e05ab (diff)
downloadphp-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.c270
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)