Skip to content

Commit d5f117a

Browse files
bagderbch
authored andcommittedJul 19, 2023
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 curl#10639
1 parent 95cef6e commit d5f117a

File tree

7 files changed

+33
-24
lines changed

7 files changed

+33
-24
lines changed
 

‎lib/ftp.c

+9-9
Original file line numberDiff line numberDiff line change
@@ -3761,7 +3761,7 @@ static CURLcode init_wc_data(struct Curl_easy *data)
37613761
char *last_slash;
37623762
struct FTP *ftp = data->req.p.ftp;
37633763
char *path = ftp->path;
3764-
struct WildcardData *wildcard = &(data->wildcard);
3764+
struct WildcardData *wildcard = data->wildcard;
37653765
CURLcode result = CURLE_OK;
37663766
struct ftp_wc *ftpwc = NULL;
37673767

@@ -3809,7 +3809,7 @@ static CURLcode init_wc_data(struct Curl_easy *data)
38093809
goto fail;
38103810
}
38113811

3812-
wildcard->protdata = ftpwc; /* put it to the WildcardData tmp pointer */
3812+
wildcard->ftpwc = ftpwc; /* put it to the WildcardData tmp pointer */
38133813
wildcard->dtor = wc_data_dtor;
38143814

38153815
/* wildcard does not support NOCWD option (assert it?) */
@@ -3847,13 +3847,13 @@ static CURLcode init_wc_data(struct Curl_easy *data)
38473847
}
38483848
Curl_safefree(wildcard->pattern);
38493849
wildcard->dtor = ZERO_NULL;
3850-
wildcard->protdata = NULL;
3850+
wildcard->ftpwc = NULL;
38513851
return result;
38523852
}
38533853

38543854
static CURLcode wc_statemach(struct Curl_easy *data)
38553855
{
3856-
struct WildcardData * const wildcard = &(data->wildcard);
3856+
struct WildcardData * const wildcard = data->wildcard;
38573857
struct connectdata *conn = data->conn;
38583858
CURLcode result = CURLE_OK;
38593859

@@ -3870,7 +3870,7 @@ static CURLcode wc_statemach(struct Curl_easy *data)
38703870
case CURLWC_MATCHING: {
38713871
/* In this state is LIST response successfully parsed, so lets restore
38723872
previous WRITEFUNCTION callback and WRITEDATA pointer */
3873-
struct ftp_wc *ftpwc = wildcard->protdata;
3873+
struct ftp_wc *ftpwc = wildcard->ftpwc;
38743874
data->set.fwrite_func = ftpwc->backup.write_function;
38753875
data->set.out = ftpwc->backup.file_descriptor;
38763876
ftpwc->backup.write_function = ZERO_NULL;
@@ -3959,7 +3959,7 @@ static CURLcode wc_statemach(struct Curl_easy *data)
39593959
}
39603960

39613961
case CURLWC_CLEAN: {
3962-
struct ftp_wc *ftpwc = wildcard->protdata;
3962+
struct ftp_wc *ftpwc = wildcard->ftpwc;
39633963
result = CURLE_OK;
39643964
if(ftpwc)
39653965
result = Curl_ftp_parselist_geterror(ftpwc->parser);
@@ -3972,7 +3972,7 @@ static CURLcode wc_statemach(struct Curl_easy *data)
39723972
case CURLWC_ERROR:
39733973
case CURLWC_CLEAR:
39743974
if(wildcard->dtor)
3975-
wildcard->dtor(wildcard->protdata);
3975+
wildcard->dtor(wildcard->ftpwc);
39763976
return result;
39773977
}
39783978
}
@@ -3999,8 +3999,8 @@ static CURLcode ftp_do(struct Curl_easy *data, bool *done)
39993999

