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_chmod */ int ftp_chmod(ftpbuf_t *ftp, const int mode, const char *filename, const int filename_len) { char *buffer; size_t buffer_len; if (ftp == NULL || filename_len <= 0) { return 0; } buffer_len = spprintf(&buffer, 0, "CHMOD %o %s", mode, filename); if (!buffer) { return 0; } if (!ftp_putcmd(ftp, "SITE", sizeof("SITE")-1, buffer, buffer_len)) { efree(buffer); return 0; } efree(buffer); if (!ftp_getresp(ftp) || ftp->resp != 200) { return 0; } return 1; }
/* {{{ ftp_type */ int ftp_type(ftpbuf_t *ftp, ftptype_t type) { const char *typechar; if (ftp == NULL) { return 0; } if (type == ftp->type) { return 1; } if (type == FTPTYPE_ASCII) { typechar = "A"; } else if (type == FTPTYPE_IMAGE) { typechar = "I"; } else { return 0; } if (!ftp_putcmd(ftp, "TYPE", sizeof("TYPE")-1, typechar, 1)) { return 0; } if (!ftp_getresp(ftp) || ftp->resp != 200) { return 0; } ftp->type = type; return 1; }
/* {{{ ftp_syst */ const char* ftp_syst(ftpbuf_t *ftp) { char *syst, *end; if (ftp == NULL) { return NULL; } /* default to cached value */ if (ftp->syst) { return ftp->syst; } if (!ftp_putcmd(ftp, "SYST", NULL)) { return NULL; } if (!ftp_getresp(ftp) || ftp->resp != 215) { return NULL; } syst = ftp->inbuf; while (*syst == ' ') { syst++; } if ((end = strchr(syst, ' '))) { *end = 0; } ftp->syst = estrdup(syst); if (end) { *end = ' '; } return ftp->syst; }
char* ftp_mkdir(ftpbuf_t *ftp, const char *dir) { char *mkd, *end; if (ftp == NULL) return NULL; if (!ftp_putcmd(ftp, "MKD", dir)) return NULL; if (!ftp_getresp(ftp) || ftp->resp != 257) return NULL; /* copy out the dir from response */ if ((mkd = strchr(ftp->inbuf, '"')) == NULL) { mkd = strdup(dir); return mkd; } end = strrchr(++mkd, '"'); *end = 0; mkd = strdup(mkd); *end = '"'; return mkd; }
/* {{{ ftp_pwd */ const char* ftp_pwd(ftpbuf_t *ftp) { char *pwd, *end; if (ftp == NULL) { return NULL; } /* default to cached value */ if (ftp->pwd) { return ftp->pwd; } if (!ftp_putcmd(ftp, "PWD", NULL)) { return NULL; } if (!ftp_getresp(ftp) || ftp->resp != 257) { return NULL; } /* copy out the pwd from response */ if ((pwd = strchr(ftp->inbuf, '"')) == NULL) { return NULL; } if ((end = strrchr(++pwd, '"')) == NULL) { return NULL; } ftp->pwd = estrndup(pwd, end - pwd); return ftp->pwd; }
/* {{{ ftp_mkdir */ zend_string* ftp_mkdir(ftpbuf_t *ftp, const char *dir) { char *mkd, *end; zend_string *ret; if (ftp == NULL) { return NULL; } if (!ftp_putcmd(ftp, "MKD", dir)) { return NULL; } if (!ftp_getresp(ftp) || ftp->resp != 257) { return NULL; } /* copy out the dir from response */ if ((mkd = strchr(ftp->inbuf, '"')) == NULL) { return zend_string_init(dir, strlen(dir), 0); } if ((end = strrchr(++mkd, '"')) == NULL) { return NULL; } *end = 0; ret = zend_string_init(mkd, end - mkd, 0); *end = '"'; return ret; }
/* {{{ ftp_alloc */ int ftp_alloc(ftpbuf_t *ftp, const zend_long size, zend_string **response) { char buffer[64]; if (ftp == NULL || size <= 0) { return 0; } snprintf(buffer, sizeof(buffer) - 1, ZEND_LONG_FMT, size); if (!ftp_putcmd(ftp, "ALLO", buffer)) { return 0; } if (!ftp_getresp(ftp)) { return 0; } if (response) { *response = zend_string_init(ftp->inbuf, strlen(ftp->inbuf), 0); } if (ftp->resp < 200 || ftp->resp >= 300) { return 0; } return 1; }
const char* ftp_pwd(ftpbuf_t *ftp) { char *pwd, *end; if (ftp == NULL) return NULL; /* default to cached value */ if (ftp->pwd) return ftp->pwd; if (!ftp_putcmd(ftp, "PWD", NULL)) return NULL; if (!ftp_getresp(ftp) || ftp->resp != 257) return NULL; /* copy out the pwd from response */ if ((pwd = strchr(ftp->inbuf, '"')) == NULL) return NULL; end = strrchr(++pwd, '"'); *end = 0; ftp->pwd = strdup(pwd); *end = '"'; return ftp->pwd; }
const char* ftp_syst(ftpbuf_t *ftp) { char *syst, *end; if (ftp == NULL) return NULL; /* default to cached value */ if (ftp->syst) return ftp->syst; if (!ftp_putcmd(ftp, "SYST", NULL)) return NULL; if (!ftp_getresp(ftp) || ftp->resp != 215) return NULL; syst = ftp->inbuf; if ((end = strchr(syst, ' '))) *end = 0; ftp->syst = strdup(syst); if (end) *end = ' '; return ftp->syst; }
/* {{{ ftp_type */ int ftp_type(ftpbuf_t *ftp, ftptype_t type) { char typechar[2] = "?"; if (ftp == NULL) { return 0; } if (type == ftp->type) { return 1; } if (type == FTPTYPE_ASCII) { typechar[0] = 'A'; } else if (type == FTPTYPE_IMAGE) { typechar[0] = 'I'; } else { return 0; } if (!ftp_putcmd(ftp, "TYPE", typechar)) { return 0; } if (!ftp_getresp(ftp) || ftp->resp != 200) { return 0; } ftp->type = type; return 1; }
/* {{{ ftp_nb_continue_read */ int ftp_nb_continue_read(ftpbuf_t *ftp) { databuf_t *data = NULL; char *ptr; int lastch; size_t rcvd; ftptype_t type; data = ftp->data; /* check if there is already more data */ if (!data_available(ftp, data->fd)) { return PHP_FTP_MOREDATA; } type = ftp->type; lastch = ftp->lastch; if ((rcvd = my_recv(ftp, 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') { php_stream_putc(ftp->stream, '\r'); } if (*ptr != '\r') { php_stream_putc(ftp->stream, *ptr); } lastch = *ptr; } } else if (rcvd != php_stream_write(ftp->stream, data->buf, rcvd)) { goto bail; } ftp->lastch = lastch; return PHP_FTP_MOREDATA; } if (type == FTPTYPE_ASCII && lastch == '\r') { php_stream_putc(ftp->stream, '\r'); } ftp->data = data = data_close(ftp, data); if (!ftp_getresp(ftp) || (ftp->resp != 226 && ftp->resp != 250)) { goto bail; } ftp->nb = 0; return PHP_FTP_FINISHED; bail: ftp->nb = 0; 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; }
int ftp_rename(ftpbuf_t *ftp, const char *src, const char *dest) { if (ftp == NULL) return 0; if (!ftp_putcmd(ftp, "RNFR", src)) return 0; if (!ftp_getresp(ftp) || ftp->resp != 350) return 0; if (!ftp_putcmd(ftp, "RNTO", dest)) return 0; if (!ftp_getresp(ftp) || ftp->resp != 250) return 0; return 1; }
/* {{{ ftp_rename */ int ftp_rename(ftpbuf_t *ftp, const char *src, const size_t src_len, const char *dest, const size_t dest_len) { if (ftp == NULL) { return 0; } if (!ftp_putcmd(ftp, "RNFR", sizeof("RNFR")-1, src, src_len)) { return 0; } if (!ftp_getresp(ftp) || ftp->resp != 350) { return 0; } if (!ftp_putcmd(ftp, "RNTO", sizeof("RNTO")-1, dest, dest_len)) { return 0; } if (!ftp_getresp(ftp) || ftp->resp != 250) { return 0; } return 1; }
int ftp_login(ftpbuf_t *ftp, const char *user, const char *pass) { if (ftp == NULL) return 0; 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; if (!ftp_getresp(ftp)) return 0; return (ftp->resp == 230); }
int ftp_exec(ftpbuf_t *ftp, const char *cmd) { if (ftp == NULL) return 0; if (!ftp_putcmd(ftp, "SITE EXEC", cmd)) return 0; if (!ftp_getresp(ftp) || ftp->resp != 200) return 0; return 1; }
int ftp_rmdir(ftpbuf_t *ftp, const char *dir) { if (ftp == NULL) return 0; if (!ftp_putcmd(ftp, "RMD", dir)) return 0; if (!ftp_getresp(ftp) || ftp->resp != 250) return 0; return 1; }
int ftp_size(ftpbuf_t *ftp, const char *path) { if (ftp == NULL) return -1; if (!ftp_putcmd(ftp, "SIZE", path)) return -1; if (!ftp_getresp(ftp) || ftp->resp != 213) return -1; return atoi(ftp->inbuf); }
int ftp_site(ftpbuf_t *ftp, const char *cmd) { if (ftp == NULL) return 0; if (!ftp_putcmd(ftp, "SITE", cmd)) return 0; if (!ftp_getresp(ftp) || ftp->resp < 200 || ftp->resp >= 300) return 0; return 1; }
int ftp_delete(ftpbuf_t *ftp, const char *path) { if (ftp == NULL) return 0; if (!ftp_putcmd(ftp, "DELE", path)) return 0; if (!ftp_getresp(ftp) || ftp->resp != 250) return 0; return 1; }
/* {{{ ftp_rmdir */ int ftp_rmdir(ftpbuf_t *ftp, const char *dir, const size_t dir_len) { if (ftp == NULL) { return 0; } if (!ftp_putcmd(ftp, "RMD", sizeof("RMD")-1, dir, dir_len)) { return 0; } if (!ftp_getresp(ftp) || ftp->resp != 250) { return 0; } return 1; }
/* {{{ ftp_delete */ int ftp_delete(ftpbuf_t *ftp, const char *path, const size_t path_len) { if (ftp == NULL) { return 0; } if (!ftp_putcmd(ftp, "DELE", sizeof("DELE")-1, path, path_len)) { return 0; } if (!ftp_getresp(ftp) || ftp->resp != 250) { return 0; } return 1; }
/* {{{ ftp_exec */ int ftp_exec(ftpbuf_t *ftp, const char *cmd, const size_t cmd_len) { if (ftp == NULL) { return 0; } if (!ftp_putcmd(ftp, "SITE EXEC", sizeof("SITE EXEC")-1, cmd, cmd_len)) { return 0; } if (!ftp_getresp(ftp) || ftp->resp != 200) { return 0; } return 1; }
int ftp_reinit(ftpbuf_t *ftp) { if (ftp == NULL) return 0; ftp_gc(ftp); if (!ftp_putcmd(ftp, "REIN", NULL)) return 0; if (!ftp_getresp(ftp) || ftp->resp != 220) return 0; return 1; }
/* {{{ ftp_site */ int ftp_site(ftpbuf_t *ftp, const char *cmd, const size_t cmd_len) { if (ftp == NULL) { return 0; } if (!ftp_putcmd(ftp, "SITE", sizeof("SITE")-1, cmd, cmd_len)) { return 0; } if (!ftp_getresp(ftp) || ftp->resp < 200 || ftp->resp >= 300) { return 0; } return 1; }
/* {{{ ftp_nb_continue_write */ int ftp_nb_continue_write(ftpbuf_t *ftp) { long size; char *ptr; int ch; /* check if we can write more data */ if (!data_writeable(ftp, ftp->data->fd)) { return PHP_FTP_MOREDATA; } size = 0; ptr = ftp->data->buf; while (!php_stream_eof(ftp->stream) && (ch = php_stream_getc(ftp->stream)) != EOF) { if (ch == '\n' && ftp->type == FTPTYPE_ASCII) { *ptr++ = '\r'; size++; } *ptr++ = ch; size++; /* flush if necessary */ if (FTP_BUFSIZE - size < 2) { if (my_send(ftp, ftp->data->fd, ftp->data->buf, size) != size) { goto bail; } return PHP_FTP_MOREDATA; } } if (size && my_send(ftp, ftp->data->fd, ftp->data->buf, size) != size) { goto bail; } ftp->data = data_close(ftp, ftp->data); if (!ftp_getresp(ftp) || (ftp->resp != 226 && ftp->resp != 250)) { goto bail; } ftp->nb = 0; return PHP_FTP_FINISHED; bail: ftp->data = data_close(ftp, ftp->data); ftp->nb = 0; return PHP_FTP_FAILED; }
int ftp_chdir(ftpbuf_t *ftp, const char *dir) { if (ftp == NULL) return 0; free(ftp->pwd); ftp->pwd = NULL; if (!ftp_putcmd(ftp, "CWD", dir)) return 0; if (!ftp_getresp(ftp) || ftp->resp != 250) return 0; return 1; }
int ftp_cdup(ftpbuf_t *ftp) { if (ftp == NULL) return 0; free(ftp->pwd); ftp->pwd = NULL; if (!ftp_putcmd(ftp, "CDUP", NULL)) return 0; if (!ftp_getresp(ftp) || ftp->resp != 250) return 0; return 1; }