quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

tool_operhlp.c (6852B)


      1 /***************************************************************************
      2  *                                  _   _ ____  _
      3  *  Project                     ___| | | |  _ \| |
      4  *                             / __| | | | |_) | |
      5  *                            | (__| |_| |  _ <| |___
      6  *                             \___|\___/|_| \_\_____|
      7  *
      8  * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
      9  *
     10  * This software is licensed as described in the file COPYING, which
     11  * you should have received as part of this distribution. The terms
     12  * are also available at https://curl.se/docs/copyright.html.
     13  *
     14  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
     15  * copies of the Software, and permit persons to whom the Software is
     16  * furnished to do so, under the terms of the COPYING file.
     17  *
     18  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
     19  * KIND, either express or implied.
     20  *
     21  * SPDX-License-Identifier: curl
     22  *
     23  ***************************************************************************/
     24 #include "tool_setup.h"
     25 #include "tool_operate.h"
     26 
     27 #include "tool_cfgable.h"
     28 #include "tool_doswin.h"
     29 #include "tool_operhlp.h"
     30 #include "tool_msgs.h"
     31 #include "memdebug.h" /* keep this as LAST include */
     32 
     33 void clean_getout(struct OperationConfig *config)
     34 {
     35   if(config) {
     36     struct getout *next;
     37     struct getout *node = config->url_list;
     38 
     39     while(node) {
     40       next = node->next;
     41       tool_safefree(node->url);
     42       tool_safefree(node->outfile);
     43       tool_safefree(node->infile);
     44       tool_safefree(node);
     45       node = next;
     46     }
     47     config->url_list = NULL;
     48   }
     49   single_transfer_cleanup(config);
     50 }
     51 
     52 bool output_expected(const char *url, const char *uploadfile)
     53 {
     54   if(!uploadfile)
     55     return TRUE;  /* download */
     56   if(checkprefix("http://", url) || checkprefix("https://", url))
     57     return TRUE;   /* HTTP(S) upload */
     58 
     59   return FALSE; /* non-HTTP upload, probably no output should be expected */
     60 }
     61 
     62 bool stdin_upload(const char *uploadfile)
     63 {
     64   return !strcmp(uploadfile, "-") || !strcmp(uploadfile, ".");
     65 }
     66 
     67 /* Convert a CURLUcode into a CURLcode */
     68 CURLcode urlerr_cvt(CURLUcode ucode)
     69 {
     70   if(ucode == CURLUE_OUT_OF_MEMORY)
     71     return CURLE_OUT_OF_MEMORY;
     72   else if(ucode == CURLUE_UNSUPPORTED_SCHEME)
     73     return CURLE_UNSUPPORTED_PROTOCOL;
     74   else if(ucode == CURLUE_LACKS_IDN)
     75     return CURLE_NOT_BUILT_IN;
     76   else if(ucode == CURLUE_BAD_HANDLE)
     77     return CURLE_BAD_FUNCTION_ARGUMENT;
     78   return CURLE_URL_MALFORMAT;
     79 }
     80 
     81 /*
     82  * Adds the filename to the URL if it does not already have one.
     83  * url will be freed before return if the returned pointer is different
     84  */
     85 CURLcode add_file_name_to_url(CURL *curl, char **inurlp, const char *filename)
     86 {
     87   CURLcode result = CURLE_URL_MALFORMAT;
     88   CURLUcode uerr;
     89   CURLU *uh = curl_url();
     90   char *path = NULL;
     91   char *query = NULL;
     92   if(uh) {
     93     char *ptr;
     94     uerr = curl_url_set(uh, CURLUPART_URL, *inurlp,
     95                     CURLU_GUESS_SCHEME|CURLU_NON_SUPPORT_SCHEME);
     96     if(uerr) {
     97       result = urlerr_cvt(uerr);
     98       goto fail;
     99     }
    100     uerr = curl_url_get(uh, CURLUPART_PATH, &path, 0);
    101     if(uerr) {
    102       result = urlerr_cvt(uerr);
    103       goto fail;
    104     }
    105     uerr = curl_url_get(uh, CURLUPART_QUERY, &query, 0);
    106     if(!uerr && query) {
    107       curl_free(query);
    108       curl_free(path);
    109       curl_url_cleanup(uh);
    110       return CURLE_OK;
    111     }
    112     ptr = strrchr(path, '/');
    113     if(!ptr || !*++ptr) {
    114       /* The URL path has no filename part, add the local filename. In order
    115          to be able to do so, we have to create a new URL in another buffer.*/
    116 
    117       /* We only want the part of the local path that is on the right
    118          side of the rightmost slash and backslash. */
    119       const char *filep = strrchr(filename, '/');
    120       char *file2 = strrchr(filep ? filep : filename, '\\');
    121       char *encfile;
    122 
    123       if(file2)
    124         filep = file2 + 1;
    125       else if(filep)
    126         filep++;
    127       else
    128         filep = filename;
    129 
    130       /* URL encode the filename */
    131       encfile = curl_easy_escape(curl, filep, 0 /* use strlen */);
    132       if(encfile) {
    133         char *newpath;
    134         char *newurl;
    135         if(ptr)
    136           /* there is a trailing slash on the path */
    137           newpath = aprintf("%s%s", path, encfile);
    138         else
    139           /* there is no trailing slash on the path */
    140           newpath = aprintf("%s/%s", path, encfile);
    141 
    142         curl_free(encfile);
    143 
    144         if(!newpath)
    145           goto fail;
    146         uerr = curl_url_set(uh, CURLUPART_PATH, newpath, 0);
    147         free(newpath);
    148         if(uerr) {
    149           result = urlerr_cvt(uerr);
    150           goto fail;
    151         }
    152         uerr = curl_url_get(uh, CURLUPART_URL, &newurl, CURLU_DEFAULT_SCHEME);
    153         if(uerr) {
    154           result = urlerr_cvt(uerr);
    155           goto fail;
    156         }
    157         free(*inurlp);
    158         *inurlp = newurl;
    159         result = CURLE_OK;
    160       }
    161     }
    162     else
    163       /* nothing to do */
    164       result = CURLE_OK;
    165   }
    166 fail:
    167   curl_url_cleanup(uh);
    168   curl_free(path);
    169   return result;
    170 }
    171 
    172 /* Extracts the name portion of the URL.
    173  * Returns a pointer to a heap-allocated string or NULL if
    174  * no name part, at location indicated by first argument.
    175  */
    176 CURLcode get_url_file_name(struct GlobalConfig *global,
    177                            char **filename, const char *url)
    178 {
    179   CURLU *uh = curl_url();
    180   char *path = NULL;
    181   CURLUcode uerr;
    182 
    183   if(!uh)
    184     return CURLE_OUT_OF_MEMORY;
    185 
    186   *filename = NULL;
    187 
    188   uerr = curl_url_set(uh, CURLUPART_URL, url, CURLU_GUESS_SCHEME);
    189   if(!uerr) {
    190     uerr = curl_url_get(uh, CURLUPART_PATH, &path, 0);
    191     curl_url_cleanup(uh);
    192     uh = NULL;
    193     if(!uerr) {
    194       int i;
    195       char *pc = NULL, *pc2 = NULL;
    196       for(i = 0; i < 2; i++) {
    197         pc = strrchr(path, '/');
    198         pc2 = strrchr(pc ? pc + 1 : path, '\\');
    199         if(pc2)
    200           pc = pc2;
    201         if(pc && !pc[1] && !i) {
    202           /* if the path ends with slash, try removing the trailing one
    203              and get the last directory part */
    204           *pc = 0;
    205         }
    206       }
    207 
    208       if(pc) {
    209         /* duplicate the string beyond the slash */
    210         *filename = strdup(pc + 1);
    211       }
    212       else {
    213         /* no slash => empty string, use default */
    214         *filename = strdup("curl_response");
    215         warnf(global, "No remote file name, uses \"%s\"", *filename);
    216       }
    217 
    218       curl_free(path);
    219       if(!*filename)
    220         return CURLE_OUT_OF_MEMORY;
    221 
    222 #if defined(_WIN32) || defined(MSDOS)
    223       {
    224         char *sanitized;
    225         SANITIZEcode sc = sanitize_file_name(&sanitized, *filename, 0);
    226         tool_safefree(*filename);
    227         if(sc) {
    228           if(sc == SANITIZE_ERR_OUT_OF_MEMORY)
    229             return CURLE_OUT_OF_MEMORY;
    230           return CURLE_URL_MALFORMAT;
    231         }
    232         *filename = sanitized;
    233       }
    234 #endif /* _WIN32 || MSDOS */
    235 
    236       return CURLE_OK;
    237     }
    238   }
    239   curl_url_cleanup(uh);
    240   return urlerr_cvt(uerr);
    241 }