Re: [PHP4BETA] cvs: /php4/ext/ftp ftp.h ftp.c

From: 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

« previous php.version4 (#6479) next »