diff options
author | Andrew Skalski <askalski@php.net> | 1999-09-27 14:07:09 +0000 |
---|---|---|
committer | Andrew Skalski <askalski@php.net> | 1999-09-27 14:07:09 +0000 |
commit | 0413f524800e8830e2fdb161b61284a039504545 (patch) | |
tree | c571a63242a24bd0ae7edff33138428203f575c6 | |
parent | 10591231ca090c3f3353d7d61a46c1606d7ffde8 (diff) | |
download | php-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.c | 177 | ||||
-rw-r--r-- | ext/ftp/ftp.h | 13 | ||||
-rw-r--r-- | ext/ftp/php_ftp.c | 331 | ||||
-rw-r--r-- | ext/ftp/php_ftp.h | 5 |
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 |