summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Skalski <askalski@php.net>1999-09-27 14:07:09 +0000
committerAndrew Skalski <askalski@php.net>1999-09-27 14:07:09 +0000
commit0413f524800e8830e2fdb161b61284a039504545 (patch)
treec571a63242a24bd0ae7edff33138428203f575c6
parent10591231ca090c3f3353d7d61a46c1606d7ffde8 (diff)
downloadphp-git-0413f524800e8830e2fdb161b61284a039504545.tar.gz
Added functions ftp_{pasv,size,mdtm,fget,fput}
PASV mode is now supported; file size and last-modified time can now be fetched from servers that support them; files now may be stored to and retrieved from open files, in addition to disk files.
-rw-r--r--ext/ftp/ftp.c177
-rw-r--r--ext/ftp/ftp.h13
-rw-r--r--ext/ftp/php_ftp.c331
-rw-r--r--ext/ftp/php_ftp.h5
4 files changed, 384 insertions, 142 deletions
diff --git a/ext/ftp/ftp.c b/ext/ftp/ftp.c
index 4cd1123894..b83f34b8a6 100644
--- a/ext/ftp/ftp.c
+++ b/ext/ftp/ftp.c
@@ -34,8 +34,11 @@
#if HAVE_FTP
+#include <stdio.h>
+#include <ctype.h>
#include <stdlib.h>
#include <string.h>
+#include <time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
@@ -48,8 +51,8 @@ static int ftp_getresp(ftpbuf_t *ftp);
/* sets the ftp transfer type */
static int ftp_type(ftpbuf_t *ftp, ftptype_t type);
-/* opens up a port for ftp transfer */
-static databuf_t* ftp_port(ftpbuf_t *ftp);
+/* opens up a data stream */
+static databuf_t* ftp_getdata(ftpbuf_t *ftp);
/* accepts the data connection, returns updated data buffer */
static databuf_t* data_accept(databuf_t *data);
@@ -61,6 +64,13 @@ static databuf_t* data_close(databuf_t *data);
static char** ftp_genlist(ftpbuf_t *ftp,
const char *cmd, const char *path);
+/* IP and port conversion box */
+union ipbox {
+ unsigned long l[2];
+ unsigned short s[4];
+ unsigned char c[8];
+};
+
ftpbuf_t*
ftp_open(const char *host, short port)
@@ -428,6 +438,49 @@ ftp_type(ftpbuf_t *ftp, ftptype_t type)
int
+ftp_pasv(ftpbuf_t *ftp, int pasv)
+{
+ char *ptr;
+ union ipbox ipbox;
+ unsigned long b[6];
+ int n;
+
+ if (ftp == NULL)
+ return 0;
+
+ if (pasv && ftp->pasv == 2)
+ return 1;
+
+ ftp->pasv = 0;
+ if (!pasv)
+ return 1;
+
+ fprintf(ftp->fp, "PASV\r\n");
+ if (!ftp_getresp(ftp) || ftp->resp != 227)
+ return 0;
+
+ /* parse out the IP and port */
+ for (ptr = ftp->inbuf; *ptr && !isdigit(*ptr); ptr++);
+ n = sscanf(ptr, "%u,%u,%u,%u,%u,%u",
+ &b[0], &b[1], &b[2], &b[3], &b[4], &b[5]);
+ if (n != 6)
+ return 0;
+
+ for (n=0; n<6; n++)
+ ipbox.c[n] = b[n];
+
+ memset(&ftp->pasvaddr, 0, sizeof(ftp->pasvaddr));
+ ftp->pasvaddr.sin_family = AF_INET;
+ ftp->pasvaddr.sin_addr.s_addr = ipbox.l[0];
+ ftp->pasvaddr.sin_port = ipbox.s[2];
+
+ ftp->pasv = 2;
+
+ return 1;
+}
+
+
+int
ftp_get(ftpbuf_t *ftp, FILE *outfp, const char *path, ftptype_t type)
{
databuf_t *data = NULL;
@@ -439,7 +492,7 @@ ftp_get(ftpbuf_t *ftp, FILE *outfp, const char *path, ftptype_t type)
if (!ftp_type(ftp, type))
goto bail;
- if ((data = ftp_port(ftp)) == NULL)
+ if ((data = ftp_getdata(ftp)) == NULL)
goto bail;
fprintf(ftp->fp, "RETR %s\r\n", path);
@@ -492,7 +545,7 @@ ftp_put(ftpbuf_t *ftp, const char *path, FILE *infp, ftptype_t type)
if (!ftp_type(ftp, type))
goto bail;
- if ((data = ftp_port(ftp)) == NULL)
+ if ((data = ftp_getdata(ftp)) == NULL)
goto bail;
fprintf(ftp->fp, "STOR %s\r\n", path);
@@ -523,18 +576,77 @@ bail:
}
+int
+ftp_size(ftpbuf_t *ftp, const char *path)
+{
+ if (ftp == NULL)
+ return -1;
+
+ fprintf(ftp->fp, "SIZE %s\r\n", path);
+ if (!ftp_getresp(ftp) || ftp->resp != 213)
+ return -1;
+
+ return atoi(ftp->inbuf);
+}
+
+
+time_t
+ftp_mdtm(ftpbuf_t *ftp, const char *path)
+{
+ time_t stamp;
+ struct tm *gmt;
+ struct tm tm;
+ char *ptr;
+ int n;
+
+ if (ftp == NULL)
+ return -1;
+
+ fprintf(ftp->fp, "MDTM %s\r\n", path);
+ if (!ftp_getresp(ftp) || ftp->resp != 213)
+ return -1;
+
+ /* parse out the timestamp */
+ for (ptr = ftp->inbuf; *ptr && !isdigit(*ptr); ptr++);
+ n = sscanf(ptr, "%4u%2u%2u%2u%2u%2u",
+ &tm.tm_year, &tm.tm_mon, &tm.tm_mday,
+ &tm.tm_hour, &tm.tm_min, &tm.tm_sec);
+ if (n != 6)
+ return -1;
+ tm.tm_year -= 1900;
+ tm.tm_mon--;
+ tm.tm_isdst = -1;
+
+ /* figure out the GMT offset */
+ stamp = time(NULL);
+ gmt = gmtime(&stamp);
+ gmt->tm_isdst = -1;
+
+ /* apply the GMT offset */
+ tm.tm_sec += stamp - mktime(gmt);
+ tm.tm_isdst = gmt->tm_isdst;
+
+ stamp = mktime(&tm);
+
+ return stamp;
+}
+
+
+/* static functions */
+
databuf_t*
-ftp_port(ftpbuf_t *ftp)
+ftp_getdata(ftpbuf_t *ftp)
{
int fd = -1;
databuf_t *data;
struct sockaddr_in addr;
int size;
- union {
- unsigned long l[1];
- unsigned short s[2];
- unsigned char c[4];
- } ipbox;
+ union ipbox ipbox;
+
+
+ /* ask for a passive connection if we need one */
+ if (ftp->pasv && !ftp_pasv(ftp, 1))
+ return NULL;
/* alloc the data structure */
data = calloc(1, sizeof(*data));
@@ -551,6 +663,36 @@ ftp_port(ftpbuf_t *ftp)
goto bail;
}
+ /* passive connection handler */
+ if (ftp->pasv) {
+ /* clear the ready status */
+ ftp->pasv = 1;
+
+ /* connect */
+ if (connect(fd, (struct sockaddr*) &ftp->pasvaddr,
+ sizeof(ftp->pasvaddr)) == -1)
+ {
+ perror("connect");
+ close(fd);
+ free(data);
+ return NULL;
+ }
+
+ /* wrap fd in a FILE stream */
+ data->fp = fdopen(fd, "r+");
+ if (data->fp == NULL) {
+ perror("fdopen");
+ close(fd);
+ free(data);
+ return NULL;
+ }
+
+ return data;
+ }
+
+
+ /* active (normal) connection */
+
/* bind to a local address */
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
@@ -577,11 +719,10 @@ ftp_port(ftpbuf_t *ftp)
/* send the PORT */
ipbox.l[0] = ftp->localaddr.s_addr;
- fprintf(ftp->fp, "PORT %u,%u,%u,%u,",
- ipbox.c[0], ipbox.c[1], ipbox.c[2], ipbox.c[3]);
- ipbox.s[0] = addr.sin_port;
- fprintf(ftp->fp, "%u,%u\r\n",
- ipbox.c[0], ipbox.c[1]);
+ ipbox.s[2] = addr.sin_port;
+ fprintf(ftp->fp, "PORT %u,%u,%u,%u,%u,%u\r\n",
+ ipbox.c[0], ipbox.c[1], ipbox.c[2], ipbox.c[3],
+ ipbox.c[4], ipbox.c[5]);
if (!ftp_getresp(ftp) || ftp->resp != 200)
goto bail;
@@ -603,6 +744,10 @@ data_accept(databuf_t *data)
int size;
int fd;
+
+ if (data->fp)
+ return data;
+
size = sizeof(addr);
fd = accept(data->listener, (struct sockaddr*) &addr, &size);
close(data->listener);
@@ -656,7 +801,7 @@ ftp_genlist(ftpbuf_t *ftp, const char *cmd, const char *path)
if (!ftp_type(ftp, FTPTYPE_ASCII))
goto bail;
- if ((data = ftp_port(ftp)) == NULL)
+ if ((data = ftp_getdata(ftp)) == NULL)
goto bail;
if (path)
diff --git a/ext/ftp/ftp.h b/ext/ftp/ftp.h
index 800a9a197f..ddfe9aa118 100644
--- a/ext/ftp/ftp.h
+++ b/ext/ftp/ftp.h
@@ -53,6 +53,8 @@ typedef struct ftpbuf
char *pwd; /* cached pwd */
char *syst; /* cached system type */
ftptype_t type; /* current transfer type */
+ int pasv; /* 0=off; 1=pasv; 2=ready */
+ struct sockaddr_in pasvaddr; /* passive mode address */
} ftpbuf_t;
typedef struct databuf
@@ -118,6 +120,11 @@ char** ftp_nlist(ftpbuf_t *ftp, const char *path);
*/
char** ftp_list(ftpbuf_t *ftp, const char *path);
+/* switches passive mode on or off
+ * returns true on success, false on error
+ */
+int ftp_pasv(ftpbuf_t *ftp, int pasv);
+
/* retrieves a file and saves its contents to outfp
* returns true on success, false on error
*/
@@ -130,4 +137,10 @@ int ftp_get(ftpbuf_t *ftp, FILE *outfp, const char *path,
int ftp_put(ftpbuf_t *ftp, const char *path, FILE *infp,
ftptype_t type);
+/* returns the size of the given file, or -1 on error */
+int 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);
+
#endif
diff --git a/ext/ftp/php_ftp.c b/ext/ftp/php_ftp.c
index 8e641fa549..2307b0aa9c 100644
--- a/ext/ftp/php_ftp.c
+++ b/ext/ftp/php_ftp.c
@@ -57,8 +57,13 @@ function_entry php3_ftp_functions[] = {
PHP_FE(ftp_nlist, NULL)
PHP_FE(ftp_rawlist, NULL)
PHP_FE(ftp_systype, NULL)
+ PHP_FE(ftp_pasv, NULL)
PHP_FE(ftp_get, NULL)
+ PHP_FE(ftp_fget, NULL)
PHP_FE(ftp_put, NULL)
+ PHP_FE(ftp_fput, NULL)
+ PHP_FE(ftp_size, NULL)
+ PHP_FE(ftp_mdtm, NULL)
PHP_FE(ftp_quit, NULL)
{NULL, NULL, NULL}
};
@@ -101,12 +106,47 @@ PHP_MINIT_FUNCTION(ftp)
return SUCCESS;
}
+
+#define FTPBUF(ftp, pval) { \
+ int id, type; \
+ convert_to_long(pval); \
+ id = (pval)->value.lval; \
+ (ftp) = php3_list_find(id, &type); \
+ if (!(ftp) || type != le_ftpbuf) { \
+ php_error(E_WARNING, "Unable to find ftpbuf %d", id); \
+ RETURN_FALSE; \
+ } \
+ }
+
+#define XTYPE(xtype, pval) { \
+ convert_to_long(pval); \
+ if ( pval->value.lval != FTPTYPE_ASCII && \
+ pval->value.lval != FTPTYPE_IMAGE) \
+ { \
+ php_error(E_WARNING, "arg4 must be FTP_ASCII or FTP_IMAGE"); \
+ RETURN_FALSE; \
+ } \
+ (xtype) = pval->value.lval; \
+ }
+
+#define FILEP(fp, pval) { \
+ int id, type; \
+ int le_fp; \
+ le_fp = php3i_get_le_fp(); \
+ convert_to_long(pval); \
+ id = (pval)->value.lval; \
+ (fp) = php3_list_find(id, &type); \
+ if (!(fp) || type != le_fp) { \
+ php_error(E_WARNING, "Unable to find fp %d", id); \
+ RETURN_FALSE; \
+ } \
+ }
+
/* {{{ proto int ftp_connect(string host [, int port])
Open a FTP stream */
PHP_FUNCTION(ftp_connect)
{
pval *arg1, *arg2;
- int id;
ftpbuf_t *ftp;
short port = 0;
@@ -137,8 +177,7 @@ PHP_FUNCTION(ftp_connect)
if (ftp == NULL)
RETURN_FALSE;
- id = php3_list_insert(ftp, le_ftpbuf);
- RETURN_LONG(id);
+ RETURN_LONG(php3_list_insert(ftp, le_ftpbuf));
}
/* }}} */
@@ -147,7 +186,6 @@ PHP_FUNCTION(ftp_connect)
PHP_FUNCTION(ftp_login)
{
pval *arg1, *arg2, *arg3;
- int id, type;
ftpbuf_t *ftp;
/* arg1 - ftp
@@ -160,16 +198,10 @@ PHP_FUNCTION(ftp_login)
WRONG_PARAM_COUNT;
}
- convert_to_long(arg1);
convert_to_string(arg2);
convert_to_string(arg3);
- id = arg1->value.lval;
- ftp = php3_list_find(id, &type);
- if (!ftp || type != le_ftpbuf) {
- php_error(E_WARNING, "Unable to find ftpbuf %d", id);
- RETURN_FALSE;
- }
+ FTPBUF(ftp, arg1);
/* log in */
if (!ftp_login(ftp, arg2->value.str.val, arg3->value.str.val)) {
@@ -186,7 +218,6 @@ PHP_FUNCTION(ftp_login)
PHP_FUNCTION(ftp_pwd)
{
pval *arg1;
- int id, type;
ftpbuf_t *ftp;
const char *pwd;
@@ -196,14 +227,7 @@ PHP_FUNCTION(ftp_pwd)
WRONG_PARAM_COUNT;
}
- convert_to_long(arg1);
-
- id = arg1->value.lval;
- ftp = php3_list_find(id, &type);
- if (!ftp || type != le_ftpbuf) {
- php_error(E_WARNING, "Unable to find ftpbuf %d", id);
- RETURN_FALSE;
- }
+ FTPBUF(ftp, arg1);
pwd = ftp_pwd(ftp);
if (pwd == NULL) {
@@ -220,7 +244,6 @@ PHP_FUNCTION(ftp_pwd)
PHP_FUNCTION(ftp_cdup)
{
pval *arg1;
- int id, type;
ftpbuf_t *ftp;
/* arg1 - ftp
@@ -229,14 +252,7 @@ PHP_FUNCTION(ftp_cdup)
WRONG_PARAM_COUNT;
}
- convert_to_long(arg1);
-
- id = arg1->value.lval;
- ftp = php3_list_find(id, &type);
- if (!ftp || type != le_ftpbuf) {
- php_error(E_WARNING, "Unable to find ftpbuf %d", id);
- RETURN_FALSE;
- }
+ FTPBUF(ftp, arg1);
if (!ftp_cdup(ftp)) {
php_error(E_WARNING, "ftp_cdup: %s", ftp->inbuf);
@@ -252,7 +268,6 @@ PHP_FUNCTION(ftp_cdup)
PHP_FUNCTION(ftp_chdir)
{
pval *arg1, *arg2;
- int id, type;
ftpbuf_t *ftp;
/* arg1 - ftp
@@ -264,15 +279,9 @@ PHP_FUNCTION(ftp_chdir)
WRONG_PARAM_COUNT;
}
- convert_to_long(arg1);
convert_to_string(arg2);
- id = arg1->value.lval;
- ftp = php3_list_find(id, &type);
- if (!ftp || type != le_ftpbuf) {
- php_error(E_WARNING, "Unable to find ftpbuf %d", id);
- RETURN_FALSE;
- }
+ FTPBUF(ftp, arg1);
/* change directories */
if (!ftp_chdir(ftp, arg2->value.str.val)) {
@@ -289,7 +298,6 @@ PHP_FUNCTION(ftp_chdir)
PHP_FUNCTION(ftp_mkdir)
{
pval *arg1, *arg2;
- int id, type;
ftpbuf_t *ftp;
char *ret, *tmp;
@@ -302,15 +310,9 @@ PHP_FUNCTION(ftp_mkdir)
WRONG_PARAM_COUNT;
}
- convert_to_long(arg1);
convert_to_string(arg2);
- id = arg1->value.lval;
- ftp = php3_list_find(id, &type);
- if (!ftp || type != le_ftpbuf) {
- php_error(E_WARNING, "Unable to find ftpbuf %d", id);
- RETURN_FALSE;
- }
+ FTPBUF(ftp, arg1);
/* change directories */
tmp = ftp_mkdir(ftp, arg2->value.str.val);
@@ -334,7 +336,6 @@ PHP_FUNCTION(ftp_mkdir)
PHP_FUNCTION(ftp_rmdir)
{
pval *arg1, *arg2;
- int id, type;
ftpbuf_t *ftp;
/* arg1 - ftp
@@ -346,15 +347,9 @@ PHP_FUNCTION(ftp_rmdir)
WRONG_PARAM_COUNT;
}
- convert_to_long(arg1);
convert_to_string(arg2);
- id = arg1->value.lval;
- ftp = php3_list_find(id, &type);
- if (!ftp || type != le_ftpbuf) {
- php_error(E_WARNING, "Unable to find ftpbuf %d", id);
- RETURN_FALSE;
- }
+ FTPBUF(ftp, arg1);
/* change directories */
if (!ftp_rmdir(ftp, arg2->value.str.val)) {
@@ -371,7 +366,6 @@ PHP_FUNCTION(ftp_rmdir)
PHP_FUNCTION(ftp_nlist)
{
pval *arg1, *arg2;
- int id, type;
ftpbuf_t *ftp;
char **nlist, **ptr;
@@ -384,15 +378,9 @@ PHP_FUNCTION(ftp_nlist)
WRONG_PARAM_COUNT;
}
- convert_to_long(arg1);
convert_to_string(arg2);
- id = arg1->value.lval;
- ftp = php3_list_find(id, &type);
- if (!ftp || type != le_ftpbuf) {
- php_error(E_WARNING, "Unable to find ftpbuf %d", id);
- RETURN_FALSE;
- }
+ FTPBUF(ftp, arg1);
/* get list of files */
nlist = ftp_nlist(ftp, arg2->value.str.val);
@@ -412,7 +400,6 @@ PHP_FUNCTION(ftp_nlist)
PHP_FUNCTION(ftp_rawlist)
{
pval *arg1, *arg2;
- int id, type;
ftpbuf_t *ftp;
char **llist, **ptr;
@@ -425,15 +412,9 @@ PHP_FUNCTION(ftp_rawlist)
WRONG_PARAM_COUNT;
}
- convert_to_long(arg1);
convert_to_string(arg2);
- id = arg1->value.lval;
- ftp = php3_list_find(id, &type);
- if (!ftp || type != le_ftpbuf) {
- php_error(E_WARNING, "Unable to find ftpbuf %d", id);
- RETURN_FALSE;
- }
+ FTPBUF(ftp, arg1);
/* get directory listing */
llist = ftp_list(ftp, arg2->value.str.val);
@@ -453,7 +434,6 @@ PHP_FUNCTION(ftp_rawlist)
PHP_FUNCTION(ftp_systype)
{
pval *arg1;
- int id, type;
ftpbuf_t *ftp;
const char *syst;
@@ -465,14 +445,7 @@ PHP_FUNCTION(ftp_systype)
WRONG_PARAM_COUNT;
}
- convert_to_long(arg1);
-
- id = arg1->value.lval;
- ftp = php3_list_find(id, &type);
- if (!ftp || type != le_ftpbuf) {
- php_error(E_WARNING, "Unable to find ftpbuf %d", id);
- RETURN_FALSE;
- }
+ FTPBUF(ftp, arg1);
syst = ftp_syst(ftp);
if (syst == NULL) {
@@ -484,12 +457,76 @@ PHP_FUNCTION(ftp_systype)
}
/* }}} */
+/* {{{ proto int ftp_fget(int stream, int fp, string remote_file, int mode)
+ Retrieves a file from the FTP server and writes it to an open file. */
+PHP_FUNCTION(ftp_fget)
+{
+ pval *arg1, *arg2, *arg3, *arg4;
+ ftpbuf_t *ftp;
+ ftptype_t xtype;
+ FILE *fp;
+
+ /* arg1 - ftp
+ * arg2 - fp
+ * arg3 - remote file
+ * arg4 - transfer mode
+ */
+ if ( ARG_COUNT(ht) != 4 ||
+ getParameters(ht, 4, &arg1, &arg2, &arg3, &arg4) == FAILURE)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ FTPBUF(ftp, arg1);
+ FILEP(fp, arg2);
+ convert_to_string(arg3);
+ XTYPE(xtype, arg4);
+
+ if (!ftp_get(ftp, fp, arg3->value.str.val, xtype) || ferror(fp)) {
+ php_error(E_WARNING, "ftp_get: %s", ftp->inbuf);
+ RETURN_FALSE;
+ }
+
+ if (ferror(fp)) {
+ php_error(E_WARNING, "error writing %s", arg2->value.str.val);
+ RETURN_FALSE;
+ }
+
+ RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto int ftp_pasv(int stream, int pasv)
+ Turns passive mode on or off. */
+PHP_FUNCTION(ftp_pasv)
+{
+ pval *arg1, *arg2;
+ ftpbuf_t *ftp;
+
+ /* arg1 - ftp
+ * arg2 - pasv
+ */
+ if ( ARG_COUNT(ht) != 2 ||
+ getParameters(ht, 2, &arg1, &arg2) == FAILURE)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ FTPBUF(ftp, arg1);
+ convert_to_long(arg2);
+
+ if (!ftp_pasv(ftp, (arg2->value.lval) ? 1 : 0))
+ RETURN_FALSE;
+
+ RETURN_TRUE;
+}
+/* }}} */
+
/* {{{ proto int ftp_get(int stream, string local_file, string remote_file, int mode)
- Retrieves a file from the FTP server. */
+ Retrieves a file from the FTP server and writes it to a local file. */
PHP_FUNCTION(ftp_get)
{
pval *arg1, *arg2, *arg3, *arg4;
- int id, type;
ftpbuf_t *ftp;
ftptype_t xtype;
FILE *outfp, *tmpfp;
@@ -507,26 +544,10 @@ PHP_FUNCTION(ftp_get)
WRONG_PARAM_COUNT;
}
- convert_to_long(arg1);
+ FTPBUF(ftp, arg1);
convert_to_string(arg2);
convert_to_string(arg3);
- convert_to_long(arg4);
-
- id = arg1->value.lval;
- ftp = php3_list_find(id, &type);
- if (!ftp || type != le_ftpbuf) {
- php_error(E_WARNING, "Unable to find ftpbuf %d", id);
- RETURN_FALSE;
- }
-
- if ( arg4->value.lval != FTPTYPE_ASCII &&
- arg4->value.lval != FTPTYPE_IMAGE)
- {
- php_error(E_WARNING, "arg4 must be FTP_ASCII or FTP_IMAGE");
- RETURN_FALSE;
- }
-
- xtype = arg4->value.lval;
+ XTYPE(xtype, arg4);
/* get to temporary file, so if there is an error, no existing
* file gets clobbered
@@ -568,12 +589,45 @@ PHP_FUNCTION(ftp_get)
}
/* }}} */
+/* {{{ proto int ftp_fput(int stream, string local_file, string remote_file, int mode)
+ Stores a file from an open file to the FTP server. */
+PHP_FUNCTION(ftp_fput)
+{
+ pval *arg1, *arg2, *arg3, *arg4;
+ ftpbuf_t *ftp;
+ ftptype_t xtype;
+ FILE *fp;
+
+ /* arg1 - ftp
+ * arg2 - remote file
+ * arg3 - fp
+ * arg4 - transfer mode
+ */
+ if ( ARG_COUNT(ht) != 4 ||
+ getParameters(ht, 4, &arg1, &arg2, &arg3, &arg4) == FAILURE)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ FTPBUF(ftp, arg1);
+ convert_to_string(arg2);
+ FILEP(fp, arg3);
+ XTYPE(xtype, arg4);
+
+ if (!ftp_put(ftp, arg2->value.str.val, fp, xtype)) {
+ php_error(E_WARNING, "ftp_put: %s", ftp->inbuf);
+ RETURN_FALSE;
+ }
+
+ RETURN_TRUE;
+}
+/* }}} */
+
/* {{{ proto int ftp_put(int stream, string remote_file, string local_file, int mode)
Stores a file on the FTP server */
PHP_FUNCTION(ftp_put)
{
pval *arg1, *arg2, *arg3, *arg4;
- int id, type;
ftpbuf_t *ftp;
ftptype_t xtype;
FILE *infp;
@@ -590,26 +644,10 @@ PHP_FUNCTION(ftp_put)
WRONG_PARAM_COUNT;
}
- convert_to_long(arg1);
+ FTPBUF(ftp, arg1);
convert_to_string(arg2);
convert_to_string(arg3);
- convert_to_long(arg4);
-
- id = arg1->value.lval;
- ftp = php3_list_find(id, &type);
- if (!ftp || type != le_ftpbuf) {
- php_error(E_WARNING, "Unable to find ftpbuf %d", id);
- RETURN_FALSE;
- }
-
- if ( arg4->value.lval != FTPTYPE_ASCII &&
- arg4->value.lval != FTPTYPE_IMAGE)
- {
- php_error(E_WARNING, "arg4 must be FTP_ASCII or FTP_IMAGE");
- RETURN_FALSE;
- }
-
- xtype = arg4->value.lval;
+ XTYPE(xtype, arg4);
if ((infp = fopen(arg3->value.str.val, "r")) == NULL) {
php_error(E_WARNING, "error opening %s", arg3->value.str.val);
@@ -628,13 +666,60 @@ PHP_FUNCTION(ftp_put)
}
/* }}} */
+/* {{{ proto int ftp_size(int stream, string path)
+ Returns the size of the file, or -1 on error. */
+PHP_FUNCTION(ftp_size)
+{
+ pval *arg1, *arg2;
+ ftpbuf_t *ftp;
+
+ /* arg1 - ftp
+ * arg2 - path
+ */
+ if ( ARG_COUNT(ht) != 2 ||
+ getParameters(ht, 2, &arg1, &arg2) == FAILURE)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ FTPBUF(ftp, arg1);
+ convert_to_string(arg2);
+
+ /* get file size */
+ RETURN_LONG(ftp_size(ftp, arg2->value.str.val));
+}
+/* }}} */
+
+/* {{{ proto int ftp_mdtm(int stream, string path)
+ Returns the last modification time of the file, or -1 on error */
+PHP_FUNCTION(ftp_mdtm)
+{
+ pval *arg1, *arg2;
+ ftpbuf_t *ftp;
+
+ /* arg1 - ftp
+ * arg2 - path
+ */
+ if ( ARG_COUNT(ht) != 2 ||
+ getParameters(ht, 2, &arg1, &arg2) == FAILURE)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ FTPBUF(ftp, arg1);
+ convert_to_string(arg2);
+
+ /* get file mod time */
+ RETURN_LONG(ftp_mdtm(ftp, arg2->value.str.val));
+}
+/* }}} */
+
/* {{{ proto int ftp_quit(int stream)
Closes the FTP stream */
PHP_FUNCTION(ftp_quit)
{
pval *arg1;
int id, type;
- ftpbuf_t *ftp;
/* arg1 - ftp
*/
@@ -642,15 +727,9 @@ PHP_FUNCTION(ftp_quit)
WRONG_PARAM_COUNT;
}
- convert_to_long(arg1);
id = arg1->value.lval;
- ftp = php3_list_find(id, &type);
- if (!ftp || type != le_ftpbuf) {
- php_error(E_WARNING, "Unable to find ftpbuf %d", id);
- RETURN_FALSE;
- }
-
- php3_list_delete(id);
+ if (php3_list_find(id, &type) && type == le_ftpbuf)
+ php3_list_delete(id);
RETURN_TRUE;
}
diff --git a/ext/ftp/php_ftp.h b/ext/ftp/php_ftp.h
index 05173d5909..1515b79725 100644
--- a/ext/ftp/php_ftp.h
+++ b/ext/ftp/php_ftp.h
@@ -59,8 +59,13 @@ PHP_FUNCTION(ftp_rmdir);
PHP_FUNCTION(ftp_nlist);
PHP_FUNCTION(ftp_rawlist);
PHP_FUNCTION(ftp_systype);
+PHP_FUNCTION(ftp_pasv);
PHP_FUNCTION(ftp_get);
+PHP_FUNCTION(ftp_fget);
PHP_FUNCTION(ftp_put);
+PHP_FUNCTION(ftp_fput);
+PHP_FUNCTION(ftp_size);
+PHP_FUNCTION(ftp_mdtm);
PHP_FUNCTION(ftp_quit);
#define phpext_ftp_ptr php3_ftp_module_ptr