int ftp_get(ftpbuf_t *ftp, FILE *outfp, const char *path, ftptype_t type) { databuf_t *data = NULL; char *ptr; int lastch; int rcvd; if (ftp == NULL) return 0; if (!ftp_type(ftp, type)) goto bail; if ((data = ftp_getdata(ftp)) == NULL) goto bail; if (!ftp_putcmd(ftp, "RETR", path)) goto bail; if (!ftp_getresp(ftp) || (ftp->resp != 150 && ftp->resp != 125)) goto bail; if ((data = data_accept(data)) == NULL) goto bail; lastch = 0; while ((rcvd = my_recv(data->fd, data->buf, FTP_BUFSIZE))) { if (rcvd == -1) goto bail; if (type == FTPTYPE_ASCII) { for (ptr = data->buf; rcvd; rcvd--, ptr++) { if (lastch == '\r' && *ptr != '\n') putc('\r', outfp); if (*ptr != '\r') putc(*ptr, outfp); lastch = *ptr; } } else { fwrite(data->buf, rcvd, 1, outfp); } } if (type == FTPTYPE_ASCII && lastch == '\r') putc('\r', outfp); data = data_close(data); if (ferror(outfp)) goto bail; if (!ftp_getresp(ftp) || (ftp->resp != 226 && ftp->resp != 250)) goto bail; return 1; bail: data_close(data); return 0; }
/* {{{ ftp_nb_get */ int ftp_nb_get(ftpbuf_t *ftp, php_stream *outstream, const char *path, const size_t path_len, ftptype_t type, zend_long resumepos) { databuf_t *data = NULL; char arg[11]; if (ftp == NULL) { return PHP_FTP_FAILED; } if (!ftp_type(ftp, type)) { goto bail; } if ((data = ftp_getdata(ftp)) == NULL) { goto bail; } if (resumepos>0) { int arg_len = snprintf(arg, sizeof(arg), ZEND_LONG_FMT, resumepos); if (arg_len < 0) { goto bail; } if (!ftp_putcmd(ftp, "REST", sizeof("REST")-1, arg, arg_len)) { goto bail; } if (!ftp_getresp(ftp) || (ftp->resp != 350)) { goto bail; } } if (!ftp_putcmd(ftp, "RETR", sizeof("RETR")-1, path, path_len)) { goto bail; } if (!ftp_getresp(ftp) || (ftp->resp != 150 && ftp->resp != 125)) { goto bail; } if ((data = data_accept(data, ftp)) == NULL) { goto bail; } ftp->data = data; ftp->stream = outstream; ftp->lastch = 0; ftp->nb = 1; return (ftp_nb_continue_read(ftp)); bail: ftp->data = data_close(ftp, data); return PHP_FTP_FAILED; }
/* {{{ ftp_nb_put */ int ftp_nb_put(ftpbuf_t *ftp, const char *path, php_stream *instream, ftptype_t type, zend_long startpos) { databuf_t *data = NULL; char arg[11]; if (ftp == NULL) { return 0; } if (!ftp_type(ftp, type)) { goto bail; } if ((data = ftp_getdata(ftp)) == NULL) { goto bail; } if (startpos > 0) { snprintf(arg, sizeof(arg), ZEND_LONG_FMT, startpos); if (!ftp_putcmd(ftp, "REST", arg)) { goto bail; } if (!ftp_getresp(ftp) || (ftp->resp != 350)) { goto bail; } } if (!ftp_putcmd(ftp, "STOR", path)) { goto bail; } if (!ftp_getresp(ftp) || (ftp->resp != 150 && ftp->resp != 125)) { goto bail; } if ((data = data_accept(data, ftp)) == NULL) { goto bail; } ftp->data = data; ftp->stream = instream; ftp->lastch = 0; ftp->nb = 1; return (ftp_nb_continue_write(ftp)); bail: ftp->data = data_close(ftp, data); return PHP_FTP_FAILED; }
/* {{{ ftp_put */ int ftp_put(ftpbuf_t *ftp, const char *path, php_stream *instream, ftptype_t type, zend_long startpos) { databuf_t *data = NULL; zend_long size; char *ptr; int ch; char arg[11]; if (ftp == NULL) { return 0; } if (!ftp_type(ftp, type)) { goto bail; } if ((data = ftp_getdata(ftp)) == NULL) { goto bail; } ftp->data = data; if (startpos > 0) { snprintf(arg, sizeof(arg), ZEND_LONG_FMT, startpos); if (!ftp_putcmd(ftp, "REST", arg)) { goto bail; } if (!ftp_getresp(ftp) || (ftp->resp != 350)) { goto bail; } } if (!ftp_putcmd(ftp, "STOR", path)) { goto bail; } if (!ftp_getresp(ftp) || (ftp->resp != 150 && ftp->resp != 125)) { goto bail; } if ((data = data_accept(data, ftp)) == NULL) { goto bail; } size = 0; ptr = data->buf; while (!php_stream_eof(instream) && (ch = php_stream_getc(instream))!=EOF) { /* flush if necessary */ if (FTP_BUFSIZE - size < 2) { if (my_send(ftp, 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(ftp, data->fd, data->buf, size) != size) { goto bail; } ftp->data = data = data_close(ftp, data); if (!ftp_getresp(ftp) || (ftp->resp != 226 && ftp->resp != 250 && ftp->resp != 200)) { goto bail; } return 1; bail: ftp->data = data_close(ftp, data); return 0; }
/* {{{ ftp_get */ int ftp_get(ftpbuf_t *ftp, php_stream *outstream, const char *path, ftptype_t type, zend_long resumepos) { databuf_t *data = NULL; size_t rcvd; char arg[11]; if (ftp == NULL) { return 0; } if (!ftp_type(ftp, type)) { goto bail; } if ((data = ftp_getdata(ftp)) == NULL) { goto bail; } ftp->data = data; if (resumepos > 0) { snprintf(arg, sizeof(arg), ZEND_LONG_FMT, resumepos); if (!ftp_putcmd(ftp, "REST", arg)) { goto bail; } if (!ftp_getresp(ftp) || (ftp->resp != 350)) { goto bail; } } if (!ftp_putcmd(ftp, "RETR", path)) { goto bail; } if (!ftp_getresp(ftp) || (ftp->resp != 150 && ftp->resp != 125)) { goto bail; } if ((data = data_accept(data, ftp)) == NULL) { goto bail; } while ((rcvd = my_recv(ftp, data->fd, data->buf, FTP_BUFSIZE))) { if (rcvd == -1) { goto bail; } if (type == FTPTYPE_ASCII) { #ifndef PHP_WIN32 char *s; #endif char *ptr = data->buf; char *e = ptr + rcvd; /* logic depends on the OS EOL * Win32 -> \r\n * Everything Else \n */ #ifdef PHP_WIN32 php_stream_write(outstream, ptr, (e - ptr)); ptr = e; #else while (e > ptr && (s = memchr(ptr, '\r', (e - ptr)))) { php_stream_write(outstream, ptr, (s - ptr)); if (*(s + 1) == '\n') { s++; php_stream_putc(outstream, '\n'); } ptr = s + 1; } #endif if (ptr < e) { php_stream_write(outstream, ptr, (e - ptr)); } } else if (rcvd != php_stream_write(outstream, data->buf, rcvd)) { goto bail; } } ftp->data = data = data_close(ftp, data); if (!ftp_getresp(ftp) || (ftp->resp != 226 && ftp->resp != 250)) { goto bail; } return 1; bail: ftp->data = data_close(ftp, data); return 0; }
int 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) return 0; if (!ftp_type(ftp, type)) goto bail; if ((data = ftp_getdata(ftp)) == NULL) goto bail; if (!ftp_putcmd(ftp, "STOR", path)) goto bail; if (!ftp_getresp(ftp) || (ftp->resp != 150 && ftp->resp != 125)) goto bail; if ((data = data_accept(data)) == NULL) goto bail; size = 0; ptr = data->buf; while ((ch = getc(infp)) != EOF) { /* 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(infp)) goto bail; data = data_close(data); if (!ftp_getresp(ftp) || (ftp->resp != 226 && ftp->resp != 250)) goto bail; return 1; bail: data_close(data); return 0; }