Re: [PHP4BETA] cvs: /php4/ext/ftp ftp.h ftp.c
| From: | Thies C. Arntzen | Date: | Fri, 19 Nov 1999 09:06:48 +0000 |
| Subject: | Re: [PHP4BETA] cvs: /php4/ext/ftp ftp.h ftp.c | ||
| References: | 1 | Groups: | php.version4 |
| Request: | Send a blank email to php-version4+get-6479@lists.php.net to get a copy of this message | ||
andrew,
thanx for looking into that - work's now for me (solaris->linux). also
makeing it work with windows should now be easy!
tc
On Thu, 18 Nov 1999, Andrew Skalski wrote:
> askalski Thu Nov 18 15:30:03 1999 EDT
>
> Modified files:
> /php4/ext/ftp ftp.h ftp.c
> Log:
> Removed stdio wrapper from sockets; added timeouts to socket ops.
>
>
> Index: php4/ext/ftp/ftp.h
> diff -u php4/ext/ftp/ftp.h:1.7 php4/ext/ftp/ftp.h:1.8
> --- php4/ext/ftp/ftp.h:1.7 Mon Oct 4 14:30:37 1999
> +++ php4/ext/ftp/ftp.h Thu Nov 18 15:29:32 1999
> @@ -28,7 +28,7 @@
> +----------------------------------------------------------------------+
> */
>
> -/* $Id: ftp.h,v 1.7 1999/10/04 18:30:37 askalski Exp $ */
> +/* $Id: ftp.h,v 1.8 1999/11/18 20:29:32 askalski Exp $ */
>
> #ifndef _FTP_H
> #define _FTP_H
> @@ -37,7 +37,9 @@
> #include <netinet/in.h>
>
>
> +/* XXX these should be configurable at runtime XXX */
> #define FTP_BUFSIZE 4096
> +#define FTP_TIMEOUT 90
>
> typedef enum ftptype {
> FTPTYPE_ASCII,
> @@ -46,10 +48,13 @@
>
> typedef struct ftpbuf
> {
> - FILE *fp; /* control connection */
> + int fd; /* control connection */
> struct in_addr localaddr; /* local inet address */
> int resp; /* last response code */
> char inbuf[FTP_BUFSIZE]; /* last response text */
> + char *extra; /* extra characters */
> + int extralen; /* number of extra chars */
> + char outbuf[FTP_BUFSIZE]; /* command output buffer */
> char *pwd; /* cached pwd */
> char *syst; /* cached system type */
> ftptype_t type; /* current transfer type */
> @@ -60,8 +65,9 @@
> typedef struct databuf
> {
> int listener; /* listener socket */
> - FILE *fp; /* data connection */
> + int fd; /* data connection */
> ftptype_t type; /* transfer type */
> + char buf[FTP_BUFSIZE]; /* data buffer */
> } databuf_t;
>
>
> Index: php4/ext/ftp/ftp.c
> diff -u php4/ext/ftp/ftp.c:1.9 php4/ext/ftp/ftp.c:1.10
> --- php4/ext/ftp/ftp.c:1.9 Mon Oct 4 14:30:37 1999
> +++ php4/ext/ftp/ftp.c Thu Nov 18 15:29:32 1999
> @@ -28,7 +28,7 @@
> +----------------------------------------------------------------------+
> */
>
> -/* $Id: ftp.c,v 1.9 1999/10/04 18:30:37 askalski Exp $ */
> +/* $Id: ftp.c,v 1.10 1999/11/18 20:29:32 askalski Exp $ */
>
> #include "php.h"
>
> @@ -37,14 +37,35 @@
> #include <stdio.h>
> #include <ctype.h>
> #include <stdlib.h>
> +#include <unistd.h>
> +#include <fcntl.h>
> #include <string.h>
> #include <time.h>
> #include <sys/socket.h>
> #include <netinet/in.h>
> #include <netdb.h>
> +#include <errno.h>
> #include "ftp.h"
>
>
> +/* sends an ftp command, returns true on success, false on error.
> + * it sends the string "cmd args\r\n" if args is non-null, or
> + * "cmd\r\n" if args is null
> + */
> +static int ftp_putcmd( ftpbuf_t *ftp,
> + const char *cmd,
> + const char *args);
> +
> +/* wrapper around send/recv to handle timeouts */
> +static int my_send(int s, void *buf, size_t len);
> +static int my_recv(int s, void *buf, size_t len);
> +static int my_connect(int s, const struct sockaddr *addr,
> + int addrlen);
> +static int my_accept(int s, struct sockaddr *addr, int *addrlen);
> +
> +/* reads a line the socket , returns true on success, false on error */
> +static int ftp_readline(ftpbuf_t *ftp);
> +
> /* reads an ftp response, returns true on success, false on error */
> static int ftp_getresp(ftpbuf_t *ftp);
>
> @@ -84,7 +105,9 @@
>
> /* set up the address */
> if ((he = gethostbyname(host)) == NULL) {
> +#if 0
> herror("gethostbyname");
> +#endif
> return NULL;
> }
>
> @@ -107,7 +130,7 @@
> goto bail;
> }
>
> - if (connect(fd, (struct sockaddr*) &addr, sizeof(addr)) == -1) {
> + if (my_connect(fd, (struct sockaddr*) &addr, sizeof(addr)) == -1) {
> perror("connect");
> goto bail;
> }
> @@ -119,12 +142,8 @@
> }
>
> ftp->localaddr = addr.sin_addr;
> + ftp->fd = fd;
>
> - if ((ftp->fp = fdopen(fd, "r+")) == NULL) {
> - perror("fdopen");
> - goto bail;
> - }
> -
> if (!ftp_getresp(ftp) || ftp->resp != 220) {
> goto bail;
> }
> @@ -132,9 +151,7 @@
> return ftp;
>
> bail:
> - if (ftp->fp)
> - fclose(ftp->fp);
> - else if (fd != -1)
> + if (fd != -1)
> close(fd);
> free(ftp);
> return NULL;
> @@ -146,8 +163,8 @@
> {
> if (ftp == NULL)
> return NULL;
> - if (ftp->fp)
> - fclose(ftp->fp);
> + if (ftp->fd)
> + close(ftp->fd);
> ftp_gc(ftp);
> free(ftp);
> return NULL;
> @@ -173,7 +190,8 @@
> if (ftp == NULL)
> return 0;
>
> - fprintf(ftp->fp, "QUIT\r\n");
> + if (!ftp_putcmd(ftp, "QUIT", NULL))
> + return 0;
> if (!ftp_getresp(ftp) || ftp->resp != 221)
> return 0;
>
> @@ -190,14 +208,16 @@
> if (ftp == NULL)
> return 0;
>
> - fprintf(ftp->fp, "USER %s\r\n", user);
> + if (!ftp_putcmd(ftp, "USER", user))
> + return 0;
> if (!ftp_getresp(ftp))
> return 0;
> if (ftp->resp == 230)
> return 1;
> if (ftp->resp != 331)
> + return 0;
> + if (!ftp_putcmd(ftp, "PASS", pass))
> return 0;
> - fprintf(ftp->fp, "PASS %s\r\n", pass);
> if (!ftp_getresp(ftp))
> return 0;
> return (ftp->resp == 230);
> @@ -212,7 +232,8 @@
>
> ftp_gc(ftp);
>
> - fprintf(ftp->fp, "REIN\r\n");
> + if (!ftp_putcmd(ftp, "REIN", NULL))
> + return 0;
> if (!ftp_getresp(ftp) || ftp->resp != 220)
> return 0;
>
> @@ -232,7 +253,8 @@
> if (ftp->syst)
> return ftp->syst;
>
> - fprintf(ftp->fp, "SYST\r\n");
> + if (!ftp_putcmd(ftp, "SYST", NULL))
> + return NULL;
> if (!ftp_getresp(ftp) || ftp->resp != 215)
> return NULL;
>
> @@ -259,7 +281,8 @@
> if (ftp->pwd)
> return ftp->pwd;
>
> - fprintf(ftp->fp, "PWD\r\n");
> + if (!ftp_putcmd(ftp, "PWD", NULL))
> + return NULL;
> if (!ftp_getresp(ftp) || ftp->resp != 257)
> return NULL;
>
> @@ -284,7 +307,8 @@
> free(ftp->pwd);
> ftp->pwd = NULL;
>
> - fprintf(ftp->fp, "CWD %s\r\n", dir);
> + if (!ftp_putcmd(ftp, "CWD", dir))
> + return 0;
> if (!ftp_getresp(ftp) || ftp->resp != 250)
> return 0;
>
> @@ -301,7 +325,8 @@
> free(ftp->pwd);
> ftp->pwd = NULL;
>
> - fprintf(ftp->fp, "CDUP\r\n");
> + if (!ftp_putcmd(ftp, "CDUP", NULL))
> + return 0;
> if (!ftp_getresp(ftp) || ftp->resp != 250)
> return 0;
>
> @@ -317,7 +342,8 @@
> if (ftp == NULL)
> return NULL;
>
> - fprintf(ftp->fp, "MKD %s\r\n", dir);
> + if (!ftp_putcmd(ftp, "MKD", dir))
> + return NULL;
> if (!ftp_getresp(ftp) || ftp->resp != 257)
> return NULL;
>
> @@ -339,7 +365,8 @@
> if (ftp == NULL)
> return 0;
>
> - fprintf(ftp->fp, "RMD %s\r\n", dir);
> + if (!ftp_putcmd(ftp, "RMD", dir))
> + return 0;
> if (!ftp_getresp(ftp) || ftp->resp != 250)
> return 0;
>
> @@ -362,57 +389,9 @@
>
>
> int
> -ftp_getresp(ftpbuf_t *ftp)
> -{
> - char tag[4];
> - int ch;
> - char *buf;
> - char *ptr;
> -
> - if (ftp == NULL)
> - return 0;
> - buf = ftp->inbuf;
> - ftp->resp = 0;
> -
> - do {
> - if (!fread(tag, 4, 1, ftp->fp))
> - return 0;
> -
> - if (tag[3] == '-') {
> - while ((ch = getc(ftp->fp)) != '\n')
> - if (ch == EOF) {
> - return 0;
> - }
> - }
> - else if (tag[3] == ' ') {
> - ptr = fgets(buf, FTP_BUFSIZE, ftp->fp);
> - if (!ptr || !(ptr = strchr(buf, '\n')))
> - return 0;
> - if (ptr > buf && ptr[-1] == '\r')
> - ptr--;
> - *ptr = 0;
> - }
> - else {
> - return 0;
> - }
> - } while (tag[3] == '-');
> -
> -
> - /* translate the tag */
> - if (!isdigit(tag[0]) || !isdigit(tag[1]) || !isdigit(tag[2]))
> - return 0;
> -
> - ftp->resp = 100 * (tag[0] - '0') +
> - 10 * (tag[1] - '0') +
> - (tag[2] - '0');
> - return 1;
> -}
> -
> -
> -int
> ftp_type(ftpbuf_t *ftp, ftptype_t type)
> {
> - char typechar;
> + char typechar[2] = "?";
>
> if (ftp == NULL)
> return 0;
> @@ -421,13 +400,14 @@
> return 1;
>
> if (type == FTPTYPE_ASCII)
> - typechar = 'A';
> + typechar[0] = 'A';
> else if (type == FTPTYPE_IMAGE)
> - typechar = 'I';
> + typechar[0] = 'I';
> else
> return 0;
>
> - fprintf(ftp->fp, "TYPE %c\r\n", typechar);
> + if (!ftp_putcmd(ftp, "TYPE", typechar))
> + return 0;
> if (!ftp_getresp(ftp) || ftp->resp != 200)
> return 0;
>
> @@ -455,13 +435,14 @@
> if (!pasv)
> return 1;
>
> - fprintf(ftp->fp, "PASV\r\n");
> + if (!ftp_putcmd(ftp, "PASV", NULL))
> + return 0;
> 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",
> + n = sscanf(ptr, "%lu,%lu,%lu,%lu,%lu,%lu",
> &b[0], &b[1], &b[2], &b[3], &b[4], &b[5]);
> if (n != 6)
> return 0;
> @@ -484,7 +465,9 @@
> ftp_get(ftpbuf_t *ftp, FILE *outfp, const char *path, ftptype_t type)
> {
> databuf_t *data = NULL;
> - int ch, lastch;
> + char *ptr;
> + int lastch;
> + int rcvd;
>
> if (ftp == NULL)
> return 0;
> @@ -495,7 +478,8 @@
> if ((data = ftp_getdata(ftp)) == NULL)
> goto bail;
>
> - fprintf(ftp->fp, "RETR %s\r\n", path);
> + if (!ftp_putcmd(ftp, "RETR", path))
> + goto bail;
> if (!ftp_getresp(ftp) || ftp->resp != 150)
> goto bail;
>
> @@ -503,26 +487,32 @@
> goto bail;
>
> lastch = 0;
> - while ((ch = getc(data->fp)) != EOF) {
> + while ((rcvd = my_recv(data->fd, data->buf, FTP_BUFSIZE))) {
> + if (rcvd == -1)
> + goto bail;
> +
> if (type == FTPTYPE_ASCII) {
> - if (lastch == '\r' && ch != '\n')
> - putc('\r', outfp);
> - if (ch != '\r')
> - putc(ch, outfp);
> - lastch = ch;
> + for (ptr = data->buf; rcvd; rcvd--, ptr++) {
> + if (lastch == '\r' && *ptr != '\n')
> + putc('\r', outfp);
> + if (*ptr != '\r')
> + putc(*ptr, outfp);
> + lastch = *ptr;
> + }
> }
> else {
> - putc(ch, outfp);
> + fwrite(data->buf, rcvd, 1, outfp);
> }
> }
> +
> if (type == FTPTYPE_ASCII && lastch == '\r')
> putc('\r', outfp);
>
> - if (ferror(data->fp) || ferror(outfp))
> - goto bail;
> -
> data = data_close(data);
>
> + if (ferror(outfp))
> + goto bail;
> +
> if (!ftp_getresp(ftp) || ftp->resp != 226)
> goto bail;
>
> @@ -537,6 +527,8 @@
> ftp_put(ftpbuf_t *ftp, const char *path, FILE *infp, ftptype_t type)
> {
> databuf_t *data = NULL;
> + int size;
> + char *ptr;
> int ch;
>
> if (ftp == NULL)
> @@ -548,20 +540,38 @@
> if ((data = ftp_getdata(ftp)) == NULL)
> goto bail;
>
> - fprintf(ftp->fp, "STOR %s\r\n", path);
> + if (!ftp_putcmd(ftp, "STOR", path))
> + goto bail;
> if (!ftp_getresp(ftp) || ftp->resp != 150)
> goto bail;
>
> if ((data = data_accept(data)) == NULL)
> goto bail;
>
> + size = 0;
> + ptr = data->buf;
> while ((ch = getc(infp)) != EOF) {
> - if (type == FTPTYPE_ASCII && ch == '\n')
> - putc('\r', data->fp);
> - putc(ch, data->fp);
> + /* flush if necessary */
> + if (FTP_BUFSIZE - size < 2) {
> + if (my_send(data->fd, data->buf, size) != size)
> + goto bail;
> + ptr = data->buf;
> + size = 0;
> + }
> +
> + if (ch == '\n' && type == FTPTYPE_ASCII) {
> + *ptr++ = '\r';
> + size++;
> + }
> +
> + *ptr++ = ch;
> + size++;
> }
> +
> + if (size && my_send(data->fd, data->buf, size) != size)
> + goto bail;
>
> - if (ferror(data->fp) || ferror(infp))
> + if (ferror(infp))
> goto bail;
>
> data = data_close(data);
> @@ -582,7 +592,8 @@
> if (ftp == NULL)
> return -1;
>
> - fprintf(ftp->fp, "SIZE %s\r\n", path);
> + if (!ftp_putcmd(ftp, "SIZE", path))
> + return -1;
> if (!ftp_getresp(ftp) || ftp->resp != 213)
> return -1;
>
> @@ -602,7 +613,8 @@
> if (ftp == NULL)
> return -1;
>
> - fprintf(ftp->fp, "MDTM %s\r\n", path);
> + if (!ftp_putcmd(ftp, "MDTM", path))
> + return -1;
> if (!ftp_getresp(ftp) || ftp->resp != 213)
> return -1;
>
> @@ -638,7 +650,8 @@
> if (ftp == NULL)
> return 0;
>
> - fprintf(ftp->fp, "DELE %s\r\n", path);
> + if (!ftp_putcmd(ftp, "DELE", path))
> + return 0;
> if (!ftp_getresp(ftp) || ftp->resp != 250)
> return 0;
>
> @@ -652,20 +665,262 @@
> if (ftp == NULL)
> return 0;
>
> - fprintf(ftp->fp, "RNFR %s\r\n", src);
> + if (!ftp_putcmd(ftp, "RNFR", src))
> + return 0;
> if (!ftp_getresp(ftp) || ftp->resp != 350)
> return 0;
>
> - fprintf(ftp->fp, "RNTO %s\r\n", dest);
> + if (!ftp_putcmd(ftp, "RNTO", dest))
> + return 0;
> if (!ftp_getresp(ftp) || ftp->resp != 250)
> return 0;
>
> return 1;
> }
>
> -
> /* static functions */
>
> +int
> +ftp_putcmd(ftpbuf_t *ftp, const char *cmd, const char *args)
> +{
> + int size;
> + char *data;
> +
> + /* build the output buffer */
> + if (args) {
> + /* "cmd args\r\n\0" */
> + if (strlen(cmd) + strlen(args) + 4 > FTP_BUFSIZE)
> + return 0;
> + size = sprintf(ftp->outbuf, "%s %s\r\n", cmd, args);
> + }
> + else {
> + /* "cmd\r\n\0" */
> + if (strlen(cmd) + 3 > FTP_BUFSIZE)
> + return 0;
> + size = sprintf(ftp->outbuf, "%s\r\n", cmd);
> + }
> +
> + data = ftp->outbuf;
> + if (my_send(ftp->fd, data, size) != size)
> + return 0;
> +
> + return 1;
> +}
> +
> +
> +int
> +ftp_readline(ftpbuf_t *ftp)
> +{
> + int size, rcvd;
> + char *data, *eol;
> +
> + /* shift the extra to the front */
> + size = FTP_BUFSIZE;
> + rcvd = 0;
> + if (ftp->extra) {
> + memmove(ftp->inbuf, ftp->extra, ftp->extralen);
> + rcvd = ftp->extralen;
> + }
> +
> + data = ftp->inbuf;
> +
> + do {
> + size -= rcvd;
> + for (eol = data; rcvd; rcvd--, eol++) {
> + if (*eol == '\r') {
> + *eol = 0;
> + ftp->extra = eol + 1;
> + if (rcvd > 1 && *(eol + 1) == '\n') {
> + ftp->extra++;
> + rcvd--;
> + }
> + if ((ftp->extralen = --rcvd) == 0)
> + ftp->extra = NULL;
> + return 1;
> + }
> + else if (*eol == '\n') {
> + *eol = 0;
> + ftp->extra = eol + 1;
> + if ((ftp->extralen = --rcvd) == 0)
> + ftp->extra = NULL;
> + return 1;
> + }
> + }
> +
> + data = eol;
> + if ((rcvd = my_recv(ftp->fd, data, size)) < 1)
> + return 0;
> + } while (size);
> +
> + return 0;
> +}
> +
> +
> +int
> +ftp_getresp(ftpbuf_t *ftp)
> +{
> + char *buf;
> +
> + if (ftp == NULL)
> + return 0;
> + buf = ftp->inbuf;
> + ftp->resp = 0;
> +
> +
> + while (1) {
> + if (!ftp_readline(ftp))
> + return 0;
> + if (ftp->inbuf[3] == '-')
> + continue;
> + else if (ftp->inbuf[3] != ' ')
> + return 0;
> + break;
> + }
> +
> + /* translate the tag */
> + if ( !isdigit(ftp->inbuf[0]) ||
> + !isdigit(ftp->inbuf[1]) ||
> + !isdigit(ftp->inbuf[2]))
> + {
> + return 0;
> + }
> +
> + ftp->resp = 100 * (ftp->inbuf[0] - '0') +
> + 10 * (ftp->inbuf[1] - '0') +
> + (ftp->inbuf[2] - '0');
> +
> + memmove(ftp->inbuf, ftp->inbuf + 4, FTP_BUFSIZE - 4);
> +
> + return 1;
> +}
> +
> +
> +int
> +my_send(int s, void *buf, size_t len)
> +{
> + fd_set write_set;
> + struct timeval tv;
> + int n, size, sent;
> +
> + size = len;
> + while (size) {
> + tv.tv_sec = FTP_TIMEOUT;
> + tv.tv_usec = 0;
> +
> + FD_ZERO(&write_set);
> + FD_SET(s, &write_set);
> + n = select(s + 1, NULL, &write_set, NULL, &tv);
> + if (n < 1) {
> + if (n == 0)
> + errno = ETIMEDOUT;
> + return -1;
> + }
> +
> + sent = send(s, buf, size, 0);
> + if (sent == -1)
> + return -1;
> +
> + buf += sent;
> + size -= sent;
> + }
> +
> + return len;
> +}
> +
> +
> +int
> +my_recv(int s, void *buf, size_t len)
> +{
> + fd_set read_set;
> + struct timeval tv;
> + int n;
> +
> + tv.tv_sec = FTP_TIMEOUT;
> + tv.tv_usec = 0;
> +
> + FD_ZERO(&read_set);
> + FD_SET(s, &read_set);
> + n = select(s + 1, &read_set, NULL, NULL, &tv);
> + if (n < 1) {
> + if (n == 0)
> + errno = ETIMEDOUT;
> + return -1;
> + }
> +
> + return recv(s, buf, len, 0);
> +}
> +
> +
> +int
> +my_connect(int s, const struct sockaddr *addr, int addrlen)
> +{
> + fd_set conn_set;
> + int flags;
> + int n;
> + int error = 0;
> + struct timeval tv;
> +
> + flags = fcntl(s, F_GETFL, 0);
> + fcntl(s, F_SETFL, flags | O_NONBLOCK);
> +
> + n = connect(s, addr, addrlen);
> + if (n == -1 && errno != EINPROGRESS)
> + return -1;
> +
> + if (n) {
> + FD_ZERO(&conn_set);
> + FD_SET(s, &conn_set);
> +
> + tv.tv_sec = FTP_TIMEOUT;
> + tv.tv_usec = 0;
> +
> + n = select(s + 1, &conn_set, &conn_set, NULL, &tv);
> + if (n < 1) {
> + if (n == 0)
> + errno = ETIMEDOUT;
> + return -1;
> + }
> +
> + if (FD_ISSET(s, &conn_set)) {
> + n = sizeof(error);
> + n = getsockopt(s, SOL_SOCKET, SO_ERROR, &error, &n);
> + if (n == -1 || error) {
> + if (error)
> + errno = error;
> + return -1;
> + }
> + }
> + }
> +
> + fcntl(s, F_SETFL, flags);
> +
> + return 0;
> +}
> +
> +
> +int
> +my_accept(int s, struct sockaddr *addr, int *addrlen)
> +{
> + fd_set accept_set;
> + struct timeval tv;
> + int n;
> +
> + tv.tv_sec = FTP_TIMEOUT;
> + tv.tv_usec = 0;
> + FD_ZERO(&accept_set);
> + FD_SET(s, &accept_set);
> +
> + n = select(s + 1, &accept_set, NULL, NULL, &tv);
> + if (n < 1) {
> + if (n == 0)
> + errno = ETIMEDOUT;
> + return -1;
> + }
> +
> + return accept(s, addr, addrlen);
> +}
> +
> +
> databuf_t*
> ftp_getdata(ftpbuf_t *ftp)
> {
> @@ -674,6 +929,7 @@
> struct sockaddr_in addr;
> int size;
> union ipbox ipbox;
> + char arg[sizeof("255,255,255,255,255,255")];
>
>
> /* ask for a passive connection if we need one */
> @@ -687,6 +943,7 @@
> return NULL;
> }
> data->listener = -1;
> + data->fd = -1;
> data->type = ftp->type;
>
> /* bind/listen */
> @@ -701,7 +958,7 @@
> ftp->pasv = 1;
>
> /* connect */
> - if (connect(fd, (struct sockaddr*) &ftp->pasvaddr,
> + if (my_connect(fd, (struct sockaddr*) &ftp->pasvaddr,
> sizeof(ftp->pasvaddr)) == -1)
> {
> perror("connect");
> @@ -710,14 +967,7 @@
> 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;
> - }
> + data->fd = fd;
>
> return data;
> }
> @@ -752,10 +1002,12 @@
> /* send the PORT */
> ipbox.l[0] = ftp->localaddr.s_addr;
> ipbox.s[2] = addr.sin_port;
> - fprintf(ftp->fp, "PORT %u,%u,%u,%u,%u,%u\r\n",
> + sprintf(arg, "%u,%u,%u,%u,%u,%u",
> ipbox.c[0], ipbox.c[1], ipbox.c[2], ipbox.c[3],
> ipbox.c[4], ipbox.c[5]);
>
> + if (!ftp_putcmd(ftp, "PORT", arg))
> + goto bail;
> if (!ftp_getresp(ftp) || ftp->resp != 200)
> goto bail;
>
> @@ -774,24 +1026,16 @@
> {
> struct sockaddr_in addr;
> int size;
> - int fd;
>
> -
> - if (data->fp)
> + if (data->fd != -1)
> return data;
>
> size = sizeof(addr);
> - fd = accept(data->listener, (struct sockaddr*) &addr, &size);
> + data->fd = my_accept(data->listener, (struct sockaddr*) &addr, &size);
> close(data->listener);
> data->listener = -1;
> -
> - if (fd == -1) {
> - free(data);
> - return NULL;
> - }
>
> - if ((data->fp = fdopen(fd, "r+")) == NULL) {
> - close(fd);
> + if (data->fd == -1) {
> free(data);
> return NULL;
> }
> @@ -807,8 +1051,8 @@
> return NULL;
> if (data->listener != -1)
> close(data->listener);
> - if (data->fp)
> - fclose(data->fp);
> + if (data->fd != -1)
> + close(data->fd);
> free(data);
> return NULL;
> }
> @@ -819,8 +1063,9 @@
> {
> FILE *tmpfp = NULL;
> databuf_t *data = NULL;
> + char *ptr;
> int ch, lastch;
> - int size;
> + int size, rcvd;
> int lines;
> char **ret = NULL;
> char **entry;
> @@ -836,10 +1081,8 @@
> if ((data = ftp_getdata(ftp)) == NULL)
> goto bail;
>
> - if (path)
> - fprintf(ftp->fp, "%s %s\r\n", cmd, path);
> - else
> - fprintf(ftp->fp, "%s\r\n", cmd);
> + if (!ftp_putcmd(ftp, cmd, path))
> + goto bail;
> if (!ftp_getresp(ftp) || ftp->resp != 150)
> goto bail;
>
> @@ -850,18 +1093,28 @@
> size = 0;
> lines = 0;
> lastch = 0;
> - while ((ch = getc(data->fp)) != EOF) {
> - if (ch == '\n' && lastch == '\r')
> - lines++;
> - else
> - size++;
> - putc(ch, tmpfp);
> - lastch = ch;
> + while ((rcvd = my_recv(data->fd, data->buf, FTP_BUFSIZE))) {
> + if (rcvd == -1)
> + goto bail;
> +
> + fwrite(data->buf, rcvd, 1, tmpfp);
> +
> + size += rcvd;
> + for (ptr = data->buf; rcvd; rcvd--, ptr++) {
> + if (*ptr == '\n' && lastch == '\r')
> + lines++;
> + else
> + size++;
> + lastch = *ptr;
> + }
> }
> +
> data = data_close(data);
>
> if (ferror(tmpfp))
> goto bail;
> +
> +
>
> rewind(tmpfp);
>
>
>
>
> --
> PHP 4.0 Beta Mailing List <http://www.php.net/version4/>
> To unsubscribe, e-mail: php4beta-unsubscribe@lists.php.net
> For additional commands, e-mail: php4beta-help@lists.php.net
> To contact the list administrators, e-mail: php4beta-admin@lists.php.net
>
>
Thies C. Arntzen "One Big-Mac, Small Fries and a Coke!"
Digital Collections Phone +49 40 235350 Fax +49 40 23535180
Hammerbrookstr. 93 20097 Hamburg / Germany