]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
ftp: allocate the wildcard struct on demand
authorDaniel Stenberg <daniel@haxx.se>
Mon, 27 Feb 2023 22:57:23 +0000 (23:57 +0100)
committerDaniel Stenberg <daniel@haxx.se>
Fri, 3 Mar 2023 22:25:23 +0000 (23:25 +0100)
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

lib/ftp.c
lib/ftplistparser.c
lib/multi.c
lib/transfer.c
lib/urldata.h
lib/wildcard.c
lib/wildcard.h

index 2f72e0c3bb8943cdf42e60887cca4d09776f4e73..3777e038789896a995dd97dbcf7054ad949f1cfc 100644 (file)
--- 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;
     }
index f7c6434eb04b8230b67e5370e22d05759202b769..4d6698b9aa505179a8c4115a265c48730400c2d1 100644 (file)
@@ -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;
index f020a0b64acf159798dc7bbedc87a9b25e3c86f6..2f0d020afd2bc96817aa8cefc2380b951be702d1 100644 (file)
@@ -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);
index 27843f50cc1f0cdd18d1e0b78a95f46fc28e76b9..140895113ed1d947bbf1d103a9febde56f767d31 100644 (file)
@@ -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)
index d7d104d419dfefe6480c8488b5d50ade7289c40b..6df811dba3c805f1e599d659351ba0466b23d453 100644 (file)
@@ -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
index dea2a01bf821951073204235b11601423819cd89..7b9f6efd0002b349c7d3089714d54e33bc69f989 100644 (file)
@@ -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 */
index 5b363fc585be7e138d760438425e3096edc7f87e..e5c6ffff1f7d106d2901a0c7e33a48c88e42e62d 100644 (file)
@@ -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;