summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2023-02-27 23:57:23 +0100
committerDaniel Stenberg <daniel@haxx.se>2023-03-03 23:25:23 +0100
commit9c188e771c9d5ecbdb04cbc9f3936bb9f52f78c9 (patch)
tree8e80174942206e34a4d3b2d478847a537b5ecf3c
parentc84c0f9aa3bb0068bd6cbf6fce77bacccececa75 (diff)
downloadcurl-9c188e771c9d5ecbdb04cbc9f3936bb9f52f78c9.tar.gz
ftp: allocate the wildcard struct on demand
The feature is rarely used so this frees up data for the vast majority of easy handles that don't use it. Rename "protdata" to "ftpwc" since it is always an FTP wildcard struct pointer. Made the state struct field an unsigned char to save space. Closes #10639
-rw-r--r--lib/ftp.c18
-rw-r--r--lib/ftplistparser.c6
-rw-r--r--lib/multi.c6
-rw-r--r--lib/transfer.c8
-rw-r--r--lib/urldata.h2
-rw-r--r--lib/wildcard.c11
-rw-r--r--lib/wildcard.h6
7 files changed, 33 insertions, 24 deletions
diff --git a/lib/ftp.c b/lib/ftp.c
index 2f72e0c3b..3777e0387 100644
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -3761,7 +3761,7 @@ static CURLcode init_wc_data(struct Curl_easy *data)
char *last_slash;
struct FTP *ftp = data->req.p.ftp;
char *path = ftp->path;
- struct WildcardData *wildcard = &(data->wildcard);
+ struct WildcardData *wildcard = data->wildcard;
CURLcode result = CURLE_OK;
struct ftp_wc *ftpwc = NULL;
@@ -3809,7 +3809,7 @@ static CURLcode init_wc_data(struct Curl_easy *data)
goto fail;
}
- wildcard->protdata = ftpwc; /* put it to the WildcardData tmp pointer */
+ wildcard->ftpwc = ftpwc; /* put it to the WildcardData tmp pointer */
wildcard->dtor = wc_data_dtor;
/* wildcard does not support NOCWD option (assert it?) */
@@ -3847,13 +3847,13 @@ static CURLcode init_wc_data(struct Curl_easy *data)
}
Curl_safefree(wildcard->pattern);
wildcard->dtor = ZERO_NULL;
- wildcard->protdata = NULL;
+ wildcard->ftpwc = NULL;
return result;
}
static CURLcode wc_statemach(struct Curl_easy *data)
{
- struct WildcardData * const wildcard = &(data->wildcard);
+ struct WildcardData * const wildcard = data->wildcard;
struct connectdata *conn = data->conn;
CURLcode result = CURLE_OK;
@@ -3870,7 +3870,7 @@ static CURLcode wc_statemach(struct Curl_easy *data)
case CURLWC_MATCHING: {
/* In this state is LIST response successfully parsed, so lets restore
previous WRITEFUNCTION callback and WRITEDATA pointer */
- struct ftp_wc *ftpwc = wildcard->protdata;
+ struct ftp_wc *ftpwc = wildcard->ftpwc;
data->set.fwrite_func = ftpwc->backup.write_function;
data->set.out = ftpwc->backup.file_descriptor;
ftpwc->backup.write_function = ZERO_NULL;
@@ -3959,7 +3959,7 @@ static CURLcode wc_statemach(struct Curl_easy *data)
}
case CURLWC_CLEAN: {
- struct ftp_wc *ftpwc = wildcard->protdata;
+ struct ftp_wc *ftpwc = wildcard->ftpwc;
result = CURLE_OK;
if(ftpwc)
result = Curl_ftp_parselist_geterror(ftpwc->parser);
@@ -3972,7 +3972,7 @@ static CURLcode wc_statemach(struct Curl_easy *data)
case CURLWC_ERROR:
case CURLWC_CLEAR:
if(wildcard->dtor)
- wildcard->dtor(wildcard->protdata);
+ wildcard->dtor(wildcard->ftpwc);
return result;
}
}
@@ -3999,8 +3999,8 @@ static CURLcode ftp_do(struct Curl_easy *data, bool *done)
if(data->state.wildcardmatch) {
result = wc_statemach(data);
- if(data->wildcard.state == CURLWC_SKIP ||
- data->wildcard.state == CURLWC_DONE) {
+ if(data->wildcard->state == CURLWC_SKIP ||
+ data->wildcard->state == CURLWC_DONE) {
/* do not call ftp_regular_transfer */
return CURLE_OK;
}
diff --git a/lib/ftplistparser.c b/lib/ftplistparser.c
index f7c6434eb..4d6698b9a 100644
--- a/lib/ftplistparser.c
+++ b/lib/ftplistparser.c
@@ -274,8 +274,8 @@ static CURLcode ftp_pl_insert_finfo(struct Curl_easy *data,
struct fileinfo *infop)
{
curl_fnmatch_callback compare;
- struct WildcardData *wc = &data->wildcard;
- struct ftp_wc *ftpwc = wc->protdata;
+ struct WildcardData *wc = data->wildcard;
+ struct ftp_wc *ftpwc = wc->ftpwc;
struct Curl_llist *llist = &wc->filelist;
struct ftp_parselist_data *parser = ftpwc->parser;
bool add = TRUE;
@@ -330,7 +330,7 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
{
size_t bufflen = size*nmemb;
struct Curl_easy *data = (struct Curl_easy *)connptr;
- struct ftp_wc *ftpwc = data->wildcard.protdata;
+ struct ftp_wc *ftpwc = data->wildcard->ftpwc;
struct ftp_parselist_data *parser = ftpwc->parser;
struct fileinfo *infop;
struct curl_fileinfo *finfo;
diff --git a/lib/multi.c b/lib/multi.c
index f020a0b64..2f0d020af 100644
--- a/lib/multi.c
+++ b/lib/multi.c
@@ -2192,7 +2192,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
#ifndef CURL_DISABLE_FTP
/* some steps needed for wildcard matching */
if(data->state.wildcardmatch) {
- struct WildcardData *wc = &data->wildcard;
+ struct WildcardData *wc = data->wildcard;
if(wc->state == CURLWC_DONE || wc->state == CURLWC_SKIP) {
/* skip some states if it is important */
multi_done(data, CURLE_OK, FALSE);
@@ -2344,7 +2344,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
#ifndef CURL_DISABLE_FTP
if(data->state.wildcardmatch &&
((data->conn->handler->flags & PROTOPT_WILDCARD) == 0)) {
- data->wildcard.state = CURLWC_DONE;
+ data->wildcard->state = CURLWC_DONE;
}
#endif
multistate(data, MSTATE_DONE);
@@ -2574,7 +2574,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
#ifndef CURL_DISABLE_FTP
if(data->state.wildcardmatch) {
- if(data->wildcard.state != CURLWC_DONE) {
+ if(data->wildcard->state != CURLWC_DONE) {
/* if a wildcard is set and we are not ending -> lets start again
with MSTATE_INIT */
multistate(data, MSTATE_INIT);
diff --git a/lib/transfer.c b/lib/transfer.c
index 27843f50c..140895113 100644
--- a/lib/transfer.c
+++ b/lib/transfer.c
@@ -1402,7 +1402,13 @@ CURLcode Curl_pretransfer(struct Curl_easy *data)
#ifndef CURL_DISABLE_FTP
data->state.wildcardmatch = data->set.wildcard_enabled;
if(data->state.wildcardmatch) {
- struct WildcardData *wc = &data->wildcard;
+ struct WildcardData *wc;
+ if(!data->wildcard) {
+ data->wildcard = calloc(1, sizeof(struct WildcardData));
+ if(!data->wildcard)
+ return CURLE_OUT_OF_MEMORY;
+ }
+ wc = data->wildcard;
if(wc->state < CURLWC_INIT) {
result = Curl_wildcard_init(wc); /* init wildcard structures */
if(result)
diff --git a/lib/urldata.h b/lib/urldata.h
index d7d104d41..6df811dba 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -1939,7 +1939,7 @@ struct Curl_easy {
struct UrlState state; /* struct for fields used for state info and
other dynamic purposes */
#ifndef CURL_DISABLE_FTP
- struct WildcardData wildcard; /* wildcard download state info */
+ struct WildcardData *wildcard; /* wildcard download state info */
#endif
struct PureInfo info; /* stats, reports and info data */
struct curl_tlssessioninfo tsi; /* Information about the TLS session, only
diff --git a/lib/wildcard.c b/lib/wildcard.c
index dea2a01bf..7b9f6efd0 100644
--- a/lib/wildcard.c
+++ b/lib/wildcard.c
@@ -48,17 +48,18 @@ CURLcode Curl_wildcard_init(struct WildcardData *wc)
return CURLE_OK;
}
-void Curl_wildcard_dtor(struct WildcardData *wc)
+void Curl_wildcard_dtor(struct WildcardData **wcp)
{
+ struct WildcardData *wc = *wcp;
if(!wc)
return;
if(wc->dtor) {
- wc->dtor(wc->protdata);
+ wc->dtor(wc->ftpwc);
wc->dtor = ZERO_NULL;
- wc->protdata = NULL;
+ wc->ftpwc = NULL;
}
- DEBUGASSERT(wc->protdata == NULL);
+ DEBUGASSERT(wc->ftpwc == NULL);
Curl_llist_destroy(&wc->filelist, NULL);
free(wc->path);
@@ -66,6 +67,8 @@ void Curl_wildcard_dtor(struct WildcardData *wc)
free(wc->pattern);
wc->pattern = NULL;
wc->state = CURLWC_INIT;
+ free(wc);
+ *wcp = NULL;
}
#endif /* if disabled */
diff --git a/lib/wildcard.h b/lib/wildcard.h
index 5b363fc58..e5c6ffff1 100644
--- a/lib/wildcard.h
+++ b/lib/wildcard.h
@@ -48,16 +48,16 @@ typedef void (*wildcard_dtor)(void *ptr);
/* struct keeping information about wildcard download process */
struct WildcardData {
- wildcard_states state;
char *path; /* path to the directory, where we trying wildcard-match */
char *pattern; /* wildcard pattern */
struct Curl_llist filelist; /* llist with struct Curl_fileinfo */
- void *protdata; /* pointer to protocol specific temporary data */
+ struct ftp_wc *ftpwc; /* pointer to FTP wildcard data */
wildcard_dtor dtor;
+ unsigned char state; /* wildcard_states */
};
CURLcode Curl_wildcard_init(struct WildcardData *wc);
-void Curl_wildcard_dtor(struct WildcardData *wc);
+void Curl_wildcard_dtor(struct WildcardData **wcp);
struct Curl_easy;