diff --git a/CHANGES b/CHANGES index 74c321984..470039344 100644 --- a/CHANGES +++ b/CHANGES @@ -7,6 +7,9 @@ Changelog Daniel (19 August 2006) +- Based on a patch by Armel Asselin, the FTP code no longer re-issues the TYPE + command on subsequent requests on a re-used connection unless it has to. + - Armel Asselin fixed a crash in the FTP code when using SINGLECWD mode and files in the root directory. diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 49698e524..756515a8f 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -11,6 +11,7 @@ Curl and libcurl 7.15.6 This release includes the following changes: + o (FTP) libcurl avoids sending TYPE if the desired type was already set o CURLOPT_PREQUOTE works even when CURLOPT_NOBODY is set true This release includes the following bugfixes: diff --git a/lib/content_encoding.c b/lib/content_encoding.c index bcd5b838a..97f834177 100644 --- a/lib/content_encoding.c +++ b/lib/content_encoding.c @@ -62,9 +62,9 @@ enum zlibState { }; static CURLcode -process_zlib_error(struct SessionHandle *data, - z_stream *z) +process_zlib_error(struct connectdata *conn, z_stream *z) { + struct SessionHandle *data = conn->data; if (z->msg) failf (data, "Error while processing content unencoding: %s", z->msg); @@ -84,7 +84,7 @@ exit_zlib(z_stream *z, bool *zlib_init, CURLcode result) } static CURLcode -inflate_stream(struct SessionHandle *data, +inflate_stream(struct connectdata *conn, struct Curl_transfer_keeper *k) { int allow_restart = 1; @@ -113,7 +113,7 @@ inflate_stream(struct SessionHandle *data, if (status == Z_OK || status == Z_STREAM_END) { allow_restart = 0; if(DSIZ - z->avail_out) { - result = Curl_client_write(data, CLIENTWRITE_BODY, decomp, + result = Curl_client_write(conn, CLIENTWRITE_BODY, decomp, DSIZ - z->avail_out); /* if !CURLE_OK, clean up, return */ if (result) { @@ -128,7 +128,7 @@ inflate_stream(struct SessionHandle *data, if (inflateEnd(z) == Z_OK) return exit_zlib(z, &k->zlib_init, result); else - return exit_zlib(z, &k->zlib_init, process_zlib_error(data, z)); + return exit_zlib(z, &k->zlib_init, process_zlib_error(conn, z)); } /* Done with these bytes, exit */ @@ -143,7 +143,7 @@ inflate_stream(struct SessionHandle *data, inflateReset(z); if (inflateInit2(z, -MAX_WBITS) != Z_OK) { - return process_zlib_error(data, z); + return process_zlib_error(conn, z); } z->next_in = orig_in; z->avail_in = nread; @@ -152,14 +152,14 @@ inflate_stream(struct SessionHandle *data, } else { /* Error; exit loop, handle below */ free(decomp); - return exit_zlib(z, &k->zlib_init, process_zlib_error(data, z)); + return exit_zlib(z, &k->zlib_init, process_zlib_error(conn, z)); } } /* Will never get here */ } CURLcode -Curl_unencode_deflate_write(struct SessionHandle *data, +Curl_unencode_deflate_write(struct connectdata *conn, struct Curl_transfer_keeper *k, ssize_t nread) { @@ -173,7 +173,7 @@ Curl_unencode_deflate_write(struct SessionHandle *data, z->next_in = NULL; z->avail_in = 0; if (inflateInit(z) != Z_OK) - return process_zlib_error(data, z); + return process_zlib_error(conn, z); k->zlib_init = ZLIB_INIT; } @@ -182,7 +182,7 @@ Curl_unencode_deflate_write(struct SessionHandle *data, z->avail_in = (uInt)nread; /* Now uncompress the data */ - return inflate_stream(data, k); + return inflate_stream(conn, k); } #ifdef OLD_ZLIB_SUPPORT @@ -272,7 +272,7 @@ static enum { #endif CURLcode -Curl_unencode_gzip_write(struct SessionHandle *data, +Curl_unencode_gzip_write(struct connectdata *conn, struct Curl_transfer_keeper *k, ssize_t nread) { @@ -289,14 +289,14 @@ Curl_unencode_gzip_write(struct SessionHandle *data, if (strcmp(zlibVersion(), "1.2.0.4") >= 0) { /* zlib ver. >= 1.2.0.4 supports transparent gzip decompressing */ if (inflateInit2(z, MAX_WBITS+32) != Z_OK) { - return process_zlib_error(data, z); + return process_zlib_error(conn, z); } k->zlib_init = ZLIB_INIT_GZIP; /* Transparent gzip decompress state */ } else { /* we must parse the gzip header ourselves */ if (inflateInit2(z, -MAX_WBITS) != Z_OK) { - return process_zlib_error(data, z); + return process_zlib_error(conn, z); } k->zlib_init = ZLIB_INIT; /* Initial call state */ } @@ -307,7 +307,7 @@ Curl_unencode_gzip_write(struct SessionHandle *data, z->next_in = (Bytef *)k->str; z->avail_in = (uInt)nread; /* Now uncompress the data */ - return inflate_stream(data, k); + return inflate_stream(conn, k); } #ifndef OLD_ZLIB_SUPPORT @@ -360,7 +360,7 @@ Curl_unencode_gzip_write(struct SessionHandle *data, case GZIP_BAD: default: - return exit_zlib(z, &k->zlib_init, process_zlib_error(data, z)); + return exit_zlib(z, &k->zlib_init, process_zlib_error(conn, z)); } } @@ -398,7 +398,7 @@ Curl_unencode_gzip_write(struct SessionHandle *data, case GZIP_BAD: default: free(z->next_in); - return exit_zlib(z, &k->zlib_init, process_zlib_error(data, z)); + return exit_zlib(z, &k->zlib_init, process_zlib_error(conn, z)); } } @@ -418,7 +418,7 @@ Curl_unencode_gzip_write(struct SessionHandle *data, } /* We've parsed the header, now uncompress the data */ - return inflate_stream(data, k); + return inflate_stream(conn, k); #endif } #endif /* HAVE_LIBZ */ diff --git a/lib/content_encoding.h b/lib/content_encoding.h index 6f01c69e8..b31669be4 100644 --- a/lib/content_encoding.h +++ b/lib/content_encoding.h @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2004, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2006, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -31,11 +31,11 @@ #define ALL_CONTENT_ENCODINGS "identity" #endif -CURLcode Curl_unencode_deflate_write(struct SessionHandle *data, +CURLcode Curl_unencode_deflate_write(struct connectdata *conn, struct Curl_transfer_keeper *k, ssize_t nread); CURLcode -Curl_unencode_gzip_write(struct SessionHandle *data, +Curl_unencode_gzip_write(struct connectdata *conn, struct Curl_transfer_keeper *k, ssize_t nread); diff --git a/lib/file.c b/lib/file.c index 7415d8a78..7ac53f19b 100644 --- a/lib/file.c +++ b/lib/file.c @@ -311,11 +311,11 @@ CURLcode Curl_file(struct connectdata *conn, bool *done) CURLcode result; snprintf(buf, sizeof(data->state.buffer), "Content-Length: %" FORMAT_OFF_T "\r\n", expected_size); - result = Curl_client_write(data, CLIENTWRITE_BOTH, buf, 0); + result = Curl_client_write(conn, CLIENTWRITE_BOTH, buf, 0); if(result) return result; - result = Curl_client_write(data, CLIENTWRITE_BOTH, + result = Curl_client_write(conn, CLIENTWRITE_BOTH, (char *)"Accept-ranges: bytes\r\n", 0); if(result) return result; @@ -339,7 +339,7 @@ CURLcode Curl_file(struct connectdata *conn, bool *done) tm->tm_hour, tm->tm_min, tm->tm_sec); - result = Curl_client_write(data, CLIENTWRITE_BOTH, buf, 0); + result = Curl_client_write(conn, CLIENTWRITE_BOTH, buf, 0); } return result; } @@ -377,7 +377,7 @@ CURLcode Curl_file(struct connectdata *conn, bool *done) bytecount += nread; - res = Curl_client_write(data, CLIENTWRITE_BODY, buf, nread); + res = Curl_client_write(conn, CLIENTWRITE_BODY, buf, nread); if(res) return res; diff --git a/lib/ftp.c b/lib/ftp.c index e7d8b2269..62c941e5d 100644 --- a/lib/ftp.c +++ b/lib/ftp.c @@ -132,6 +132,10 @@ static CURLcode ftp_state_post_rest(struct connectdata *conn); static CURLcode ftp_state_post_cwd(struct connectdata *conn); static CURLcode ftp_state_quote(struct connectdata *conn, bool init, ftpstate instate); +static CURLcode ftp_nb_type(struct connectdata *conn, + bool ascii, ftpstate state); +static int ftp_need_type(struct connectdata *conn, + bool ascii); /* easy-to-use macro: */ #define FTPSENDF(x,y,z) if((result = Curl_ftpsendf(x,y,z))) return result @@ -339,7 +343,7 @@ static CURLcode ftp_readresp(curl_socket_t sockfd, * for "headers". The response lines can be seen as a kind of * headers. */ - result = Curl_client_write(data, CLIENTWRITE_HEADER, + result = Curl_client_write(conn, CLIENTWRITE_HEADER, ftp->linestart_resp, perline); if(result) return result; @@ -570,7 +574,7 @@ CURLcode Curl_GetFTPResponse(ssize_t *nreadp, /* return number of bytes read */ * for "headers". The response lines can be seen as a kind of * headers. */ - result = Curl_client_write(data, CLIENTWRITE_HEADER, + result = Curl_client_write(conn, CLIENTWRITE_HEADER, line_start, perline); if(result) return result; @@ -1313,7 +1317,8 @@ static CURLcode ftp_state_post_mdtm(struct connectdata *conn) /* If we have selected NOBODY and HEADER, it means that we only want file information. Which in FTP can't be much more than the file size and date. */ - if(conn->bits.no_body && data->set.include_header && ftp->file) { + if(conn->bits.no_body && data->set.include_header && ftp->file && + ftp_need_type(conn, data->set.prefer_ascii)) { /* The SIZE command is _not_ RFC 959 specified, and therefor many servers may not support it! It is however the only way we have to get a file's size! */ @@ -1322,11 +1327,9 @@ static CURLcode ftp_state_post_mdtm(struct connectdata *conn) /* Some servers return different sizes for different modes, and thus we must set the proper type before we check the size */ - NBFTPSENDF(conn, "TYPE %c", - data->set.ftp_ascii?'A':'I'); - state(conn, FTP_TYPE); - /* keep track of our current transfer type */ - data->ftp_in_ascii_mode = data->set.ftp_ascii; + result = ftp_nb_type(conn, data->set.prefer_ascii, FTP_TYPE); + if (result) + return result; } else result = ftp_state_post_type(conn); @@ -1828,7 +1831,7 @@ static CURLcode ftp_state_mdtm_resp(struct connectdata *conn, tm->tm_hour, tm->tm_min, tm->tm_sec); - result = Curl_client_write(data, CLIENTWRITE_BOTH, buf, 0); + result = Curl_client_write(conn, CLIENTWRITE_BOTH, buf, 0); if(result) return result; } /* end of a ridiculous amount of conditionals */ @@ -2003,7 +2006,7 @@ static CURLcode ftp_state_size_resp(struct connectdata *conn, if(-1 != filesize) { snprintf(buf, sizeof(data->state.buffer), "Content-Length: %" FORMAT_OFF_T "\r\n", filesize); - result = Curl_client_write(data, CLIENTWRITE_BOTH, buf, 0); + result = Curl_client_write(conn, CLIENTWRITE_BOTH, buf, 0); if(result) return result; } @@ -2030,7 +2033,7 @@ static CURLcode ftp_state_rest_resp(struct connectdata *conn, case FTP_REST: default: if (ftpcode == 350) { - result = Curl_client_write(conn->data, CLIENTWRITE_BOTH, + result = Curl_client_write(conn, CLIENTWRITE_BOTH, (char *)"Accept-ranges: bytes\r\n", 0); if(result) return result; @@ -2141,7 +2144,7 @@ static CURLcode ftp_state_get_resp(struct connectdata *conn, */ if((instate != FTP_LIST) && - !data->set.ftp_ascii && + !data->set.prefer_ascii && (ftp->downloadsize < 1)) { /* * It seems directory listings either don't show the size or very @@ -3095,7 +3098,7 @@ static CURLcode ftp_transfertype(struct connectdata *conn, ssize_t nread; CURLcode result; - FTPSENDF(conn, "TYPE %s", ascii?"A":"I"); + FTPSENDF(conn, "TYPE %c", ascii?'A':'I'); result = Curl_GetFTPResponse(&nread, conn, &ftpcode); if(result) @@ -3107,11 +3110,52 @@ static CURLcode ftp_transfertype(struct connectdata *conn, return ascii? CURLE_FTP_COULDNT_SET_ASCII:CURLE_FTP_COULDNT_SET_BINARY; } /* keep track of our current transfer type */ - data->ftp_in_ascii_mode = ascii; + conn->proto.ftp->transfertype = ascii?'A':'I'; return CURLE_OK; } + +/*********************************************************************** + * + * ftp_need_type() + * + * Returns TRUE if we in the current situation should send TYPE + */ +static int ftp_need_type(struct connectdata *conn, + bool ascii_wanted) +{ + return conn->proto.ftp->transfertype != (ascii_wanted?'A':'I'); +} + +/*********************************************************************** + * + * ftp_nb_type() + * + * Set TYPE. We only deal with ASCII or BINARY so this function + * sets one of them. + * If the transfer type is not sent, simulate on OK response in newstate + */ +static CURLcode ftp_nb_type(struct connectdata *conn, + bool ascii, ftpstate newstate) +{ + struct FTP *ftp = conn->proto.ftp; + CURLcode result; + int want = ascii?'A':'I'; + + if (ftp->transfertype == want) { + state(conn, newstate); + return ftp_state_type_resp(conn, 200, newstate); + } + + NBFTPSENDF(conn, "TYPE %c", want); + state(conn, newstate); + + /* keep track of our current transfer type */ + ftp->transfertype = want; + return CURLE_OK; +} + /*************************************************************************** * * ftp_pasv_verbose() @@ -3207,10 +3251,10 @@ CURLcode Curl_ftp_nextconnect(struct connectdata *conn) /* a transfer is about to take place */ if(data->set.upload) { - NBFTPSENDF(conn, "TYPE %c", data->set.ftp_ascii?'A':'I'); - state(conn, FTP_STOR_TYPE); - /* keep track of our current transfer type */ - data->ftp_in_ascii_mode = data->set.ftp_ascii; + result = ftp_nb_type(conn, data->set.prefer_ascii, + FTP_STOR_TYPE); + if (result) + return result; } else { /* download */ @@ -3223,16 +3267,14 @@ CURLcode Curl_ftp_nextconnect(struct connectdata *conn) /* The specified path ends with a slash, and therefore we think this is a directory that is requested, use LIST. But before that we need to set ASCII transfer mode. */ - NBFTPSENDF(conn, "TYPE A", NULL); - state(conn, FTP_LIST_TYPE); - /* keep track of our current transfer type */ - data->ftp_in_ascii_mode = 1; + result = ftp_nb_type(conn, 1, FTP_LIST_TYPE); + if (result) + return result; } else { - NBFTPSENDF(conn, "TYPE %c", data->set.ftp_ascii?'A':'I'); - state(conn, FTP_RETR_TYPE); - /* keep track of our current transfer type */ - data->ftp_in_ascii_mode = data->set.ftp_ascii; + result = ftp_nb_type(conn, data->set.prefer_ascii, FTP_RETR_TYPE); + if (result) + return result; } } result = ftp_easy_statemach(conn); @@ -3621,11 +3663,11 @@ static CURLcode ftp_3rdparty_pretransfer(struct connectdata *conn) sec_conn->xfertype = SOURCE3RD; /* sets transfer type */ - result = ftp_transfertype(conn, data->set.ftp_ascii); + result = ftp_transfertype(conn, data->set.prefer_ascii); if (result) return result; - result = ftp_transfertype(sec_conn, data->set.ftp_ascii); + result = ftp_transfertype(sec_conn, data->set.prefer_ascii); if (result) return result; diff --git a/lib/http.c b/lib/http.c index 4df91be0a..aab0b85a2 100644 --- a/lib/http.c +++ b/lib/http.c @@ -1251,7 +1251,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn, if(data->set.include_header) writetype |= CLIENTWRITE_BODY; - result = Curl_client_write(data, writetype, line_start, perline); + result = Curl_client_write(conn, writetype, line_start, perline); if(result) return result; diff --git a/lib/http_chunks.c b/lib/http_chunks.c index 63e136cb7..30112f2b8 100644 --- a/lib/http_chunks.c +++ b/lib/http_chunks.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2005, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2006, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -190,7 +190,7 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn, case IDENTITY: #endif if(!k->ignorebody) - result = Curl_client_write(conn->data, CLIENTWRITE_BODY, datap, + result = Curl_client_write(conn, CLIENTWRITE_BODY, datap, piece); #ifdef HAVE_LIBZ break; @@ -198,14 +198,14 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn, case DEFLATE: /* update conn->keep.str to point to the chunk data. */ conn->keep.str = datap; - result = Curl_unencode_deflate_write(conn->data, &conn->keep, + result = Curl_unencode_deflate_write(conn, &conn->keep, (ssize_t)piece); break; case GZIP: /* update conn->keep.str to point to the chunk data. */ conn->keep.str = datap; - result = Curl_unencode_gzip_write(conn->data, &conn->keep, + result = Curl_unencode_gzip_write(conn, &conn->keep, (ssize_t)piece); break; @@ -303,7 +303,7 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn, return CHUNKE_STOP; } else { - Curl_client_write(conn->data, CLIENTWRITE_HEADER, + Curl_client_write(conn, CLIENTWRITE_HEADER, conn->trailer, conn->trlPos); } ch->state = CHUNK_TRAILER; diff --git a/lib/ldap.c b/lib/ldap.c index 7b92587d7..32ef50675 100644 --- a/lib/ldap.c +++ b/lib/ldap.c @@ -372,9 +372,9 @@ CURLcode Curl_ldap(struct connectdata *conn, bool *done) char *dn = (*ldap_get_dn)(server, entryIterator); int i; - Curl_client_write(data, CLIENTWRITE_BODY, (char *)"DN: ", 4); - Curl_client_write(data, CLIENTWRITE_BODY, (char *)dn, 0); - Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\n", 1); + Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"DN: ", 4); + Curl_client_write(conn, CLIENTWRITE_BODY, (char *)dn, 0); + Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1); for (attribute = (*ldap_first_attribute)(server, entryIterator, &ber); attribute; @@ -387,9 +387,9 @@ CURLcode Curl_ldap(struct connectdata *conn, bool *done) { for (i = 0; (vals[i] != NULL); i++) { - Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\t", 1); - Curl_client_write(data, CLIENTWRITE_BODY, (char *) attribute, 0); - Curl_client_write(data, CLIENTWRITE_BODY, (char *)": ", 2); + Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\t", 1); + Curl_client_write(conn, CLIENTWRITE_BODY, (char *) attribute, 0); + Curl_client_write(conn, CLIENTWRITE_BODY, (char *)": ", 2); if ((strlen(attribute) > 7) && (strcmp(";binary", (char *)attribute + @@ -398,19 +398,19 @@ CURLcode Curl_ldap(struct connectdata *conn, bool *done) val_b64_sz = Curl_base64_encode(vals[i]->bv_val, vals[i]->bv_len, &val_b64); if (val_b64_sz > 0) { - Curl_client_write(data, CLIENTWRITE_BODY, val_b64, val_b64_sz); + Curl_client_write(conn, CLIENTWRITE_BODY, val_b64, val_b64_sz); free(val_b64); } } else - Curl_client_write(data, CLIENTWRITE_BODY, vals[i]->bv_val, + Curl_client_write(conn, CLIENTWRITE_BODY, vals[i]->bv_val, vals[i]->bv_len); - Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\n", 0); + Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0); } /* Free memory used to store values */ (*ldap_value_free_len)((void **)vals); } - Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\n", 1); + Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1); (*ldap_memfree)(attribute); } diff --git a/lib/sendf.c b/lib/sendf.c index d598197bd..b38415c3e 100644 --- a/lib/sendf.c +++ b/lib/sendf.c @@ -367,18 +367,19 @@ CURLcode Curl_write(struct connectdata *conn, The bit pattern defines to what "streams" to write to. Body and/or header. The defines are in sendf.h of course. */ -CURLcode Curl_client_write(struct SessionHandle *data, +CURLcode Curl_client_write(struct connectdata *conn, int type, char *ptr, size_t len) { + struct SessionHandle *data = conn->data; size_t wrote; if(0 == len) len = strlen(ptr); if(type & CLIENTWRITE_BODY) { - if(data->ftp_in_ascii_mode) { + if((conn->protocol&PROT_FTP) && conn->proto.ftp->transfertype == 'A') { #ifdef CURL_DOES_CONVERSIONS /* convert from the network encoding */ size_t rc; diff --git a/lib/sendf.h b/lib/sendf.h index ae96af3e0..b556bd573 100644 --- a/lib/sendf.h +++ b/lib/sendf.h @@ -47,7 +47,7 @@ void Curl_failf(struct SessionHandle *, const char *fmt, ...); #define CLIENTWRITE_HEADER 2 #define CLIENTWRITE_BOTH (CLIENTWRITE_BODY|CLIENTWRITE_HEADER) -CURLcode Curl_client_write(struct SessionHandle *data, int type, char *ptr, +CURLcode Curl_client_write(struct connectdata *conn, int type, char *ptr, size_t len); /* internal read-function, does plain socket, SSL and krb4 */ diff --git a/lib/telnet.c b/lib/telnet.c index 5f94807df..8939dd1a6 100644 --- a/lib/telnet.c +++ b/lib/telnet.c @@ -940,7 +940,7 @@ void telrcv(struct connectdata *conn, break; /* Ignore \0 after CR */ } - Curl_client_write(data, CLIENTWRITE_BODY, (char *)&c, 1); + Curl_client_write(conn, CLIENTWRITE_BODY, (char *)&c, 1); continue; case CURL_TS_DATA: @@ -954,7 +954,7 @@ void telrcv(struct connectdata *conn, tn->telrcv_state = CURL_TS_CR; } - Curl_client_write(data, CLIENTWRITE_BODY, (char *)&c, 1); + Curl_client_write(conn, CLIENTWRITE_BODY, (char *)&c, 1); continue; case CURL_TS_IAC: @@ -978,7 +978,7 @@ void telrcv(struct connectdata *conn, tn->telrcv_state = CURL_TS_SB; continue; case CURL_IAC: - Curl_client_write(data, CLIENTWRITE_BODY, (char *)&c, 1); + Curl_client_write(conn, CLIENTWRITE_BODY, (char *)&c, 1); break; case CURL_DM: case CURL_NOP: diff --git a/lib/tftp.c b/lib/tftp.c index 1bf7281bb..61800cc3d 100644 --- a/lib/tftp.c +++ b/lib/tftp.c @@ -261,7 +261,7 @@ static CURLcode tftp_send_first(tftp_state_data_t *state, tftp_event_t event) CURLcode res = CURLE_OK; /* Set ascii mode if -B flag was used */ - if(data->set.ftp_ascii) + if(data->set.prefer_ascii) mode = "netascii"; switch(event) { @@ -699,7 +699,7 @@ CURLcode Curl_tftp(struct connectdata *conn, bool *done) /* Don't pass to the client empty or retransmitted packets */ if (state->rbytes > 4 && ((state->block+1) == getrpacketblock(&state->rpacket))) { - code = Curl_client_write(data, CLIENTWRITE_BODY, + code = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)&state->rpacket.data[4], state->rbytes-4); if(code) diff --git a/lib/transfer.c b/lib/transfer.c index 814940f8f..9cf9c2925 100644 --- a/lib/transfer.c +++ b/lib/transfer.c @@ -531,7 +531,7 @@ CURLcode Curl_readwrite(struct connectdata *conn, headerlen = k->p - data->state.headerbuff; - result = Curl_client_write(data, writetype, + result = Curl_client_write(conn, writetype, data->state.headerbuff, headerlen); if(result) @@ -990,7 +990,7 @@ CURLcode Curl_readwrite(struct connectdata *conn, Curl_debug(data, CURLINFO_HEADER_IN, k->p, k->hbuflen, conn); - result = Curl_client_write(data, writetype, k->p, k->hbuflen); + result = Curl_client_write(conn, writetype, k->p, k->hbuflen); if(result) return result; @@ -1144,7 +1144,7 @@ CURLcode Curl_readwrite(struct connectdata *conn, if(k->badheader && !k->ignorebody) { /* we parsed a piece of data wrongly assuming it was a header and now we output it as body instead */ - result = Curl_client_write(data, CLIENTWRITE_BODY, + result = Curl_client_write(conn, CLIENTWRITE_BODY, data->state.headerbuff, k->hbuflen); if(result) @@ -1164,7 +1164,7 @@ CURLcode Curl_readwrite(struct connectdata *conn, Content-Encoding header. See Curl_readwrite_init; the memset() call initializes k->content_encoding to zero. */ if(!k->ignorebody) - result = Curl_client_write(data, CLIENTWRITE_BODY, k->str, + result = Curl_client_write(conn, CLIENTWRITE_BODY, k->str, nread); #ifdef HAVE_LIBZ break; @@ -1172,13 +1172,13 @@ CURLcode Curl_readwrite(struct connectdata *conn, case DEFLATE: /* Assume CLIENTWRITE_BODY; headers are not encoded. */ if(!k->ignorebody) - result = Curl_unencode_deflate_write(data, k, nread); + result = Curl_unencode_deflate_write(conn, k, nread); break; case GZIP: /* Assume CLIENTWRITE_BODY; headers are not encoded. */ if(!k->ignorebody) - result = Curl_unencode_gzip_write(data, k, nread); + result = Curl_unencode_gzip_write(conn, k, nread); break; case COMPRESS: @@ -1283,7 +1283,7 @@ CURLcode Curl_readwrite(struct connectdata *conn, /* convert LF to CRLF if so asked */ #ifdef CURL_DO_LINEEND_CONV /* always convert if we're FTPing in ASCII mode */ - if ((data->set.crlf) || (data->ftp_in_ascii_mode)) { + if ((data->set.crlf) || (data->set.prefer_ascii)) { #else if (data->set.crlf) { #endif /* CURL_DO_LINEEND_CONV */ diff --git a/lib/url.c b/lib/url.c index 6b376faf7..c0641c78b 100644 --- a/lib/url.c +++ b/lib/url.c @@ -612,7 +612,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * * Transfer using ASCII (instead of BINARY). */ - data->set.ftp_ascii = va_arg(param, long)?TRUE:FALSE; + data->set.prefer_ascii = va_arg(param, long)?TRUE:FALSE; break; case CURLOPT_TIMECONDITION: /* @@ -3125,15 +3125,15 @@ static CURLcode CreateConnection(struct SessionHandle *data, command = (char)toupper((int)type[6]); switch(command) { case 'A': /* ASCII mode */ - data->set.ftp_ascii = 1; + data->set.prefer_ascii = TRUE; break; case 'D': /* directory mode */ - data->set.ftp_list_only = 1; + data->set.ftp_list_only = TRUE; break; case 'I': /* binary mode */ default: /* switch off ASCII */ - data->set.ftp_ascii = 0; + data->set.prefer_ascii = FALSE; break; } } @@ -3228,13 +3228,13 @@ static CURLcode CreateConnection(struct SessionHandle *data, switch(command) { case 'A': /* ASCII mode */ case 'N': /* NETASCII mode */ - data->set.ftp_ascii = 1; + data->set.prefer_ascii = TRUE; break; case 'O': /* octet mode */ case 'I': /* binary mode */ default: /* switch off ASCII */ - data->set.ftp_ascii = 0; + data->set.prefer_ascii = FALSE; break; } } diff --git a/lib/urldata.h b/lib/urldata.h index f1d14a6c0..33f7ee860 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -362,6 +362,8 @@ struct FTP { bool cwdfail; /* set TRUE if a CWD command fails, as then we must prevent caching the current directory */ char *prevpath; /* conn->path from the previous transfer */ + char transfertype; /* set by ftp_transfertype for use by Curl_client_write()a + and others (A/I or zero) */ size_t nread_resp; /* number of bytes currently read of a server response */ char *linestart_resp; /* line start pointer for the FTP server response @@ -1114,8 +1116,8 @@ struct UserDefined { bool printhost; /* printing host name in debug info */ bool get_filetime; bool tunnel_thru_httpproxy; + bool prefer_ascii; /* ASCII rather than binary */ bool ftp_append; - bool ftp_ascii; bool ftp_list_only; bool ftp_create_missing_dirs; bool ftp_use_port; @@ -1184,8 +1186,6 @@ struct SessionHandle { struct UrlState state; /* struct for fields used for state info and other dynamic purposes */ struct PureInfo info; /* stats, reports and info data */ - /* set by ftp_transfertype for use by Curl_client_write and others */ - bool ftp_in_ascii_mode; #if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV) iconv_t outbound_cd; /* for translating to the network encoding */ iconv_t inbound_cd; /* for translating from the network encoding */ diff --git a/tests/data/test146 b/tests/data/test146 index 1de7f38d4..2d1940bc8 100644 --- a/tests/data/test146 +++ b/tests/data/test146 @@ -39,7 +39,6 @@ SIZE 146 RETR 146 CWD /nowhere/anywhere EPSV -TYPE I SIZE 146 RETR 146 QUIT diff --git a/tests/data/test149 b/tests/data/test149 index b42477b79..9195e19a9 100644 --- a/tests/data/test149 +++ b/tests/data/test149 @@ -37,7 +37,6 @@ STOR 148 CWD /nowhere/anywhere CWD dir2 EPSV -TYPE I STOR 148 QUIT diff --git a/tests/data/test210 b/tests/data/test210 index f42aaecf7..711a26ad1 100644 --- a/tests/data/test210 +++ b/tests/data/test210 @@ -37,7 +37,6 @@ TYPE I SIZE 210 RETR 210 EPSV -TYPE I SIZE 210 RETR 210 QUIT diff --git a/tests/data/test211 b/tests/data/test211 index 761852862..18f4cb11e 100644 --- a/tests/data/test211 +++ b/tests/data/test211 @@ -39,7 +39,6 @@ TYPE I SIZE 211 RETR 211 PASV -TYPE I SIZE 211 RETR 211 QUIT diff --git a/tests/data/test212 b/tests/data/test212 index 3fac26bde..c5790df30 100644 --- a/tests/data/test212 +++ b/tests/data/test212 @@ -47,7 +47,6 @@ TYPE I SIZE 212 RETR 212 PORT 127,0,0,1, -TYPE I SIZE 212 RETR 212 QUIT diff --git a/tests/data/test215 b/tests/data/test215 index ac60618d9..6077feb8b 100644 --- a/tests/data/test215 +++ b/tests/data/test215 @@ -44,7 +44,6 @@ EPSV TYPE A LIST EPSV -TYPE A LIST QUIT diff --git a/tests/data/test216 b/tests/data/test216 index 236364260..ba3d52720 100644 --- a/tests/data/test216 +++ b/tests/data/test216 @@ -31,7 +31,6 @@ EPSV TYPE I STOR upload.216 EPSV -TYPE I STOR ..anotherup QUIT