Skip to content

Commit c553af4

Browse files
committed
Add ftp_alloc() for servers which require client to predeclare filesize to be sent.
1 parent 3efe102 commit c553af4

File tree

4 files changed

+77
-0
lines changed

4 files changed

+77
-0
lines changed

ext/ftp/ftp.c

+32
Original file line numberDiff line numberDiff line change
@@ -605,6 +605,38 @@ ftp_chmod(ftpbuf_t *ftp, const int mode, const char *filename, const int filenam
605605
}
606606
/* }}} */
607607

608+
/* {{{ ftp_alloc
609+
*/
610+
int
611+
ftp_alloc(ftpbuf_t *ftp, const int size, char **response)
612+
{
613+
char buffer[64];
614+
615+
if (ftp == NULL || size <= 0) {
616+
return 0;
617+
}
618+
619+
snprintf(buffer, 64, "%d", size);
620+
621+
if (!ftp_putcmd(ftp, "ALLO", buffer)) {
622+
return 0;
623+
}
624+
625+
if (!ftp_getresp(ftp)) {
626+
return 0;
627+
}
628+
629+
if (response && ftp->inbuf) {
630+
*response = estrdup(ftp->inbuf);
631+
}
632+
633+
if (ftp->resp < 200 || ftp->resp >= 300) {
634+
return 0;
635+
}
636+
637+
return 1;
638+
}
639+
/* }}} */
608640

609641
/* {{{ ftp_nlist
610642
*/

ext/ftp/ftp.h

+7
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,13 @@ int ftp_rmdir(ftpbuf_t *ftp, const char *dir);
141141
/* Set permissions on a file */
142142
int ftp_chmod(ftpbuf_t *ftp, const int mode, const char *filename, const int filename_len);
143143

144+
/* Allocate space on remote server with ALLO command
145+
* Many servers will respond with 202 Allocation not necessary,
146+
* however some servers will not accept STOR or APPE until ALLO is confirmed.
147+
* If response is passed, it is estrdup()ed from ftp->inbuf and must be freed
148+
* or assigned to a zval returned to the user */
149+
int ftp_alloc(ftpbuf_t *ftp, const int size, char **response);
150+
144151
/* returns a NULL-terminated array of filenames in the given path
145152
* or NULL on error. the return array must be freed (but don't
146153
* free the array elements)

ext/ftp/php_ftp.c

+37
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,13 @@
5050
static int le_ftpbuf;
5151
#define le_ftpbuf_name "FTP Buffer"
5252

53+
static
54+
ZEND_BEGIN_ARG_INFO(third_and_rest_force_ref, 1)
55+
ZEND_ARG_PASS_INFO(0)
56+
ZEND_ARG_PASS_INFO(0)
57+
ZEND_ARG_PASS_INFO(1)
58+
ZEND_END_ARG_INFO()
59+
5360
function_entry php_ftp_functions[] = {
5461
PHP_FE(ftp_connect, NULL)
5562
#ifdef HAVE_OPENSSL_EXT
@@ -64,6 +71,7 @@ function_entry php_ftp_functions[] = {
6471
PHP_FE(ftp_mkdir, NULL)
6572
PHP_FE(ftp_rmdir, NULL)
6673
PHP_FE(ftp_chmod, NULL)
74+
PHP_FE(ftp_alloc, third_and_rest_force_ref)
6775
PHP_FE(ftp_nlist, NULL)
6876
PHP_FE(ftp_rawlist, NULL)
6977
PHP_FE(ftp_systype, NULL)
@@ -430,6 +438,35 @@ PHP_FUNCTION(ftp_chmod)
430438
}
431439
/* }}} */
432440

441+
/* {{{ proto bool ftp_alloc(resource stream, int size[, &response])
442+
Attempt to allocate space on the remote FTP server */
443+
PHP_FUNCTION(ftp_alloc)
444+
{
445+
zval *z_ftp, *zresponse = NULL;
446+
ftpbuf_t *ftp;
447+
int size, ret;
448+
char *response = NULL;
449+
450+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl|z", &z_ftp, &size, &zresponse) == FAILURE) {
451+
RETURN_FALSE;
452+
}
453+
454+
ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
455+
456+
ret = ftp_alloc(ftp, size, zresponse ? &response : NULL);
457+
if (response) {
458+
zval_dtor(zresponse);
459+
ZVAL_STRING(zresponse, response, 0);
460+
}
461+
462+
if (!ret) {
463+
RETURN_FALSE;
464+
}
465+
466+
RETURN_TRUE;
467+
}
468+
/* }}} */
469+
433470
/* {{{ proto array ftp_nlist(resource stream, string directory)
434471
Returns an array of filenames in the given directory */
435472
PHP_FUNCTION(ftp_nlist)

ext/ftp/php_ftp.h

+1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ PHP_FUNCTION(ftp_raw);
4747
PHP_FUNCTION(ftp_mkdir);
4848
PHP_FUNCTION(ftp_rmdir);
4949
PHP_FUNCTION(ftp_chmod);
50+
PHP_FUNCTION(ftp_alloc);
5051
PHP_FUNCTION(ftp_nlist);
5152
PHP_FUNCTION(ftp_rawlist);
5253
PHP_FUNCTION(ftp_systype);

0 commit comments

Comments
 (0)