40004000
if(data->state.wildcardmatch) {
40014001
result = wc_statemach(data);
4002-
if(data->wildcard.state == CURLWC_SKIP ||
4003-
data->wildcard.state == CURLWC_DONE) {
4002+
if(data->wildcard->state == CURLWC_SKIP ||
4003+
data->wildcard->state == CURLWC_DONE) {
40044004
/* do not call ftp_regular_transfer */
40054005
return CURLE_OK;
40064006
}

‎lib/ftplistparser.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -274,8 +274,8 @@ static CURLcode ftp_pl_insert_finfo(struct Curl_easy *data,
274274
struct fileinfo *infop)
275275
{
276276
curl_fnmatch_callback compare;
277-
struct WildcardData *wc = &data->wildcard;
278-
struct ftp_wc *ftpwc = wc->protdata;
277+
struct WildcardData *wc = data->wildcard;
278+
struct ftp_wc *ftpwc = wc->ftpwc;
279279
struct Curl_llist *llist = &wc->filelist;
280280
struct ftp_parselist_data *parser = ftpwc->parser;
281281
bool add = TRUE;
@@ -330,7 +330,7 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
330330
{
331331
size_t bufflen = size*nmemb;
332332
struct Curl_easy *data = (struct Curl_easy *)connptr;
333-
struct ftp_wc *ftpwc = data->wildcard.protdata;
333+
struct ftp_wc *ftpwc = data->wildcard->ftpwc;
334334
struct ftp_parselist_data *parser = ftpwc->parser;
335335
struct fileinfo *infop;
336336
struct curl_fileinfo *finfo;

‎lib/multi.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -2192,7 +2192,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
21922192
#ifndef CURL_DISABLE_FTP
21932193
/* some steps needed for wildcard matching */
21942194
if(data->state.wildcardmatch) {
2195-
struct WildcardData *wc = &data->wildcard;
2195+
struct WildcardData *wc = data->wildcard;
21962196
if(wc->state == CURLWC_DONE || wc->state == CURLWC_SKIP) {
21972197
/* skip some states if it is important */
21982198
multi_done(data, CURLE_OK, FALSE);
@@ -2344,7 +2344,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
23442344
#ifndef CURL_DISABLE_FTP
23452345
if(data->state.wildcardmatch &&
23462346
((data->conn->handler->flags & PROTOPT_WILDCARD) == 0)) {
2347-
data->wildcard.state = CURLWC_DONE;
2347+
data->wildcard->state = CURLWC_DONE;
23482348
}
23492349
#endif
23502350
multistate(data, MSTATE_DONE);
@@ -2574,7 +2574,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
25742574

25752575
#ifndef CURL_DISABLE_FTP
25762576
if(data->state.wildcardmatch) {
2577-
if(data->wildcard.state != CURLWC_DONE) {
2577+
if(data->wildcard->state != CURLWC_DONE) {
25782578
/* if a wildcard is set and we are not ending -> lets start again
25792579
with MSTATE_INIT */
25802580
multistate(data, MSTATE_INIT);

‎lib/transfer.c

+7-1
Original file line numberDiff line numberDiff line change
@@ -1402,7 +1402,13 @@ CURLcode Curl_pretransfer(struct Curl_easy *data)
14021402
#ifndef CURL_DISABLE_FTP
14031403
data->state.wildcardmatch = data->set.wildcard_enabled;
14041404
if(data->state.wildcardmatch) {
1405-
struct WildcardData *wc = &data->wildcard;
1405+
struct WildcardData *wc;
1406+
if(!data->wildcard) {
1407+
data->wildcard = calloc(1, sizeof(struct WildcardData));
1408+
if(!data->wildcard)
1409+
return CURLE_OUT_OF_MEMORY;
1410+
}
1411+
wc = data->wildcard;
14061412
if(wc->state < CURLWC_INIT) {
14071413
result = Curl_wildcard_init(wc); /* init wildcard structures */
14081414
if(result)

‎lib/urldata.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -1939,7 +1939,7 @@ struct Curl_easy {
19391939
struct UrlState state; /* struct for fields used for state info and
19401940
other dynamic purposes */
19411941
#ifndef CURL_DISABLE_FTP
1942-
struct WildcardData wildcard; /* wildcard download state info */
1942+
struct WildcardData *wildcard; /* wildcard download state info */
19431943
#endif
19441944
struct PureInfo info; /* stats, reports and info data */
19451945
struct curl_tlssessioninfo tsi; /* Information about the TLS session, only

‎lib/wildcard.c

+7-4
Original file line numberDiff line numberDiff line change
@@ -48,24 +48,27 @@ CURLcode Curl_wildcard_init(struct WildcardData *wc)
4848
return CURLE_OK;
4949
}
5050

51-
void Curl_wildcard_dtor(struct WildcardData *wc)
51+
void Curl_wildcard_dtor(struct WildcardData **wcp)
5252
{
53+
struct WildcardData *wc = *wcp;
5354
if(!wc)
5455
return;
5556

5657
if(wc->dtor) {
57-
wc->dtor(wc->protdata);
58+
wc->dtor(wc->ftpwc);
5859
wc->dtor = ZERO_NULL;
59-
wc->protdata = NULL;
60+
wc->ftpwc = NULL;
6061
}
61-
DEBUGASSERT(wc->protdata == NULL);
62+
DEBUGASSERT(wc->ftpwc == NULL);
6263

6364
Curl_llist_destroy(&wc->filelist, NULL);
6465
free(wc->path);
6566
wc->path = NULL;
6667
free(wc->pattern);
6768
wc->pattern = NULL;
6869
wc->state = CURLWC_INIT;
70+
free(wc);
71+
*wcp = NULL;
6972
}
7073

7174
#endif /* if disabled */

‎lib/wildcard.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -48,16 +48,16 @@ typedef void (*wildcard_dtor)(void *ptr);
4848

4949
/* struct keeping information about wildcard download process */
5050
struct WildcardData {
51-
wildcard_states state;
5251
char *path; /* path to the directory, where we trying wildcard-match */
5352
char *pattern; /* wildcard pattern */
5453
struct Curl_llist filelist; /* llist with struct Curl_fileinfo */
55-
void *protdata; /* pointer to protocol specific temporary data */
54+
struct ftp_wc *ftpwc; /* pointer to FTP wildcard data */
5655
wildcard_dtor dtor;
56+
unsigned char state; /* wildcard_states */
5757
};
5858

5959
CURLcode Curl_wildcard_init(struct WildcardData *wc);
60-
void Curl_wildcard_dtor(struct WildcardData *wc);
60+
void Curl_wildcard_dtor(struct WildcardData **wcp);
6161

6262
struct Curl_easy;
6363

0 commit comments

Comments
 (0)
Please sign in to comment.