Lines Matching refs:data
146 static void _ftp_state(struct Curl_easy *data, in _ftp_state() argument
153 struct connectdata *conn = data->conn; in _ftp_state()
163 CURL_TRC_FTP(data, "[%s] -> [%s] (line %d)", FTP_DSTATE(data), in _ftp_state()
166 CURL_TRC_FTP(data, "[%s] -> [%s]", FTP_DSTATE(data), in _ftp_state()
182 static CURLcode ftp_sendquote(struct Curl_easy *data,
185 static CURLcode ftp_quit(struct Curl_easy *data, struct connectdata *conn);
186 static CURLcode ftp_parse_url_path(struct Curl_easy *data);
187 static CURLcode ftp_regular_transfer(struct Curl_easy *data, bool *done);
189 static void ftp_pasv_verbose(struct Curl_easy *data,
194 static CURLcode ftp_state_prepare_transfer(struct Curl_easy *data);
195 static CURLcode ftp_state_mdtm(struct Curl_easy *data);
196 static CURLcode ftp_state_quote(struct Curl_easy *data,
198 static CURLcode ftp_nb_type(struct Curl_easy *data,
203 static CURLcode ftp_do(struct Curl_easy *data, bool *done);
204 static CURLcode ftp_done(struct Curl_easy *data,
206 static CURLcode ftp_connect(struct Curl_easy *data, bool *done);
207 static CURLcode ftp_disconnect(struct Curl_easy *data,
209 static CURLcode ftp_do_more(struct Curl_easy *data, int *completed);
210 static CURLcode ftp_multi_statemach(struct Curl_easy *data, bool *done);
211 static int ftp_getsock(struct Curl_easy *data, struct connectdata *conn,
213 static int ftp_domore_getsock(struct Curl_easy *data,
215 static CURLcode ftp_doing(struct Curl_easy *data,
217 static CURLcode ftp_setup_connection(struct Curl_easy *data,
219 static CURLcode init_wc_data(struct Curl_easy *data);
220 static CURLcode wc_statemach(struct Curl_easy *data);
222 static CURLcode ftp_state_retr(struct Curl_easy *data, curl_off_t filesize);
223 static CURLcode ftp_readresp(struct Curl_easy *data,
228 static CURLcode ftp_dophase_done(struct Curl_easy *data,
293 static void close_secondarysocket(struct Curl_easy *data) in close_secondarysocket() argument
295 CURL_TRC_FTP(data, "[%s] closing DATA connection", FTP_DSTATE(data)); in close_secondarysocket()
296 Curl_conn_close(data, SECONDARYSOCKET); in close_secondarysocket()
297 Curl_conn_cf_discard_all(data, data->conn, SECONDARYSOCKET); in close_secondarysocket()
343 static CURLcode ftp_cw_lc_write(struct Curl_easy *data, in ftp_cw_lc_write() argument
351 data->conn->proto.ftpc.transfertype != 'A') in ftp_cw_lc_write()
352 return Curl_cwriter_write(data, writer->next, type, buf, blen); in ftp_cw_lc_write()
366 result = Curl_cwriter_write(data, writer->next, chunk_type, &nl, 1); in ftp_cw_lc_write()
382 result = Curl_cwriter_write(data, writer->next, chunk_type, in ftp_cw_lc_write()
396 return Curl_cwriter_write(data, writer->next, type, buf, blen); in ftp_cw_lc_write()
402 return Curl_cwriter_write(data, writer->next, type, &nl, 1); in ftp_cw_lc_write()
405 return Curl_cwriter_write(data, writer->next, type, buf, 0); in ftp_cw_lc_write()
425 static CURLcode ftp_check_ctrl_on_data_wait(struct Curl_easy *data) in ftp_check_ctrl_on_data_wait() argument
427 struct connectdata *conn = data->conn; in ftp_check_ctrl_on_data_wait()
438 infof(data, "There is negative response in cache while serv connect"); in ftp_check_ctrl_on_data_wait()
439 (void)Curl_GetFTPResponse(data, &nread, &ftpcode); in ftp_check_ctrl_on_data_wait()
453 failf(data, "Error while waiting for server connect"); in ftp_check_ctrl_on_data_wait()
463 infof(data, "Ctrl conn has data while waiting for data conn"); in ftp_check_ctrl_on_data_wait()
479 infof(data, "Got 226 before data activity"); in ftp_check_ctrl_on_data_wait()
485 (void)Curl_GetFTPResponse(data, &nread, &ftpcode); in ftp_check_ctrl_on_data_wait()
487 infof(data, "FTP code: %03d", ftpcode); in ftp_check_ctrl_on_data_wait()
506 static CURLcode InitiateTransfer(struct Curl_easy *data) in InitiateTransfer() argument
509 struct connectdata *conn = data->conn; in InitiateTransfer()
512 CURL_TRC_FTP(data, "InitiateTransfer()"); in InitiateTransfer()
513 result = Curl_conn_connect(data, SECONDARYSOCKET, TRUE, &connected); in InitiateTransfer()
520 Curl_pgrsSetUploadSize(data, data->state.infilesize); in InitiateTransfer()
527 Curl_xfer_setup2(data, CURL_XFER_SEND, -1, TRUE, TRUE); in InitiateTransfer()
531 Curl_xfer_setup2(data, CURL_XFER_RECV, in InitiateTransfer()
536 ftp_state(data, FTP_STOP); in InitiateTransfer()
541 static bool ftp_endofresp(struct Curl_easy *data, struct connectdata *conn, in ftp_endofresp() argument
544 (void)data; in ftp_endofresp()
555 static CURLcode ftp_readresp(struct Curl_easy *data, in ftp_readresp() argument
562 CURLcode result = Curl_pp_readresp(data, sockindex, pp, &code, size); in ftp_readresp()
566 struct connectdata *conn = data->conn; in ftp_readresp()
567 char * const buf = Curl_dyn_ptr(&data->conn->proto.ftpc.pp.recvbuf); in ftp_readresp()
572 code = Curl_sec_read_msg(data, conn, buf, PROT_SAFE); in ftp_readresp()
575 code = Curl_sec_read_msg(data, conn, buf, PROT_PRIVATE); in ftp_readresp()
578 code = Curl_sec_read_msg(data, conn, buf, PROT_CONFIDENTIAL); in ftp_readresp()
588 data->info.httpcode = code; in ftp_readresp()
601 infof(data, "We got a 421 - timeout"); in ftp_readresp()
602 ftp_state(data, FTP_STOP); in ftp_readresp()
617 CURLcode Curl_GetFTPResponse(struct Curl_easy *data, in Curl_GetFTPResponse() argument
628 struct connectdata *conn = data->conn; in Curl_GetFTPResponse()
637 CURL_TRC_FTP(data, "getFTPResponse start"); in Curl_GetFTPResponse()
649 timediff_t timeout = Curl_pp_state_timeout(data, pp, FALSE); in Curl_GetFTPResponse()
653 failf(data, "FTP response timeout"); in Curl_GetFTPResponse()
683 else if(!Curl_conn_data_pending(data, FIRSTSOCKET)) { in Curl_GetFTPResponse()
684 curl_socket_t wsock = Curl_pp_needs_flush(data, pp) ? in Curl_GetFTPResponse()
688 failf(data, "FTP response aborted due to select/poll error: %d", in Curl_GetFTPResponse()
693 if(Curl_pgrsUpdate(data)) in Curl_GetFTPResponse()
699 if(Curl_pp_needs_flush(data, pp)) { in Curl_GetFTPResponse()
700 result = Curl_pp_flushsend(data, pp); in Curl_GetFTPResponse()
705 result = ftp_readresp(data, FIRSTSOCKET, pp, ftpcode, &nread); in Curl_GetFTPResponse()
723 CURL_TRC_FTP(data, "getFTPResponse -> result=%d, nread=%zd, ftpcode=%d", in Curl_GetFTPResponse()
729 static CURLcode ftp_state_user(struct Curl_easy *data, in ftp_state_user() argument
732 CURLcode result = Curl_pp_sendf(data, in ftp_state_user()
738 ftp_state(data, FTP_USER); in ftp_state_user()
743 static CURLcode ftp_state_pwd(struct Curl_easy *data, in ftp_state_pwd() argument
746 CURLcode result = Curl_pp_sendf(data, &conn->proto.ftpc.pp, "%s", "PWD"); in ftp_state_pwd()
748 ftp_state(data, FTP_PWD); in ftp_state_pwd()
754 static int ftp_getsock(struct Curl_easy *data, in ftp_getsock() argument
758 return Curl_pp_getsock(data, &conn->proto.ftpc.pp, socks); in ftp_getsock()
762 static int ftp_domore_getsock(struct Curl_easy *data, in ftp_domore_getsock() argument
766 (void)data; in ftp_domore_getsock()
772 CURL_TRC_FTP(data, "[%s] ftp_domore_getsock()", FTP_DSTATE(data)); in ftp_domore_getsock()
785 return Curl_pp_getsock(data, &conn->proto.ftpc.pp, socks); in ftp_domore_getsock()
794 static CURLcode ftp_state_cwd(struct Curl_easy *data, in ftp_state_cwd() argument
802 result = ftp_state_mdtm(data); in ftp_state_cwd()
805 DEBUGASSERT((data->set.ftp_filemethod != FTPFILE_NOCWD) || in ftp_state_cwd()
818 result = Curl_pp_sendf(data, &ftpc->pp, "CWD %s", ftpc->entrypath); in ftp_state_cwd()
820 ftp_state(data, FTP_CWD); in ftp_state_cwd()
827 result = Curl_pp_sendf(data, &ftpc->pp, "CWD %s", in ftp_state_cwd()
830 ftp_state(data, FTP_CWD); in ftp_state_cwd()
834 result = ftp_state_mdtm(data); in ftp_state_cwd()
847 static CURLcode ftp_state_use_port(struct Curl_easy *data, in ftp_state_use_port() argument
851 struct connectdata *conn = data->conn; in ftp_state_use_port()
869 char *string_ftpport = data->set.str[STRING_FTPPORT]; in ftp_state_use_port()
885 if(data->set.str[STRING_FTPPORT] && in ftp_state_use_port()
886 (strlen(data->set.str[STRING_FTPPORT]) > 1)) { in ftp_state_use_port()
984 failf(data, "getsockname() failed: %s", in ftp_state_use_port()
1006 rc = Curl_resolv(data, host, 0, FALSE, &dns_entry); in ftp_state_use_port()
1008 (void)Curl_resolver_wait_resolv(data, &dns_entry); in ftp_state_use_port()
1016 failf(data, "failed to resolve the address provided to PORT: %s", host); in ftp_state_use_port()
1025 if(Curl_socket_open(data, ai, NULL, conn->transport, &portsock)) { in ftp_state_use_port()
1032 failf(data, "socket failure: %s", in ftp_state_use_port()
1036 CURL_TRC_FTP(data, "[%s] ftp_state_use_port(), opened socket", in ftp_state_use_port()
1037 FTP_DSTATE(data)); in ftp_state_use_port()
1059 infof(data, "bind(port=%hu) on non-local address failed: %s", port, in ftp_state_use_port()
1064 failf(data, "getsockname() failed: %s", in ftp_state_use_port()
1073 failf(data, "bind(port=%hu) failed: %s", port, in ftp_state_use_port()
1086 failf(data, "bind() failed, we ran out of ports"); in ftp_state_use_port()
1094 failf(data, "getsockname() failed: %s", in ftp_state_use_port()
1098 CURL_TRC_FTP(data, "[%s] ftp_state_use_port(), socket bound to port %d", in ftp_state_use_port()
1099 FTP_DSTATE(data), port); in ftp_state_use_port()
1104 failf(data, "socket failure: %s", in ftp_state_use_port()
1108 CURL_TRC_FTP(data, "[%s] ftp_state_use_port(), listening on %d", in ftp_state_use_port()
1109 FTP_DSTATE(data), port); in ftp_state_use_port()
1156 result = Curl_pp_sendf(data, &ftpc->pp, "%s |%d|%s|%hu|", mode[fcmd], in ftp_state_use_port()
1160 failf(data, "Failure sending EPRT command: %s", in ftp_state_use_port()
1184 result = Curl_pp_sendf(data, &ftpc->pp, "%s %s", mode[fcmd], target); in ftp_state_use_port()
1186 failf(data, "Failure sending PORT command: %s", in ftp_state_use_port()
1196 ftp_state(data, FTP_PORT); in ftp_state_use_port()
1199 result = Curl_conn_tcp_listen_set(data, conn, SECONDARYSOCKET, &portsock); in ftp_state_use_port()
1206 Curl_resolv_unlink(data, &dns_entry); in ftp_state_use_port()
1208 ftp_state(data, FTP_STOP); in ftp_state_use_port()
1212 if(conn->bits.ftp_use_data_ssl && data->set.ftp_use_port && in ftp_state_use_port()
1214 result = Curl_ssl_cfilter_add(data, conn, SECONDARYSOCKET); in ftp_state_use_port()
1216 data->conn->bits.do_more = FALSE; in ftp_state_use_port()
1217 Curl_pgrsTime(data, TIMER_STARTACCEPT); in ftp_state_use_port()
1218 Curl_expire(data, data->set.accepttimeout ? in ftp_state_use_port()
1219 data->set.accepttimeout: DEFAULT_ACCEPT_TIMEOUT, in ftp_state_use_port()
1223 Curl_socket_close(data, conn, portsock); in ftp_state_use_port()
1227 static CURLcode ftp_state_use_pasv(struct Curl_easy *data, in ftp_state_use_pasv() argument
1258 result = Curl_pp_sendf(data, &ftpc->pp, "%s", mode[modeoff]); in ftp_state_use_pasv()
1261 ftp_state(data, FTP_PASV); in ftp_state_use_pasv()
1262 infof(data, "Connect data stream passively"); in ftp_state_use_pasv()
1274 static CURLcode ftp_state_prepare_transfer(struct Curl_easy *data) in ftp_state_prepare_transfer() argument
1277 struct FTP *ftp = data->req.p.ftp; in ftp_state_prepare_transfer()
1278 struct connectdata *conn = data->conn; in ftp_state_prepare_transfer()
1284 ftp_state(data, FTP_RETR_PREQUOTE); in ftp_state_prepare_transfer()
1285 result = ftp_state_quote(data, TRUE, FTP_RETR_PREQUOTE); in ftp_state_prepare_transfer()
1287 else if(data->set.ftp_use_port) { in ftp_state_prepare_transfer()
1289 result = ftp_state_use_port(data, EPRT); in ftp_state_prepare_transfer()
1293 if(data->set.ftp_use_pret) { in ftp_state_prepare_transfer()
1298 result = Curl_pp_sendf(data, &ftpc->pp, "PRET %s", in ftp_state_prepare_transfer()
1299 data->set.str[STRING_CUSTOMREQUEST] ? in ftp_state_prepare_transfer()
1300 data->set.str[STRING_CUSTOMREQUEST] : in ftp_state_prepare_transfer()
1301 (data->state.list_only ? "NLST" : "LIST")); in ftp_state_prepare_transfer()
1302 else if(data->state.upload) in ftp_state_prepare_transfer()
1303 result = Curl_pp_sendf(data, &ftpc->pp, "PRET STOR %s", in ftp_state_prepare_transfer()
1306 result = Curl_pp_sendf(data, &ftpc->pp, "PRET RETR %s", in ftp_state_prepare_transfer()
1309 ftp_state(data, FTP_PRET); in ftp_state_prepare_transfer()
1312 result = ftp_state_use_pasv(data, conn); in ftp_state_prepare_transfer()
1317 static CURLcode ftp_state_rest(struct Curl_easy *data, in ftp_state_rest() argument
1321 struct FTP *ftp = data->req.p.ftp; in ftp_state_rest()
1329 result = Curl_pp_sendf(data, &ftpc->pp, "REST %d", 0); in ftp_state_rest()
1331 ftp_state(data, FTP_REST); in ftp_state_rest()
1334 result = ftp_state_prepare_transfer(data); in ftp_state_rest()
1339 static CURLcode ftp_state_size(struct Curl_easy *data, in ftp_state_size() argument
1343 struct FTP *ftp = data->req.p.ftp; in ftp_state_size()
1350 result = Curl_pp_sendf(data, &ftpc->pp, "SIZE %s", ftpc->file); in ftp_state_size()
1352 ftp_state(data, FTP_SIZE); in ftp_state_size()
1355 result = ftp_state_rest(data, conn); in ftp_state_size()
1360 static CURLcode ftp_state_list(struct Curl_easy *data) in ftp_state_list() argument
1363 struct FTP *ftp = data->req.p.ftp; in ftp_state_list()
1364 struct connectdata *conn = data->conn; in ftp_state_list()
1382 if((data->set.ftp_filemethod == FTPFILE_NOCWD) && ftp->path) { in ftp_state_list()
1406 data->set.str[STRING_CUSTOMREQUEST] ? in ftp_state_list()
1407 data->set.str[STRING_CUSTOMREQUEST] : in ftp_state_list()
1408 (data->state.list_only ? "NLST" : "LIST"), in ftp_state_list()
1416 result = Curl_pp_sendf(data, &conn->proto.ftpc.pp, "%s", cmd); in ftp_state_list()
1420 ftp_state(data, FTP_LIST); in ftp_state_list()
1425 static CURLcode ftp_state_retr_prequote(struct Curl_easy *data) in ftp_state_retr_prequote() argument
1428 return ftp_state_quote(data, TRUE, FTP_RETR_PREQUOTE); in ftp_state_retr_prequote()
1431 static CURLcode ftp_state_stor_prequote(struct Curl_easy *data) in ftp_state_stor_prequote() argument
1434 return ftp_state_quote(data, TRUE, FTP_STOR_PREQUOTE); in ftp_state_stor_prequote()
1437 static CURLcode ftp_state_type(struct Curl_easy *data) in ftp_state_type() argument
1440 struct FTP *ftp = data->req.p.ftp; in ftp_state_type()
1441 struct connectdata *conn = data->conn; in ftp_state_type()
1447 if(data->req.no_body && ftpc->file && in ftp_state_type()
1448 ftp_need_type(conn, data->state.prefer_ascii)) { in ftp_state_type()
1458 result = ftp_nb_type(data, conn, data->state.prefer_ascii, FTP_TYPE); in ftp_state_type()
1463 result = ftp_state_size(data, conn); in ftp_state_type()
1470 static CURLcode ftp_state_mdtm(struct Curl_easy *data) in ftp_state_mdtm() argument
1473 struct connectdata *conn = data->conn; in ftp_state_mdtm()
1477 if((data->set.get_filetime || data->set.timecondition) && ftpc->file) { in ftp_state_mdtm()
1481 result = Curl_pp_sendf(data, &ftpc->pp, "MDTM %s", ftpc->file); in ftp_state_mdtm()
1484 ftp_state(data, FTP_MDTM); in ftp_state_mdtm()
1487 result = ftp_state_type(data); in ftp_state_mdtm()
1494 static CURLcode ftp_state_ul_setup(struct Curl_easy *data, in ftp_state_ul_setup() argument
1498 struct connectdata *conn = data->conn; in ftp_state_ul_setup()
1499 struct FTP *ftp = data->req.p.ftp; in ftp_state_ul_setup()
1501 bool append = data->set.remote_append; in ftp_state_ul_setup()
1503 if((data->state.resume_from && !sizechecked) || in ftp_state_ul_setup()
1504 ((data->state.resume_from > 0) && sizechecked)) { in ftp_state_ul_setup()
1519 if(data->state.resume_from < 0) { in ftp_state_ul_setup()
1521 result = Curl_pp_sendf(data, &ftpc->pp, "SIZE %s", ftpc->file); in ftp_state_ul_setup()
1523 ftp_state(data, FTP_STOR_SIZE); in ftp_state_ul_setup()
1531 if(data->set.seek_func) { in ftp_state_ul_setup()
1532 Curl_set_in_callback(data, TRUE); in ftp_state_ul_setup()
1533 seekerr = data->set.seek_func(data->set.seek_client, in ftp_state_ul_setup()
1534 data->state.resume_from, SEEK_SET); in ftp_state_ul_setup()
1535 Curl_set_in_callback(data, FALSE); in ftp_state_ul_setup()
1541 failf(data, "Could not seek stream"); in ftp_state_ul_setup()
1548 (data->state.resume_from - passed > (curl_off_t)sizeof(scratch)) ? in ftp_state_ul_setup()
1550 curlx_sotouz(data->state.resume_from - passed); in ftp_state_ul_setup()
1553 data->state.fread_func(scratch, 1, readthisamountnow, in ftp_state_ul_setup()
1554 data->state.in); in ftp_state_ul_setup()
1560 failf(data, "Failed to read data"); in ftp_state_ul_setup()
1563 } while(passed < data->state.resume_from); in ftp_state_ul_setup()
1566 if(data->state.infilesize > 0) { in ftp_state_ul_setup()
1567 data->state.infilesize -= data->state.resume_from; in ftp_state_ul_setup()
1569 if(data->state.infilesize <= 0) { in ftp_state_ul_setup()
1570 infof(data, "File already completely uploaded"); in ftp_state_ul_setup()
1573 Curl_xfer_setup_nop(data); in ftp_state_ul_setup()
1579 ftp_state(data, FTP_STOP); in ftp_state_ul_setup()
1586 result = Curl_pp_sendf(data, &ftpc->pp, append ? "APPE %s" : "STOR %s", in ftp_state_ul_setup()
1589 ftp_state(data, FTP_STOR); in ftp_state_ul_setup()
1594 static CURLcode ftp_state_quote(struct Curl_easy *data, in ftp_state_quote() argument
1599 struct FTP *ftp = data->req.p.ftp; in ftp_state_quote()
1600 struct connectdata *conn = data->conn; in ftp_state_quote()
1608 item = data->set.quote; in ftp_state_quote()
1612 item = data->set.prequote; in ftp_state_quote()
1615 item = data->set.postquote; in ftp_state_quote()
1639 char *cmd = item->data; in ftp_state_quote()
1647 result = Curl_pp_sendf(data, &ftpc->pp, "%s", cmd); in ftp_state_quote()
1650 ftp_state(data, instate); in ftp_state_quote()
1660 result = ftp_state_cwd(data, conn); in ftp_state_quote()
1664 ftp_state(data, FTP_STOP); in ftp_state_quote()
1667 Curl_pgrsSetDownloadSize(data, ftpc->known_filesize); in ftp_state_quote()
1668 result = ftp_state_retr(data, ftpc->known_filesize); in ftp_state_quote()
1671 if(data->set.ignorecl || data->state.prefer_ascii) { in ftp_state_quote()
1684 result = Curl_pp_sendf(data, &ftpc->pp, "RETR %s", ftpc->file); in ftp_state_quote()
1686 ftp_state(data, FTP_RETR); in ftp_state_quote()
1689 result = Curl_pp_sendf(data, &ftpc->pp, "SIZE %s", ftpc->file); in ftp_state_quote()
1691 ftp_state(data, FTP_RETR_SIZE); in ftp_state_quote()
1697 result = ftp_state_ul_setup(data, FALSE); in ftp_state_quote()
1709 static CURLcode ftp_epsv_disable(struct Curl_easy *data, in ftp_epsv_disable() argument
1720 failf(data, "Failed EPSV attempt, exiting"); in ftp_epsv_disable()
1724 infof(data, "Failed EPSV attempt. Disabling EPSV"); in ftp_epsv_disable()
1727 Curl_conn_close(data, SECONDARYSOCKET); in ftp_epsv_disable()
1728 Curl_conn_cf_discard_all(data, conn, SECONDARYSOCKET); in ftp_epsv_disable()
1729 data->state.errorbuf = FALSE; /* allow error message to get in ftp_epsv_disable()
1731 result = Curl_pp_sendf(data, &conn->proto.ftpc.pp, "%s", "PASV"); in ftp_epsv_disable()
1735 ftp_state(data, FTP_PASV); in ftp_epsv_disable()
1777 static CURLcode ftp_state_pasv_resp(struct Curl_easy *data, in ftp_state_pasv_resp() argument
1780 struct connectdata *conn = data->conn; in ftp_state_pasv_resp()
1810 failf(data, "Illegal port number in EPSV reply"); in ftp_state_pasv_resp()
1824 failf(data, "Weirdly formatted EPSV reply"); in ftp_state_pasv_resp()
1849 failf(data, "Couldn't interpret the 227-response"); in ftp_state_pasv_resp()
1854 if(data->set.ftp_skip_ip) { in ftp_state_pasv_resp()
1857 infof(data, "Skip %u.%u.%u.%u for data connection, reuse %s instead", in ftp_state_pasv_resp()
1872 return ftp_epsv_disable(data, conn); in ftp_state_pasv_resp()
1875 failf(data, "Bad PASV/EPSV response: %03d", ftpcode); in ftp_state_pasv_resp()
1888 rc = Curl_resolv(data, host_name, conn->primary.remote_port, FALSE, &addr); in ftp_state_pasv_resp()
1892 (void)Curl_resolver_wait_resolv(data, &addr); in ftp_state_pasv_resp()
1898 failf(data, "cannot resolve proxy host %s:%hu", host_name, connectport); in ftp_state_pasv_resp()
1916 rc = Curl_resolv(data, ftpc->newhost, ftpc->newport, FALSE, &addr); in ftp_state_pasv_resp()
1919 (void)Curl_resolver_wait_resolv(data, &addr); in ftp_state_pasv_resp()
1924 failf(data, "cannot resolve new host %s:%hu", in ftp_state_pasv_resp()
1930 result = Curl_conn_setup(data, conn, SECONDARYSOCKET, addr, in ftp_state_pasv_resp()
1935 Curl_resolv_unlink(data, &addr); /* we are done using this address */ in ftp_state_pasv_resp()
1937 return ftp_epsv_disable(data, conn); in ftp_state_pasv_resp()
1949 if(data->set.verbose) in ftp_state_pasv_resp()
1951 ftp_pasv_verbose(data, addr->addr, ftpc->newhost, connectport); in ftp_state_pasv_resp()
1953 Curl_resolv_unlink(data, &addr); /* we are done using this address */ in ftp_state_pasv_resp()
1962 ftp_state(data, FTP_STOP); /* this phase is completed */ in ftp_state_pasv_resp()
1967 static CURLcode ftp_state_port_resp(struct Curl_easy *data, in ftp_state_port_resp() argument
1970 struct connectdata *conn = data->conn; in ftp_state_port_resp()
1981 infof(data, "disabling EPRT usage"); in ftp_state_port_resp()
1987 failf(data, "Failed to do PORT"); in ftp_state_port_resp()
1992 result = ftp_state_use_port(data, fcmd); in ftp_state_port_resp()
1995 infof(data, "Connect data stream actively"); in ftp_state_port_resp()
1996 ftp_state(data, FTP_STOP); /* end of DO phase */ in ftp_state_port_resp()
1997 result = ftp_dophase_done(data, FALSE); in ftp_state_port_resp()
2027 static CURLcode client_write_header(struct Curl_easy *data, in client_write_header() argument
2045 bool save = data->set.include_header; in client_write_header()
2046 data->set.include_header = TRUE; in client_write_header()
2047 result = Curl_client_write(data, CLIENTWRITE_HEADER, buf, blen); in client_write_header()
2048 data->set.include_header = save; in client_write_header()
2052 static CURLcode ftp_state_mdtm_resp(struct Curl_easy *data, in ftp_state_mdtm_resp() argument
2056 struct FTP *ftp = data->req.p.ftp; in ftp_state_mdtm_resp()
2057 struct connectdata *conn = data->conn; in ftp_state_mdtm_resp()
2075 data->info.filetime = Curl_getdate_capped(timebuf); in ftp_state_mdtm_resp()
2082 if(data->req.no_body && in ftp_state_mdtm_resp()
2084 data->set.get_filetime && in ftp_state_mdtm_resp()
2085 (data->info.filetime >= 0) ) { in ftp_state_mdtm_resp()
2088 time_t filetime = data->info.filetime; in ftp_state_mdtm_resp()
2107 result = client_write_header(data, headerbuf, headerbuflen); in ftp_state_mdtm_resp()
2115 infof(data, "unsupported MDTM reply format"); in ftp_state_mdtm_resp()
2120 infof(data, "MDTM failed: file does not exist or permission problem," in ftp_state_mdtm_resp()
2125 if(data->set.timecondition) { in ftp_state_mdtm_resp()
2126 if((data->info.filetime > 0) && (data->set.timevalue > 0)) { in ftp_state_mdtm_resp()
2127 switch(data->set.timecondition) { in ftp_state_mdtm_resp()
2130 if(data->info.filetime <= data->set.timevalue) { in ftp_state_mdtm_resp()
2131 infof(data, "The requested document is not new enough"); in ftp_state_mdtm_resp()
2133 data->info.timecond = TRUE; in ftp_state_mdtm_resp()
2134 ftp_state(data, FTP_STOP); in ftp_state_mdtm_resp()
2139 if(data->info.filetime > data->set.timevalue) { in ftp_state_mdtm_resp()
2140 infof(data, "The requested document is not old enough"); in ftp_state_mdtm_resp()
2142 data->info.timecond = TRUE; in ftp_state_mdtm_resp()
2143 ftp_state(data, FTP_STOP); in ftp_state_mdtm_resp()
2150 infof(data, "Skipping time comparison"); in ftp_state_mdtm_resp()
2155 result = ftp_state_type(data); in ftp_state_mdtm_resp()
2160 static CURLcode ftp_state_type_resp(struct Curl_easy *data, in ftp_state_type_resp() argument
2165 struct connectdata *conn = data->conn; in ftp_state_type_resp()
2171 failf(data, "Couldn't set desired mode"); in ftp_state_type_resp()
2175 infof(data, "Got a %03d response code instead of the assumed 200", in ftp_state_type_resp()
2179 result = ftp_state_size(data, conn); in ftp_state_type_resp()
2181 result = ftp_state_list(data); in ftp_state_type_resp()
2183 result = ftp_state_retr_prequote(data); in ftp_state_type_resp()
2185 result = ftp_state_stor_prequote(data); in ftp_state_type_resp()
2190 static CURLcode ftp_state_retr(struct Curl_easy *data, in ftp_state_retr() argument
2194 struct FTP *ftp = data->req.p.ftp; in ftp_state_retr()
2195 struct connectdata *conn = data->conn; in ftp_state_retr()
2198 CURL_TRC_FTP(data, "[%s] ftp_state_retr()", FTP_DSTATE(data)); in ftp_state_retr()
2199 if(data->set.max_filesize && (filesize > data->set.max_filesize)) { in ftp_state_retr()
2200 failf(data, "Maximum file size exceeded"); in ftp_state_retr()
2205 if(data->state.resume_from) { in ftp_state_retr()
2209 infof(data, "ftp server does not support SIZE"); in ftp_state_retr()
2218 if(data->state.resume_from < 0) { in ftp_state_retr()
2220 if(filesize < -data->state.resume_from) { in ftp_state_retr()
2221 failf(data, "Offset (%" FMT_OFF_T in ftp_state_retr()
2223 data->state.resume_from, filesize); in ftp_state_retr()
2227 ftp->downloadsize = -data->state.resume_from; in ftp_state_retr()
2229 data->state.resume_from = filesize - ftp->downloadsize; in ftp_state_retr()
2232 if(filesize < data->state.resume_from) { in ftp_state_retr()
2233 failf(data, "Offset (%" FMT_OFF_T in ftp_state_retr()
2235 data->state.resume_from, filesize); in ftp_state_retr()
2239 ftp->downloadsize = filesize-data->state.resume_from; in ftp_state_retr()
2245 Curl_xfer_setup_nop(data); in ftp_state_retr()
2246 infof(data, "File already completely downloaded"); in ftp_state_retr()
2251 ftp_state(data, FTP_STOP); in ftp_state_retr()
2256 infof(data, "Instructs server to resume from offset %" FMT_OFF_T, in ftp_state_retr()
2257 data->state.resume_from); in ftp_state_retr()
2259 result = Curl_pp_sendf(data, &ftpc->pp, "REST %" FMT_OFF_T, in ftp_state_retr()
2260 data->state.resume_from); in ftp_state_retr()
2262 ftp_state(data, FTP_RETR_REST); in ftp_state_retr()
2266 result = Curl_pp_sendf(data, &ftpc->pp, "RETR %s", ftpc->file); in ftp_state_retr()
2268 ftp_state(data, FTP_RETR); in ftp_state_retr()
2274 static CURLcode ftp_state_size_resp(struct Curl_easy *data, in ftp_state_size_resp() argument
2280 char *buf = Curl_dyn_ptr(&data->conn->proto.ftpc.pp.recvbuf); in ftp_state_size_resp()
2281 size_t len = data->conn->proto.ftpc.pp.nfinal; in ftp_state_size_resp()
2307 failf(data, "The file does not exist"); in ftp_state_size_resp()
2318 result = client_write_header(data, clbuf, clbuflen); in ftp_state_size_resp()
2323 Curl_pgrsSetDownloadSize(data, filesize); in ftp_state_size_resp()
2324 result = ftp_state_rest(data, data->conn); in ftp_state_size_resp()
2327 Curl_pgrsSetDownloadSize(data, filesize); in ftp_state_size_resp()
2328 result = ftp_state_retr(data, filesize); in ftp_state_size_resp()
2331 data->state.resume_from = filesize; in ftp_state_size_resp()
2332 result = ftp_state_ul_setup(data, TRUE); in ftp_state_size_resp()
2338 static CURLcode ftp_state_rest_resp(struct Curl_easy *data, in ftp_state_rest_resp() argument
2352 result = client_write_header(data, buffer, strlen(buffer)); in ftp_state_rest_resp()
2357 result = ftp_state_prepare_transfer(data); in ftp_state_rest_resp()
2362 failf(data, "Couldn't use REST"); in ftp_state_rest_resp()
2366 result = Curl_pp_sendf(data, &ftpc->pp, "RETR %s", ftpc->file); in ftp_state_rest_resp()
2368 ftp_state(data, FTP_RETR); in ftp_state_rest_resp()
2376 static CURLcode ftp_state_stor_resp(struct Curl_easy *data, in ftp_state_stor_resp() argument
2380 struct connectdata *conn = data->conn; in ftp_state_stor_resp()
2383 failf(data, "Failed FTP upload: %0d", ftpcode); in ftp_state_stor_resp()
2384 ftp_state(data, FTP_STOP); in ftp_state_stor_resp()
2392 if(data->set.ftp_use_port) { in ftp_state_stor_resp()
2396 ftp_state(data, FTP_STOP); /* no longer in STOR state */ in ftp_state_stor_resp()
2398 result = Curl_conn_connect(data, SECONDARYSOCKET, FALSE, &connected); in ftp_state_stor_resp()
2403 infof(data, "Data conn was not available immediately"); in ftp_state_stor_resp()
2405 return ftp_check_ctrl_on_data_wait(data); in ftp_state_stor_resp()
2409 return InitiateTransfer(data); in ftp_state_stor_resp()
2413 static CURLcode ftp_state_get_resp(struct Curl_easy *data, in ftp_state_get_resp() argument
2418 struct FTP *ftp = data->req.p.ftp; in ftp_state_get_resp()
2419 struct connectdata *conn = data->conn; in ftp_state_get_resp()
2453 !data->state.prefer_ascii && in ftp_state_get_resp()
2454 !data->set.ignorecl && in ftp_state_get_resp()
2492 if(size > data->req.maxdownload && data->req.maxdownload > 0) in ftp_state_get_resp()
2493 size = data->req.size = data->req.maxdownload; in ftp_state_get_resp()
2494 else if((instate != FTP_LIST) && (data->state.prefer_ascii)) in ftp_state_get_resp()
2497 infof(data, "Maxdownload = %" FMT_OFF_T, data->req.maxdownload); in ftp_state_get_resp()
2500 infof(data, "Getting file with size: %" FMT_OFF_T, size); in ftp_state_get_resp()
2506 if(data->set.ftp_use_port) { in ftp_state_get_resp()
2510 result = Curl_conn_connect(data, SECONDARYSOCKET, FALSE, &connected); in ftp_state_get_resp()
2515 infof(data, "Data conn was not available immediately"); in ftp_state_get_resp()
2516 ftp_state(data, FTP_STOP); in ftp_state_get_resp()
2518 return ftp_check_ctrl_on_data_wait(data); in ftp_state_get_resp()
2522 return InitiateTransfer(data); in ftp_state_get_resp()
2528 ftp_state(data, FTP_STOP); /* this phase is over */ in ftp_state_get_resp()
2531 failf(data, "RETR response: %03d", ftpcode); in ftp_state_get_resp()
2542 static CURLcode ftp_state_loggedin(struct Curl_easy *data) in ftp_state_loggedin() argument
2545 struct connectdata *conn = data->conn; in ftp_state_loggedin()
2562 result = Curl_pp_sendf(data, &conn->proto.ftpc.pp, "PBSZ %d", 0); in ftp_state_loggedin()
2564 ftp_state(data, FTP_PBSZ); in ftp_state_loggedin()
2567 result = ftp_state_pwd(data, conn); in ftp_state_loggedin()
2573 static CURLcode ftp_state_user_resp(struct Curl_easy *data, in ftp_state_user_resp() argument
2577 struct connectdata *conn = data->conn; in ftp_state_user_resp()
2584 result = Curl_pp_sendf(data, &ftpc->pp, "PASS %s", in ftp_state_user_resp()
2587 ftp_state(data, FTP_PASS); in ftp_state_user_resp()
2592 result = ftp_state_loggedin(data); in ftp_state_user_resp()
2595 if(data->set.str[STRING_FTP_ACCOUNT]) { in ftp_state_user_resp()
2596 result = Curl_pp_sendf(data, &ftpc->pp, "ACCT %s", in ftp_state_user_resp()
2597 data->set.str[STRING_FTP_ACCOUNT]); in ftp_state_user_resp()
2599 ftp_state(data, FTP_ACCT); in ftp_state_user_resp()
2602 failf(data, "ACCT requested but none available"); in ftp_state_user_resp()
2612 if(data->set.str[STRING_FTP_ALTERNATIVE_TO_USER] && in ftp_state_user_resp()
2616 Curl_pp_sendf(data, &ftpc->pp, "%s", in ftp_state_user_resp()
2617 data->set.str[STRING_FTP_ALTERNATIVE_TO_USER]); in ftp_state_user_resp()
2620 ftp_state(data, FTP_USER); in ftp_state_user_resp()
2624 failf(data, "Access denied: %03d", ftpcode); in ftp_state_user_resp()
2632 static CURLcode ftp_state_acct_resp(struct Curl_easy *data, in ftp_state_acct_resp() argument
2637 failf(data, "ACCT rejected by server: %03d", ftpcode); in ftp_state_acct_resp()
2641 result = ftp_state_loggedin(data); in ftp_state_acct_resp()
2647 static CURLcode ftp_statemachine(struct Curl_easy *data, in ftp_statemachine() argument
2658 return Curl_pp_flushsend(data, pp); in ftp_statemachine()
2660 result = ftp_readresp(data, FIRSTSOCKET, pp, &ftpcode, &nread); in ftp_statemachine()
2670 if(data->set.use_ssl <= CURLUSESSL_TRY || in ftp_statemachine()
2672 return ftp_state_user_resp(data, ftpcode); in ftp_statemachine()
2675 failf(data, "Got a %03d ftp-server response when 220 was expected", in ftp_statemachine()
2682 if(data->set.krb) { in ftp_statemachine()
2689 Curl_sec_request_prot(conn, data->set.str[STRING_KRB_LEVEL]); in ftp_statemachine()
2691 if(Curl_sec_login(data, conn)) { in ftp_statemachine()
2692 failf(data, "secure login failed"); in ftp_statemachine()
2695 infof(data, "Authentication successful"); in ftp_statemachine()
2699 if(data->set.use_ssl && !conn->bits.ftp_use_control_ssl) { in ftp_statemachine()
2704 switch(data->set.ftpsslauth) { in ftp_statemachine()
2715 failf(data, "unsupported parameter to CURLOPT_FTPSSLAUTH: %d", in ftp_statemachine()
2716 (int)data->set.ftpsslauth); in ftp_statemachine()
2719 result = Curl_pp_sendf(data, &ftpc->pp, "AUTH %s", in ftp_statemachine()
2722 ftp_state(data, FTP_AUTH); in ftp_statemachine()
2725 result = ftp_state_user(data, conn); in ftp_statemachine()
2745 result = Curl_ssl_cfilter_add(data, conn, FIRSTSOCKET); in ftp_statemachine()
2751 result = Curl_conn_connect(data, FIRSTSOCKET, TRUE, &done); in ftp_statemachine()
2755 result = ftp_state_user(data, conn); in ftp_statemachine()
2761 result = Curl_pp_sendf(data, &ftpc->pp, "AUTH %s", in ftp_statemachine()
2766 if(data->set.use_ssl > CURLUSESSL_TRY) in ftp_statemachine()
2771 result = ftp_state_user(data, conn); in ftp_statemachine()
2777 result = ftp_state_user_resp(data, ftpcode); in ftp_statemachine()
2781 result = ftp_state_acct_resp(data, ftpcode); in ftp_statemachine()
2786 Curl_pp_sendf(data, &ftpc->pp, "PROT %c", in ftp_statemachine()
2787 data->set.use_ssl == CURLUSESSL_CONTROL ? 'C' : 'P'); in ftp_statemachine()
2789 ftp_state(data, FTP_PROT); in ftp_statemachine()
2796 (data->set.use_ssl != CURLUSESSL_CONTROL); in ftp_statemachine()
2799 else if(data->set.use_ssl > CURLUSESSL_CONTROL) in ftp_statemachine()
2803 if(data->set.ftp_ccc) { in ftp_statemachine()
2806 result = Curl_pp_sendf(data, &ftpc->pp, "%s", "CCC"); in ftp_statemachine()
2808 ftp_state(data, FTP_CCC); in ftp_statemachine()
2811 result = ftp_state_pwd(data, conn); in ftp_statemachine()
2822 result = Curl_ssl_cfilter_remove(data, FIRSTSOCKET, in ftp_statemachine()
2823 (data->set.ftp_ccc == CURLFTPSSL_CCC_ACTIVE)); in ftp_statemachine()
2826 failf(data, "Failed to clear the command channel (CCC)"); in ftp_statemachine()
2830 result = ftp_state_pwd(data, conn); in ftp_statemachine()
2891 result = Curl_pp_sendf(data, &ftpc->pp, "%s", "SYST"); in ftp_statemachine()
2898 infof(data, "Entry path is '%s'", ftpc->entrypath); in ftp_statemachine()
2900 data->state.most_recent_ftp_entrypath = ftpc->entrypath; in ftp_statemachine()
2901 ftp_state(data, FTP_SYST); in ftp_statemachine()
2907 infof(data, "Entry path is '%s'", ftpc->entrypath); in ftp_statemachine()
2909 data->state.most_recent_ftp_entrypath = ftpc->entrypath; in ftp_statemachine()
2914 infof(data, "Failed to figure out path"); in ftp_statemachine()
2917 ftp_state(data, FTP_STOP); /* we are done with the CONNECT phase! */ in ftp_statemachine()
2918 CURL_TRC_FTP(data, "[%s] protocol connect phase DONE", FTP_DSTATE(data)); in ftp_statemachine()
2942 result = Curl_pp_sendf(data, &ftpc->pp, "%s", "SITE NAMEFMT 1"); in ftp_statemachine()
2950 ftp_state(data, FTP_NAMEFMT); in ftp_statemachine()
2962 ftp_state(data, FTP_STOP); /* we are done with the CONNECT phase! */ in ftp_statemachine()
2963 CURL_TRC_FTP(data, "[%s] protocol connect phase DONE", FTP_DSTATE(data)); in ftp_statemachine()
2969 ftp_state_pwd(data, conn); in ftp_statemachine()
2973 ftp_state(data, FTP_STOP); /* we are done with the CONNECT phase! */ in ftp_statemachine()
2974 CURL_TRC_FTP(data, "[%s] protocol connect phase DONE", FTP_DSTATE(data)); in ftp_statemachine()
2983 failf(data, "QUOT command failed with %03d", ftpcode); in ftp_statemachine()
2987 result = ftp_state_quote(data, FALSE, ftpc->state); in ftp_statemachine()
2993 if(data->set.ftp_create_missing_dirs && in ftp_statemachine()
3001 ftpc->count3 = (data->set.ftp_create_missing_dirs == 2) ? 1 : 0; in ftp_statemachine()
3003 result = Curl_pp_sendf(data, &ftpc->pp, "MKD %s", in ftp_statemachine()
3006 ftp_state(data, FTP_MKD); in ftp_statemachine()
3010 failf(data, "Server denied you to change to the given directory"); in ftp_statemachine()
3021 result = Curl_pp_sendf(data, &ftpc->pp, "CWD %s", in ftp_statemachine()
3024 result = ftp_state_mdtm(data); in ftp_statemachine()
3031 failf(data, "Failed to MKD dir: %03d", ftpcode); in ftp_statemachine()
3035 ftp_state(data, FTP_CWD); in ftp_statemachine()
3037 result = Curl_pp_sendf(data, &ftpc->pp, "CWD %s", in ftp_statemachine()
3043 result = ftp_state_mdtm_resp(data, ftpcode); in ftp_statemachine()
3050 result = ftp_state_type_resp(data, ftpcode, ftpc->state); in ftp_statemachine()
3056 result = ftp_state_size_resp(data, ftpcode, ftpc->state); in ftp_statemachine()
3061 result = ftp_state_rest_resp(data, conn, ftpcode, ftpc->state); in ftp_statemachine()
3067 failf(data, "PRET command not accepted: %03d", ftpcode); in ftp_statemachine()
3070 result = ftp_state_use_pasv(data, conn); in ftp_statemachine()
3074 result = ftp_state_pasv_resp(data, ftpcode); in ftp_statemachine()
3078 result = ftp_state_port_resp(data, ftpcode); in ftp_statemachine()
3083 result = ftp_state_get_resp(data, ftpcode, ftpc->state); in ftp_statemachine()
3087 result = ftp_state_stor_resp(data, ftpcode, ftpc->state); in ftp_statemachine()
3093 ftp_state(data, FTP_STOP); in ftp_statemachine()
3103 static CURLcode ftp_multi_statemach(struct Curl_easy *data, in ftp_multi_statemach() argument
3106 struct connectdata *conn = data->conn; in ftp_multi_statemach()
3108 CURLcode result = Curl_pp_statemach(data, &ftpc->pp, FALSE, FALSE); in ftp_multi_statemach()
3118 static CURLcode ftp_block_statemach(struct Curl_easy *data, in ftp_block_statemach() argument
3126 result = Curl_pp_statemach(data, pp, TRUE, TRUE /* disconnecting */); in ftp_block_statemach()
3142 static CURLcode ftp_connect(struct Curl_easy *data, in ftp_connect() argument
3146 struct connectdata *conn = data->conn; in ftp_connect()
3159 result = Curl_conn_connect(data, FIRSTSOCKET, TRUE, done); in ftp_connect()
3169 ftp_state(data, FTP_WAIT220); in ftp_connect()
3171 result = ftp_multi_statemach(data, done); in ftp_connect()
3185 static CURLcode ftp_done(struct Curl_easy *data, CURLcode status, in ftp_done() argument
3188 struct connectdata *conn = data->conn; in ftp_done()
3189 struct FTP *ftp = data->req.p.ftp; in ftp_done()
3233 if(data->state.wildcardmatch) { in ftp_done()
3234 if(data->set.chunk_end && ftpc->file) { in ftp_done()
3235 Curl_set_in_callback(data, TRUE); in ftp_done()
3236 data->set.chunk_end(data->set.wildcardptr); in ftp_done()
3237 Curl_set_in_callback(data, FALSE); in ftp_done()
3255 if((data->set.ftp_filemethod == FTPFILE_NOCWD) && (rawPath[0] == '/')) in ftp_done()
3261 if(data->set.ftp_filemethod == FTPFILE_NOCWD) in ftp_done()
3277 infof(data, "Remembering we are in dir \"%s\"", ftpc->prevpath); in ftp_done()
3290 if(!result && ftpc->dont_check && data->req.maxdownload > 0) { in ftp_done()
3292 result = Curl_pp_sendf(data, pp, "%s", "ABOR"); in ftp_done()
3294 failf(data, "Failure sending ABOR command: %s", in ftp_done()
3301 close_secondarysocket(data); in ftp_done()
3317 result = Curl_GetFTPResponse(data, &nread, &ftpcode); in ftp_done()
3322 failf(data, "control connection looks dead"); in ftp_done()
3332 if(ftpc->dont_check && data->req.maxdownload > 0) { in ftp_done()
3335 infof(data, "partial download completed, closing connection"); in ftp_done()
3347 failf(data, "Exceeded storage allocation"); in ftp_done()
3351 failf(data, "server did not report OK, got %d", ftpcode); in ftp_done()
3362 else if(data->state.upload) { in ftp_done()
3363 if((-1 != data->state.infilesize) && in ftp_done()
3364 (data->state.infilesize != data->req.writebytecount) && in ftp_done()
3365 !data->set.crlf && in ftp_done()
3367 failf(data, "Uploaded unaligned file size (%" FMT_OFF_T in ftp_done()
3369 data->req.writebytecount, data->state.infilesize); in ftp_done()
3374 if((-1 != data->req.size) && in ftp_done()
3375 (data->req.size != data->req.bytecount) && in ftp_done()
3376 (data->req.maxdownload != data->req.bytecount)) { in ftp_done()
3377 failf(data, "Received only partial file: %" FMT_OFF_T " bytes", in ftp_done()
3378 data->req.bytecount); in ftp_done()
3382 !data->req.bytecount && in ftp_done()
3383 (data->req.size > 0)) { in ftp_done()
3384 failf(data, "No data was received"); in ftp_done()
3394 if(!status && !result && !premature && data->set.postquote) in ftp_done()
3395 result = ftp_sendquote(data, conn, data->set.postquote); in ftp_done()
3396 CURL_TRC_FTP(data, "[%s] done, result=%d", FTP_DSTATE(data), result); in ftp_done()
3412 CURLcode ftp_sendquote(struct Curl_easy *data, in ftp_sendquote() argument
3421 if(item->data) { in ftp_sendquote()
3423 char *cmd = item->data; in ftp_sendquote()
3438 result = Curl_pp_sendf(data, &ftpc->pp, "%s", cmd); in ftp_sendquote()
3441 result = Curl_GetFTPResponse(data, &nread, &ftpcode); in ftp_sendquote()
3447 failf(data, "QUOT string not accepted: %s", cmd); in ftp_sendquote()
3478 static CURLcode ftp_nb_type(struct Curl_easy *data, in ftp_nb_type() argument
3487 ftp_state(data, newstate); in ftp_nb_type()
3488 return ftp_state_type_resp(data, 200, newstate); in ftp_nb_type()
3491 result = Curl_pp_sendf(data, &ftpc->pp, "TYPE %c", want); in ftp_nb_type()
3493 ftp_state(data, newstate); in ftp_nb_type()
3512 ftp_pasv_verbose(struct Curl_easy *data, in ftp_pasv_verbose() argument
3519 infof(data, "Connecting to %s (%s) port %d", newhost, buf, port); in ftp_pasv_verbose()
3534 static CURLcode ftp_do_more(struct Curl_easy *data, int *completep) in ftp_do_more() argument
3536 struct connectdata *conn = data->conn; in ftp_do_more()
3556 bool is_eptr = Curl_conn_is_tcp_listen(data, SECONDARYSOCKET); in ftp_do_more()
3557 result = Curl_conn_connect(data, SECONDARYSOCKET, FALSE, &connected); in ftp_do_more()
3559 !Curl_conn_is_ip_connected(data, SECONDARYSOCKET))) { in ftp_do_more()
3563 return ftp_epsv_disable(data, conn); in ftp_do_more()
3571 ftp = data->req.p.ftp; in ftp_do_more()
3576 result = ftp_multi_statemach(data, &complete); in ftp_do_more()
3598 result = Curl_conn_connect(data, SECONDARYSOCKET, TRUE, &serv_conned); in ftp_do_more()
3605 result = InitiateTransfer(data); in ftp_do_more()
3614 result = ftp_check_ctrl_on_data_wait(data); in ftp_do_more()
3619 else if(data->state.upload) { in ftp_do_more()
3620 result = ftp_nb_type(data, conn, data->state.prefer_ascii, in ftp_do_more()
3625 result = ftp_multi_statemach(data, &complete); in ftp_do_more()
3632 result = Curl_range(data); in ftp_do_more()
3634 if(result == CURLE_OK && data->req.maxdownload >= 0) { in ftp_do_more()
3641 else if(data->state.list_only || !ftpc->file) { in ftp_do_more()
3648 result = ftp_nb_type(data, conn, TRUE, FTP_LIST_TYPE); in ftp_do_more()
3655 result = ftp_nb_type(data, conn, data->state.prefer_ascii, in ftp_do_more()
3661 result = ftp_multi_statemach(data, &complete); in ftp_do_more()
3668 Curl_xfer_setup_nop(data); in ftp_do_more()
3673 CURL_TRC_FTP(data, "[%s] DO-MORE phase ends with %d", FTP_DSTATE(data), in ftp_do_more()
3691 CURLcode ftp_perform(struct Curl_easy *data, in ftp_perform() argument
3698 CURL_TRC_FTP(data, "[%s] DO phase starts", FTP_DSTATE(data)); in ftp_perform()
3700 if(data->req.no_body) { in ftp_perform()
3702 struct FTP *ftp = data->req.p.ftp; in ftp_perform()
3709 result = ftp_state_quote(data, TRUE, FTP_QUOTE); in ftp_perform()
3714 result = ftp_multi_statemach(data, dophase_done); in ftp_perform()
3716 *connected = Curl_conn_is_connected(data->conn, SECONDARYSOCKET); in ftp_perform()
3719 infof(data, "[FTP] [%s] perform, DATA connection established", in ftp_perform()
3720 FTP_DSTATE(data)); in ftp_perform()
3722 CURL_TRC_FTP(data, "[%s] perform, awaiting DATA connect", in ftp_perform()
3723 FTP_DSTATE(data)); in ftp_perform()
3726 CURL_TRC_FTP(data, "[%s] DO phase is complete1", FTP_DSTATE(data)); in ftp_perform()
3739 static CURLcode init_wc_data(struct Curl_easy *data) in init_wc_data() argument
3742 struct FTP *ftp = data->req.p.ftp; in init_wc_data()
3744 struct WildcardData *wildcard = data->wildcard; in init_wc_data()
3753 return ftp_parse_url_path(data); in init_wc_data()
3769 return ftp_parse_url_path(data); in init_wc_data()
3794 if(data->set.ftp_filemethod == FTPFILE_NOCWD) in init_wc_data()
3795 data->set.ftp_filemethod = FTPFILE_MULTICWD; in init_wc_data()
3798 result = ftp_parse_url_path(data); in init_wc_data()
3810 ftpwc->backup.write_function = data->set.fwrite_func; in init_wc_data()
3812 data->set.fwrite_func = Curl_ftp_parselist; in init_wc_data()
3814 ftpwc->backup.file_descriptor = data->set.out; in init_wc_data()
3816 data->set.out = data; in init_wc_data()
3818 infof(data, "Wildcard - Parsing started"); in init_wc_data()
3832 static CURLcode wc_statemach(struct Curl_easy *data) in wc_statemach() argument
3834 struct WildcardData * const wildcard = data->wildcard; in wc_statemach()
3835 struct connectdata *conn = data->conn; in wc_statemach()
3841 result = init_wc_data(data); in wc_statemach()
3852 data->set.fwrite_func = ftpwc->backup.write_function; in wc_statemach()
3853 data->set.out = ftpwc->backup.file_descriptor; in wc_statemach()
3876 struct FTP *ftp = data->req.p.ftp; in wc_statemach()
3886 infof(data, "Wildcard - START of \"%s\"", finfo->filename); in wc_statemach()
3887 if(data->set.chunk_bgn) { in wc_statemach()
3889 Curl_set_in_callback(data, TRUE); in wc_statemach()
3890 userresponse = data->set.chunk_bgn( in wc_statemach()
3891 finfo, data->set.wildcardptr, in wc_statemach()
3893 Curl_set_in_callback(data, FALSE); in wc_statemach()
3896 infof(data, "Wildcard - \"%s\" skipped by user", in wc_statemach()
3913 result = ftp_parse_url_path(data); in wc_statemach()
3931 if(data->set.chunk_end) { in wc_statemach()
3932 Curl_set_in_callback(data, TRUE); in wc_statemach()
3933 data->set.chunk_end(data->set.wildcardptr); in wc_statemach()
3934 Curl_set_in_callback(data, FALSE); in wc_statemach()
3974 static CURLcode ftp_do(struct Curl_easy *data, bool *done) in ftp_do() argument
3977 struct connectdata *conn = data->conn; in ftp_do()
3988 result = Curl_cwriter_create(&ftp_lc_writer, data, &ftp_cw_lc, in ftp_do()
3993 result = Curl_cwriter_add(data, ftp_lc_writer); in ftp_do()
3995 Curl_cwriter_free(data, ftp_lc_writer); in ftp_do()
4001 if(data->state.wildcardmatch) { in ftp_do()
4002 result = wc_statemach(data); in ftp_do()
4003 if(data->wildcard->state == CURLWC_SKIP || in ftp_do()
4004 data->wildcard->state == CURLWC_DONE) { in ftp_do()
4012 result = ftp_parse_url_path(data); in ftp_do()
4017 result = ftp_regular_transfer(data, done); in ftp_do()
4032 static CURLcode ftp_quit(struct Curl_easy *data, struct connectdata *conn) in ftp_quit() argument
4037 result = Curl_pp_sendf(data, &conn->proto.ftpc.pp, "%s", "QUIT"); in ftp_quit()
4039 failf(data, "Failure sending QUIT command: %s", in ftp_quit()
4043 ftp_state(data, FTP_STOP); in ftp_quit()
4047 ftp_state(data, FTP_QUIT); in ftp_quit()
4049 result = ftp_block_statemach(data, conn); in ftp_quit()
4062 static CURLcode ftp_disconnect(struct Curl_easy *data, in ftp_disconnect() argument
4080 (void)ftp_quit(data, conn); /* ignore errors on the QUIT */ in ftp_disconnect()
4083 if(data->state.most_recent_ftp_entrypath == ftpc->entrypath) { in ftp_disconnect()
4084 data->state.most_recent_ftp_entrypath = NULL; in ftp_disconnect()
4112 CURLcode ftp_parse_url_path(struct Curl_easy *data) in ftp_parse_url_path() argument
4115 struct FTP *ftp = data->req.p.ftp; in ftp_parse_url_path()
4116 struct connectdata *conn = data->conn; in ftp_parse_url_path()
4130 failf(data, "path contains control characters"); in ftp_parse_url_path()
4134 switch(data->set.ftp_filemethod) { in ftp_parse_url_path()
4227 if(data->state.upload && !ftpc->file && (ftp->transfer == PPTRANSFER_BODY)) { in ftp_parse_url_path()
4229 failf(data, "Uploading to a URL without a filename"); in ftp_parse_url_path()
4236 if((data->set.ftp_filemethod == FTPFILE_NOCWD) && (rawPath[0] == '/')) in ftp_parse_url_path()
4242 if(data->set.ftp_filemethod == FTPFILE_NOCWD) in ftp_parse_url_path()
4248 infof(data, "Request has same path as previous transfer"); in ftp_parse_url_path()
4259 static CURLcode ftp_dophase_done(struct Curl_easy *data, bool connected) in ftp_dophase_done() argument
4261 struct connectdata *conn = data->conn; in ftp_dophase_done()
4262 struct FTP *ftp = data->req.p.ftp; in ftp_dophase_done()
4267 CURLcode result = ftp_do_more(data, &completed); in ftp_dophase_done()
4270 close_secondarysocket(data); in ftp_dophase_done()
4277 Curl_xfer_setup_nop(data); in ftp_dophase_done()
4288 static CURLcode ftp_doing(struct Curl_easy *data, in ftp_doing() argument
4291 CURLcode result = ftp_multi_statemach(data, dophase_done); in ftp_doing()
4294 CURL_TRC_FTP(data, "[%s] DO phase failed", FTP_DSTATE(data)); in ftp_doing()
4296 result = ftp_dophase_done(data, FALSE /* not connected */); in ftp_doing()
4298 CURL_TRC_FTP(data, "[%s] DO phase is complete2", FTP_DSTATE(data)); in ftp_doing()
4316 CURLcode ftp_regular_transfer(struct Curl_easy *data, in ftp_regular_transfer() argument
4321 struct connectdata *conn = data->conn; in ftp_regular_transfer()
4323 data->req.size = -1; /* make sure this is unknown at this point */ in ftp_regular_transfer()
4325 Curl_pgrsSetUploadCounter(data, 0); in ftp_regular_transfer()
4326 Curl_pgrsSetDownloadCounter(data, 0); in ftp_regular_transfer()
4327 Curl_pgrsSetUploadSize(data, -1); in ftp_regular_transfer()
4328 Curl_pgrsSetDownloadSize(data, -1); in ftp_regular_transfer()
4332 result = ftp_perform(data, in ftp_regular_transfer()
4342 result = ftp_dophase_done(data, connected); in ftp_regular_transfer()
4353 static CURLcode ftp_setup_connection(struct Curl_easy *data, in ftp_setup_connection() argument
4366 if(data->set.str[STRING_FTP_ACCOUNT]) { in ftp_setup_connection()
4367 ftpc->account = strdup(data->set.str[STRING_FTP_ACCOUNT]); in ftp_setup_connection()
4373 if(data->set.str[STRING_FTP_ALTERNATIVE_TO_USER]) { in ftp_setup_connection()
4375 strdup(data->set.str[STRING_FTP_ALTERNATIVE_TO_USER]); in ftp_setup_connection()
4382 data->req.p.ftp = ftp; in ftp_setup_connection()
4384 ftp->path = &data->state.up.path[1]; /* do not include the initial slash */ in ftp_setup_connection()
4400 data->state.prefer_ascii = TRUE; in ftp_setup_connection()
4404 data->state.list_only = TRUE; in ftp_setup_connection()
4410 data->state.prefer_ascii = FALSE; in ftp_setup_connection()
4419 ftpc->use_ssl = data->set.use_ssl; in ftp_setup_connection()
4420 ftpc->ccc = data->set.ftp_ccc; in ftp_setup_connection()
4422 CURL_TRC_FTP(data, "[%s] setup connection -> %d", FTP_CSTATE(conn), result); in ftp_setup_connection()