diff options
author | Andreas Streichardt <andreas.streichardt@gmail.com> | 2012-10-12 11:02:33 +0200 |
---|---|---|
committer | Stanislav Malyshev <stas@php.net> | 2013-08-04 19:31:30 -0700 |
commit | a93a462dcefd62e07963dd2da506fbb3409c88b5 (patch) | |
tree | 84cf579dfe9f2bd1e0cf35108f7de975071ad069 /ext/ftp | |
parent | 8d86597d7368460383a33a4399ea7a8b244cd6fa (diff) | |
download | php-git-a93a462dcefd62e07963dd2da506fbb3409c88b5.tar.gz |
First fixes for a 64bit compatible ftp extension
Diffstat (limited to 'ext/ftp')
-rw-r--r-- | ext/ftp/ftp.c | 54 | ||||
-rw-r--r-- | ext/ftp/ftp.h | 12 | ||||
-rw-r--r-- | ext/ftp/php_ftp.c | 16 | ||||
-rw-r--r-- | ext/ftp/tests/filesize_large.phpt | 23 | ||||
-rw-r--r-- | ext/ftp/tests/ftp_nb_get_large.phpt | 36 | ||||
-rw-r--r-- | ext/ftp/tests/server.inc | 23 |
6 files changed, 107 insertions, 57 deletions
diff --git a/ext/ftp/ftp.c b/ext/ftp/ftp.c index dd41f02704..0d6704f9d2 100644 --- a/ext/ftp/ftp.c +++ b/ext/ftp/ftp.c @@ -612,7 +612,7 @@ ftp_chmod(ftpbuf_t *ftp, const int mode, const char *filename, const int filenam /* {{{ ftp_alloc */ int -ftp_alloc(ftpbuf_t *ftp, const int size, char **response) +ftp_alloc(ftpbuf_t *ftp, const long size, char **response) { char buffer[64]; @@ -620,8 +620,8 @@ ftp_alloc(ftpbuf_t *ftp, const int size, char **response) return 0; } - snprintf(buffer, sizeof(buffer) - 1, "%d", size); - + snprintf(buffer, sizeof(buffer) - 1, "%ld", size); + if (!ftp_putcmd(ftp, "ALLO", buffer)) { return 0; } @@ -787,7 +787,7 @@ ftp_pasv(ftpbuf_t *ftp, int pasv) /* {{{ ftp_get */ int -ftp_get(ftpbuf_t *ftp, php_stream *outstream, const char *path, ftptype_t type, int resumepos TSRMLS_DC) +ftp_get(ftpbuf_t *ftp, php_stream *outstream, const char *path, ftptype_t type, long resumepos TSRMLS_DC) { databuf_t *data = NULL; int lastch; @@ -808,11 +808,7 @@ ftp_get(ftpbuf_t *ftp, php_stream *outstream, const char *path, ftptype_t type, ftp->data = data; if (resumepos > 0) { - if (resumepos > 2147483647) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "PHP cannot handle files greater than 2147483647 bytes."); - goto bail; - } - snprintf(arg, sizeof(arg), "%u", resumepos); + snprintf(arg, sizeof(arg), "%ld", resumepos); if (!ftp_putcmd(ftp, "REST", arg)) { goto bail; } @@ -885,10 +881,10 @@ bail: /* {{{ ftp_put */ int -ftp_put(ftpbuf_t *ftp, const char *path, php_stream *instream, ftptype_t type, int startpos TSRMLS_DC) +ftp_put(ftpbuf_t *ftp, const char *path, php_stream *instream, ftptype_t type, long startpos TSRMLS_DC) { databuf_t *data = NULL; - int size; + long size; char *ptr; int ch; char arg[11]; @@ -905,11 +901,7 @@ ftp_put(ftpbuf_t *ftp, const char *path, php_stream *instream, ftptype_t type, i ftp->data = data; if (startpos > 0) { - if (startpos > 2147483647) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "PHP cannot handle files with a size greater than 2147483647 bytes."); - goto bail; - } - snprintf(arg, sizeof(arg), "%u", startpos); + snprintf(arg, sizeof(arg), "%ld", startpos); if (!ftp_putcmd(ftp, "REST", arg)) { goto bail; } @@ -966,7 +958,7 @@ bail: /* {{{ ftp_size */ -int +long ftp_size(ftpbuf_t *ftp, const char *path) { if (ftp == NULL) { @@ -981,7 +973,7 @@ ftp_size(ftpbuf_t *ftp, const char *path) if (!ftp_getresp(ftp) || ftp->resp != 213) { return -1; } - return atoi(ftp->inbuf); + return atol(ftp->inbuf); } /* }}} */ @@ -1143,7 +1135,7 @@ ftp_putcmd(ftpbuf_t *ftp, const char *cmd, const char *args) int ftp_readline(ftpbuf_t *ftp) { - int size, rcvd; + long size, rcvd; char *data, *eol; /* shift the extra to the front */ @@ -1236,7 +1228,8 @@ ftp_getresp(ftpbuf_t *ftp) int my_send(ftpbuf_t *ftp, php_socket_t s, void *buf, size_t len) { - int n, size, sent; + long size, sent; + int n; size = len; while (size) { @@ -1719,7 +1712,7 @@ bail: /* {{{ ftp_nb_get */ int -ftp_nb_get(ftpbuf_t *ftp, php_stream *outstream, const char *path, ftptype_t type, int resumepos TSRMLS_DC) +ftp_nb_get(ftpbuf_t *ftp, php_stream *outstream, const char *path, ftptype_t type, long resumepos TSRMLS_DC) { databuf_t *data = NULL; char arg[11]; @@ -1737,14 +1730,7 @@ ftp_nb_get(ftpbuf_t *ftp, php_stream *outstream, const char *path, ftptype_t typ } if (resumepos>0) { - /* We are working on an architecture that supports 64-bit integers - * since php is 32 bit by design, we bail out with warning - */ - if (resumepos > 2147483647) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "PHP cannot handle files greater than 2147483648 bytes."); - goto bail; - } - snprintf(arg, sizeof(arg), "%u", resumepos); + snprintf(arg, sizeof(arg), "%ld", resumepos); if (!ftp_putcmd(ftp, "REST", arg)) { goto bail; } @@ -1843,7 +1829,7 @@ bail: /* {{{ ftp_nb_put */ int -ftp_nb_put(ftpbuf_t *ftp, const char *path, php_stream *instream, ftptype_t type, int startpos TSRMLS_DC) +ftp_nb_put(ftpbuf_t *ftp, const char *path, php_stream *instream, ftptype_t type, long startpos TSRMLS_DC) { databuf_t *data = NULL; char arg[11]; @@ -1858,11 +1844,7 @@ ftp_nb_put(ftpbuf_t *ftp, const char *path, php_stream *instream, ftptype_t type goto bail; } if (startpos > 0) { - if (startpos > 2147483647) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "PHP cannot handle files with a size greater than 2147483647 bytes."); - goto bail; - } - snprintf(arg, sizeof(arg), "%u", startpos); + snprintf(arg, sizeof(arg), "%ld", startpos); if (!ftp_putcmd(ftp, "REST", arg)) { goto bail; } @@ -1899,7 +1881,7 @@ bail: int ftp_nb_continue_write(ftpbuf_t *ftp TSRMLS_DC) { - int size; + long size; char *ptr; int ch; diff --git a/ext/ftp/ftp.h b/ext/ftp/ftp.h index c7db45789a..69de7dbb78 100644 --- a/ext/ftp/ftp.h +++ b/ext/ftp/ftp.h @@ -146,7 +146,7 @@ int ftp_chmod(ftpbuf_t *ftp, const int mode, const char *filename, const int fi * however some servers will not accept STOR or APPE until ALLO is confirmed. * If response is passed, it is estrdup()ed from ftp->inbuf and must be freed * or assigned to a zval returned to the user */ -int ftp_alloc(ftpbuf_t *ftp, const int size, char **response); +int ftp_alloc(ftpbuf_t *ftp, const long size, char **response); /* returns a NULL-terminated array of filenames in the given path * or NULL on error. the return array must be freed (but don't @@ -169,15 +169,15 @@ int ftp_pasv(ftpbuf_t *ftp, int pasv); /* retrieves a file and saves its contents to outfp * returns true on success, false on error */ -int ftp_get(ftpbuf_t *ftp, php_stream *outstream, const char *path, ftptype_t type, int resumepos TSRMLS_DC); +int ftp_get(ftpbuf_t *ftp, php_stream *outstream, const char *path, ftptype_t type, long resumepos TSRMLS_DC); /* stores the data from a file, socket, or process as a file on the remote server * returns true on success, false on error */ -int ftp_put(ftpbuf_t *ftp, const char *path, php_stream *instream, ftptype_t type, int startpos TSRMLS_DC); +int ftp_put(ftpbuf_t *ftp, const char *path, php_stream *instream, ftptype_t type, long startpos TSRMLS_DC); /* returns the size of the given file, or -1 on error */ -int ftp_size(ftpbuf_t *ftp, const char *path); +long ftp_size(ftpbuf_t *ftp, const char *path); /* returns the last modified time of the given file, or -1 on error */ time_t ftp_mdtm(ftpbuf_t *ftp, const char *path); @@ -194,12 +194,12 @@ int ftp_site(ftpbuf_t *ftp, const char *cmd); /* retrieves part of a file and saves its contents to outfp * returns true on success, false on error */ -int ftp_nb_get(ftpbuf_t *ftp, php_stream *outstream, const char *path, ftptype_t type, int resumepos TSRMLS_DC); +int ftp_nb_get(ftpbuf_t *ftp, php_stream *outstream, const char *path, ftptype_t type, long resumepos TSRMLS_DC); /* stores the data from a file, socket, or process as a file on the remote server * returns true on success, false on error */ -int ftp_nb_put(ftpbuf_t *ftp, const char *path, php_stream *instream, ftptype_t type, int startpos TSRMLS_DC); +int ftp_nb_put(ftpbuf_t *ftp, const char *path, php_stream *instream, ftptype_t type, long startpos TSRMLS_DC); /* continues a previous nb_(f)get command */ diff --git a/ext/ftp/php_ftp.c b/ext/ftp/php_ftp.c index 73071936e0..da22e0b63e 100644 --- a/ext/ftp/php_ftp.c +++ b/ext/ftp/php_ftp.c @@ -784,8 +784,8 @@ PHP_FUNCTION(ftp_nb_fget) ftptype_t xtype; php_stream *stream; char *file; - int file_len, ret; - long mode, resumepos=0; + int file_len; + long 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; @@ -968,9 +968,7 @@ PHP_FUNCTION(ftp_nb_get) RETURN_LONG(PHP_FTP_FAILED); } - if (ret == PHP_FTP_FINISHED) { - php_stream_close(outstream); - } + php_stream_close(outstream); RETURN_LONG(ret); } @@ -982,7 +980,7 @@ PHP_FUNCTION(ftp_nb_continue) { zval *z_ftp; ftpbuf_t *ftp; - int ret; + long ret; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &z_ftp) == FAILURE) { return; @@ -1120,7 +1118,7 @@ PHP_FUNCTION(ftp_put) ftpbuf_t *ftp; ftptype_t xtype; char *remote, *local; - int remote_len, local_len; + long remote_len, local_len; long mode, startpos=0; php_stream *instream; @@ -1173,8 +1171,8 @@ PHP_FUNCTION(ftp_nb_put) ftpbuf_t *ftp; ftptype_t xtype; char *remote, *local; - int remote_len, local_len, ret; - long mode, startpos=0; + int remote_len, local_len; + long mode, startpos=0, ret; php_stream *instream; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rppl|l", &z_ftp, &remote, &remote_len, &local, &local_len, &mode, &startpos) == FAILURE) { diff --git a/ext/ftp/tests/filesize_large.phpt b/ext/ftp/tests/filesize_large.phpt new file mode 100644 index 0000000000..05f12a3e5b --- /dev/null +++ b/ext/ftp/tests/filesize_large.phpt @@ -0,0 +1,23 @@ +--TEST-- +Verify php can handle filesizes >32bit +--SKIPIF-- +<?php +require 'skipif.inc'; +if (2147483647 == PHP_INT_MAX) { + die('skip 64-bit only'); +} +?> +--FILE-- +<?php +require 'server.inc'; + +$ftp = ftp_connect('127.0.0.1', $port); +if (!$ftp) die("Couldn't connect to the server"); + +ftp_login($ftp, 'user', 'pass'); +var_dump(ftp_size($ftp, 'largefile')); + +ftp_close($ftp); +?> +--EXPECT-- +int(5368709120) diff --git a/ext/ftp/tests/ftp_nb_get_large.phpt b/ext/ftp/tests/ftp_nb_get_large.phpt new file mode 100644 index 0000000000..3fbf2a4831 --- /dev/null +++ b/ext/ftp/tests/ftp_nb_get_large.phpt @@ -0,0 +1,36 @@ +--TEST-- +Testing ftp_nb_fget can handle large files incl. resume +--SKIPIF-- +<?php +require 'skipif.inc'; +if (2147483647 == PHP_INT_MAX) { + die('skip ot supported on this system'); +} +if (disk_free_space(__DIR__) < 10*1024*1024*1024) { + die('not enough disk space'); +} +?> +--FILE-- +<?php +require 'server.inc'; + +$ftp = ftp_connect('127.0.0.1', $port); +ftp_login($ftp, 'user', 'pass'); +if (!$ftp) die("Couldn't connect to the server"); + +$local_file = dirname(__FILE__) . DIRECTORY_SEPARATOR . "localfile.txt"; +touch($local_file); +ftp_nb_get($ftp, $local_file, 'fget_large.txt', FTP_BINARY, 5368709119); +$fp = fopen($local_file, 'r'); +fseek($fp, 5368709119); +var_dump(fread($fp, 1)); +var_dump(filesize($local_file)); +fclose($fp); +?> +--CLEAN-- +<?php +@unlink(dirname(__FILE__) . DIRECTORY_SEPARATOR . "localfile.txt"); +?> +--EXPECT-- +string(1) "X" +int(5368709120) diff --git a/ext/ftp/tests/server.inc b/ext/ftp/tests/server.inc index 8617880623..7dc8fa08d9 100644 --- a/ext/ftp/tests/server.inc +++ b/ext/ftp/tests/server.inc @@ -357,7 +357,17 @@ if ($pid) { $transfer_type = $ascii? 'ASCII' : 'BINARY' ; fputs($fs, "Bar\r\n"); fputs($s, "226 Closing data Connection.\r\n"); - break; + break; + case "fget_large": + fputs($s, "150 File status okay; about to open data connection.\r\n"); + $transfer_type = $ascii? 'ASCII' : 'BINARY' ; + if ($GLOBALS['rest_pos'] == '5368709119') { + fputs($fs, "X"); + } else { + fputs($fs, "Y"); + } + fputs($s, "226 Closing data Connection.\r\n"); + break; default: fputs($s, "550 {$matches[1]}: No such file or directory \r\n"); break; @@ -393,11 +403,12 @@ if ($pid) { }elseif (preg_match('/^LIST no_exists\//', $buf, $matches)) { fputs($s, "425 Error establishing connection\r\n"); - }elseif (preg_match('/^REST \d+/', $buf, $matches)) { + }elseif (preg_match('/^REST (\d+)/', $buf, $matches)) { + $GLOBALS['rest_pos'] = $matches[1]; fputs($s, "350 OK\r\n"); - } - - else { + }elseif (preg_match('/^SIZE largefile/', $buf)) { + fputs($s, "213 5368709120\r\n"); + }else { fputs($s, "500 Syntax error, command unrecognized.\r\n"); dump_and_exit($buf); } @@ -407,4 +418,4 @@ if ($pid) { } fclose($socket); -?>
\ No newline at end of file +?> |