From 9ecf53e1544e90aeb2e667fdbbc84f05e341cc07 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Wed, 21 Sep 2011 01:54:14 +0200 Subject: curl tool: reviewed code moved to tool_*.[ch] files my_setopt and my_setopt_str no longer ignores curl_easy_setopt result. Fixed some OOM handling issues. --- src/tool_setopt.c | 125 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 src/tool_setopt.c (limited to 'src/tool_setopt.c') diff --git a/src/tool_setopt.c b/src/tool_setopt.c new file mode 100644 index 000000000..b636aab38 --- /dev/null +++ b/src/tool_setopt.c @@ -0,0 +1,125 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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 + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include "setup.h" + +#include + +#define ENABLE_CURLX_PRINTF +/* use our own printf() functions */ +#include "curlx.h" + +#include "tool_cfgable.h" +#include "tool_easysrc.h" +#include "tool_setopt.h" + +#include "memdebug.h" /* keep this as LAST include */ + +CURLcode tool_setopt(CURL *curl, bool str, struct Configurable *config, + const char *name, CURLoption tag, ...) +{ + va_list arg; + char *bufp; + char value[256]; + bool remark = FALSE; + bool skip = FALSE; + CURLcode ret = CURLE_OK; + + va_start(arg, tag); + + if(tag < CURLOPTTYPE_OBJECTPOINT) { + long lval = va_arg(arg, long); + snprintf(value, sizeof(value), "%ldL", lval); + ret = curl_easy_setopt(curl, tag, lval); + if(!lval) + skip = TRUE; + } + else if(tag < CURLOPTTYPE_OFF_T) { + void *pval = va_arg(arg, void *); + unsigned char *ptr = (unsigned char *)pval; + + /* function pointers are never printable */ + if(tag >= CURLOPTTYPE_FUNCTIONPOINT) { + if(pval) { + strcpy(value, "functionpointer"); /* 'value' fits 256 bytes */ + remark = TRUE; + } + else + skip = TRUE; + } + + else if(pval && str) + snprintf(value, sizeof(value), "\"%s\"", (char *)ptr); + else if(pval) { + strcpy(value, "objectpointer"); /* 'value' fits 256 bytes */ + remark = TRUE; + } + else + skip = TRUE; + + ret = curl_easy_setopt(curl, tag, pval); + + } + else { + curl_off_t oval = va_arg(arg, curl_off_t); + snprintf(value, sizeof(value), + "(curl_off_t)%" CURL_FORMAT_CURL_OFF_T, oval); + ret = curl_easy_setopt(curl, tag, oval); + + if(!oval) + skip = TRUE; + } + + va_end(arg); + + if(config->libcurl && !skip && !ret) { + /* we only use this for real if --libcurl was used */ + + if(remark) + bufp = curlx_maprintf("%s set to a %s", name, value); + else + bufp = curlx_maprintf("curl_easy_setopt(hnd, %s, %s);", name, value); + + if(!bufp) + ret = CURLE_OUT_OF_MEMORY; + else { + struct curl_slist *list = + curl_slist_append(remark?easysrc_remarks:easysrc, bufp); + + curl_free(bufp); + + if(!list) { + curl_slist_free_all(easysrc_remarks); + curl_slist_free_all(easysrc); + easysrc_remarks = NULL; + easysrc = NULL; + ret = CURLE_OUT_OF_MEMORY; + } + else if(remark) + easysrc_remarks = list; + else + easysrc = list; + } + } + + return ret; +} + -- cgit v1.2.1 From 2b26eb98573a1402a8f39603b9fdaa9d04142c07 Mon Sep 17 00:00:00 2001 From: Colin Hogben Date: Sun, 5 Feb 2012 17:44:22 +0000 Subject: configure: add option disable --libcurl output --- src/tool_setopt.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/tool_setopt.c') diff --git a/src/tool_setopt.c b/src/tool_setopt.c index b636aab38..6fc604716 100644 --- a/src/tool_setopt.c +++ b/src/tool_setopt.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2011, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2012, 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 @@ -21,6 +21,8 @@ ***************************************************************************/ #include "setup.h" +#ifndef CURL_DISABLE_LIBCURL_OPTION + #include #define ENABLE_CURLX_PRINTF @@ -123,3 +125,4 @@ CURLcode tool_setopt(CURL *curl, bool str, struct Configurable *config, return ret; } +#endif /* CURL_DISABLE_LIBCURL_OPTION */ -- cgit v1.2.1 From 995424298052fa02ac82a584ee4247939503f24a Mon Sep 17 00:00:00 2001 From: Colin Hogben Date: Thu, 23 Feb 2012 09:43:37 +0000 Subject: Generate lists and use symbols in --libcurl code output. This patch improves the output of curl's --libcurl option by generating code which builds curl_httppost and curl_slist lists, and uses symbolic names for enum and flag values. Variants of the my_setopt macro in tool_setopt.h are added in order to pass extra type information to the code-generation step in tool_setopt.c. If curl is configured with --disable-libcurl-option then the macros call curl_easy_setopt directly. --- src/tool_setopt.c | 403 ++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 374 insertions(+), 29 deletions(-) (limited to 'src/tool_setopt.c') diff --git a/src/tool_setopt.c b/src/tool_setopt.c index 6fc604716..5be4c3b39 100644 --- a/src/tool_setopt.c +++ b/src/tool_setopt.c @@ -35,43 +35,397 @@ #include "memdebug.h" /* keep this as LAST include */ +/* Lookup tables for converting setopt values back to symbols */ +/* For enums, values may be in any order. */ +/* For bit masks, put combinations first, then single bits, */ +/* and finally any "NONE" value. */ + +#define NV(e) {#e, e} +#define NVEND {NULL, 0} /* sentinel to mark end of list */ + +const NameValue setopt_nv_CURLPROXY[] = { + NV(CURLPROXY_HTTP), + NV(CURLPROXY_HTTP_1_0), + NV(CURLPROXY_SOCKS4), + NV(CURLPROXY_SOCKS5), + NV(CURLPROXY_SOCKS4A), + NV(CURLPROXY_SOCKS5_HOSTNAME), + NVEND, +}; + +const NameValue setopt_nv_CURLAUTH[] = { + NV(CURLAUTH_ANY), /* combination */ + NV(CURLAUTH_ANYSAFE), /* combination */ + NV(CURLAUTH_BASIC), + NV(CURLAUTH_DIGEST), + NV(CURLAUTH_GSSNEGOTIATE), + NV(CURLAUTH_NTLM), + NV(CURLAUTH_DIGEST_IE), + NV(CURLAUTH_NTLM_WB), + NV(CURLAUTH_ONLY), + NV(CURLAUTH_NONE), + NVEND, +}; + +const NameValue setopt_nv_CURL_HTTP_VERSION[] = { + NV(CURL_HTTP_VERSION_NONE), + NV(CURL_HTTP_VERSION_1_0), + NV(CURL_HTTP_VERSION_1_1), + NVEND, +}; + +const NameValue setopt_nv_CURL_SSLVERSION[] = { + NV(CURL_SSLVERSION_DEFAULT), + NV(CURL_SSLVERSION_TLSv1), + NV(CURL_SSLVERSION_SSLv2), + NV(CURL_SSLVERSION_SSLv3), + NVEND, +}; + +const NameValue setopt_nv_CURL_TIMECOND[] = { + NV(CURL_TIMECOND_IFMODSINCE), + NV(CURL_TIMECOND_IFUNMODSINCE), + NV(CURL_TIMECOND_LASTMOD), + NV(CURL_TIMECOND_NONE), + NVEND, +}; + +const NameValue setopt_nv_CURLFTPSSL_CCC[] = { + NV(CURLFTPSSL_CCC_NONE), + NV(CURLFTPSSL_CCC_PASSIVE), + NV(CURLFTPSSL_CCC_ACTIVE), + NVEND, +}; + +/* These mappings essentially triplicated - see + * tool_libinfo.c and tool_paramhlp.c */ +const NameValue setopt_nv_CURLPROTO[] = { + NV(CURLPROTO_ALL), /* combination */ + NV(CURLPROTO_DICT), + NV(CURLPROTO_FILE), + NV(CURLPROTO_FTP), + NV(CURLPROTO_FTPS), + NV(CURLPROTO_GOPHER), + NV(CURLPROTO_HTTP), + NV(CURLPROTO_HTTPS), + NV(CURLPROTO_IMAP), + NV(CURLPROTO_IMAPS), + NV(CURLPROTO_LDAP), + NV(CURLPROTO_LDAPS), + NV(CURLPROTO_POP3), + NV(CURLPROTO_POP3S), + NV(CURLPROTO_RTSP), + NV(CURLPROTO_SCP), + NV(CURLPROTO_SFTP), + NV(CURLPROTO_SMTP), + NV(CURLPROTO_SMTPS), + NV(CURLPROTO_TELNET), + NV(CURLPROTO_TFTP), + NVEND, +}; + +/* Format and add code; jump to nomem on malloc error */ +#define ADD(args) do { \ + ret = easysrc_add args; \ + if(ret) \ + goto nomem; \ +} while(0) +#define ADDF(args) do { \ + ret = easysrc_addf args; \ + if(ret) \ + goto nomem; \ +} while(0) + +#define DECL0(s) ADD((&easysrc_decl, s)) +#define DECL1(f,a) ADDF((&easysrc_decl, f,a)) + +#define DATA0(s) ADD((&easysrc_data, s)) +#define DATA1(f,a) ADDF((&easysrc_data, f,a)) +#define DATA2(f,a,b) ADDF((&easysrc_data, f,a,b)) +#define DATA3(f,a,b,c) ADDF((&easysrc_data, f,a,b,c)) + +#define CODE0(s) ADD((&easysrc_code, s)) +#define CODE1(f,a) ADDF((&easysrc_code, f,a)) +#define CODE2(f,a,b) ADDF((&easysrc_code, f,a,b)) +#define CODE3(f,a,b,c) ADDF((&easysrc_code, f,a,b,c)) + +#define CLEAN0(s) ADD((&easysrc_clean, s)) +#define CLEAN1(f,a) ADDF((&easysrc_clean, f,a)) + +#define REM0(s) ADD((&easysrc_toohard, s)) +#define REM1(f,a) ADDF((&easysrc_toohard, f,a)) +#define REM2(f,a,b) ADDF((&easysrc_toohard, f,a,b)) + +/* Escape string to C string syntax. Return NULL if out of memory. + * Is this correct for those wacky EBCDIC guys? */ +static char *c_escape(const char *str) +{ + size_t len = 0; + const char *s; + unsigned char c; + char *escaped, *e; + /* Allocate space based on worst-case */ + len = strlen(str); + escaped = malloc(4 * len + 1); + if(!escaped) + return NULL; + + e = escaped; + for(s=str; (c=*s) != '\0'; s++) { + if(c=='\n') { + strcpy(e, "\\n"); + e += 2; + } + else if(c=='\r') { + strcpy(e, "\\r"); + e += 2; + } + else if(c=='\t') { + strcpy(e, "\\t"); + e += 2; + } + else if(c=='\\') { + strcpy(e, "\\\\"); + e += 2; + } + else if(c=='"') { + strcpy(e, "\\\""); + e += 2; + } + else if(! isprint(c)) { + sprintf(e, "\\%03o", c); + e += 4; + } + else + *e++ = c; + } + *e = '\0'; + return escaped; +} + +/* setopt wrapper for enum types */ +CURLcode tool_setopt_enum(CURL *curl, struct Configurable *config, + const char *name, CURLoption tag, + const NameValue *nvlist, long lval) +{ + CURLcode ret = CURLE_OK; + bool skip = FALSE; + + ret = curl_easy_setopt(curl, tag, lval); + if(!lval) + skip = TRUE; + + if(config->libcurl && !skip && !ret) { + /* we only use this for real if --libcurl was used */ + const NameValue *nv = NULL; + for(nv=nvlist; nv->name; nv++) { + if(nv->value == lval) break; /* found it */ + } + if(! nv->name) { + /* If no definition was found, output an explicit value. + * This could happen if new values are defined and used + * but the NameValue list is not updated. */ + CODE2("curl_easy_setopt(hnd, %s, %ldL);", name, lval); + } + else { + CODE2("curl_easy_setopt(hnd, %s, (long)%s);", name, nv->name); + } + } + + nomem: + return ret; +} + +/* setopt wrapper for bit mask */ +CURLcode tool_setopt_flags(CURL *curl, struct Configurable *config, + const char *name, CURLoption tag, + const NameValue *nvlist, long lval) +{ + CURLcode ret = CURLE_OK; + bool skip = FALSE; + + ret = curl_easy_setopt(curl, tag, lval); + if(!lval) + skip = TRUE; + + if(config->libcurl && !skip && !ret) { + /* we only use this for real if --libcurl was used */ + char preamble[80]; /* should accommodate any symbol name */ + long rest = lval; /* bits not handled yet */ + const NameValue *nv = NULL; + snprintf(preamble, sizeof(preamble), + "curl_easy_setopt(hnd, %s, ", name); + for(nv=nvlist; nv->name; nv++) { + if((nv->value & ~ rest) == 0) { + /* all value flags contained in rest */ + rest &= ~ nv->value; /* remove bits handled here */ + CODE3("%s(long)%s%s", + preamble, nv->name, rest ? " |" : ");"); + if(!rest) + break; /* handled them all */ + /* replace with all spaces for continuation line */ + sprintf(preamble, "%*s", strlen(preamble), ""); + } + } + /* If any bits have no definition, output an explicit value. + * This could happen if new bits are defined and used + * but the NameValue list is not updated. */ + if(rest) + CODE2("%s%ldL);", preamble, rest); + } + + nomem: + return ret; +} + +/* setopt wrapper for CURLOPT_HTTPPOST */ +CURLcode tool_setopt_httppost(CURL *curl, struct Configurable *config, + const char *name, CURLoption tag, + struct curl_httppost *post) +{ + CURLcode ret = CURLE_OK; + bool skip = FALSE; + + ret = curl_easy_setopt(curl, tag, post); + if(!post) + skip = TRUE; + + if(config->libcurl && !skip && !ret) { + struct curl_httppost *pp, *p; + int i; + /* May use several httppost lists, if multiple POST actions */ + i = ++ easysrc_form_count; + DECL1("struct curl_httppost *post%d;", i); + DATA1("post%d = NULL;", i); + CLEAN1("curl_formfree(post%d);", i); + CLEAN1("post%d = NULL;", i); + if(i == 1) + DECL0("struct curl_httppost *postend;"); + DATA0("postend = NULL;"); + for(p=post; p; p=p->next) { + DATA1("curl_formadd(&post%d, &postend,", i); + DATA1(" CURLFORM_COPYNAME, \"%s\",", p->name); + for(pp=p; pp; pp=pp->more) { + /* May be several files uploaded for one name; + * these are linked through the 'more' pointer */ + char *e; + e = c_escape(pp->contents); + if(!e) + goto nomem; + if(pp->flags & HTTPPOST_FILENAME) { + /* file upload as for -F @filename */ + DATA1(" CURLFORM_FILE, \"%s\",", e); + } + else if(pp->flags & HTTPPOST_READFILE) { + /* content from file as for -F showfilename) { + e = c_escape(pp->showfilename); + if(!e) + goto nomem; + DATA1(" CURLFORM_FILENAME, \"%s\",", e); + free(e); + } + if(pp->contenttype) { + e = c_escape(pp->contenttype); + if(!e) + goto nomem; + DATA1(" CURLFORM_CONTENTTYPE, \"%s\",", e); + free(e); + } + } + DATA0(" CURLFORM_END);"); + } + CODE2("curl_easy_setopt(hnd, %s, post%d);", name, i); + } + + nomem: + return ret; +} + +/* setopt wrapper for curl_slist options */ +CURLcode tool_setopt_slist(CURL *curl, struct Configurable *config, + const char *name, CURLoption tag, + struct curl_slist *list) +{ + CURLcode ret = CURLE_OK; + bool skip = FALSE; + + ret = curl_easy_setopt(curl, tag, list); + if(!list) + skip = TRUE; + + if(config->libcurl && !skip && !ret) { + struct curl_slist *s; + int i; + /* May need several slist variables, so invent name */ + i = ++ easysrc_slist_count; + DECL1("struct curl_slist *slist%d;", i); + DATA1("slist%d = NULL;", i); + CLEAN1("curl_slist_free_all(slist%d);", i); + CLEAN1("slist%d = NULL;", i); + for(s=list; s; s=s->next) { + char *e = c_escape(s->data); + if(!e) + goto nomem; + DATA3("slist%d = curl_slist_append(slist%d, \"%s\");", i, i, e); + free(e); + } + CODE2("curl_easy_setopt(hnd, %s, slist%d);", name, i); + } + + nomem: + return ret; +} + +/* generic setopt wrapper for all other options. + * Some type information is encoded in the tag value. */ CURLcode tool_setopt(CURL *curl, bool str, struct Configurable *config, const char *name, CURLoption tag, ...) { va_list arg; - char *bufp; - char value[256]; + char buf[256]; + const char *value; bool remark = FALSE; bool skip = FALSE; + bool escape = FALSE; CURLcode ret = CURLE_OK; va_start(arg, tag); if(tag < CURLOPTTYPE_OBJECTPOINT) { + /* Value is expected to be a long */ long lval = va_arg(arg, long); - snprintf(value, sizeof(value), "%ldL", lval); + snprintf(buf, sizeof(buf), "%ldL", lval); + value = buf; ret = curl_easy_setopt(curl, tag, lval); if(!lval) skip = TRUE; } else if(tag < CURLOPTTYPE_OFF_T) { + /* Value is some sort of object pointer */ void *pval = va_arg(arg, void *); - unsigned char *ptr = (unsigned char *)pval; /* function pointers are never printable */ if(tag >= CURLOPTTYPE_FUNCTIONPOINT) { if(pval) { - strcpy(value, "functionpointer"); /* 'value' fits 256 bytes */ + value = "functionpointer"; remark = TRUE; } else skip = TRUE; } - else if(pval && str) - snprintf(value, sizeof(value), "\"%s\"", (char *)ptr); + else if(pval && str) { + value = (char *)pval; + escape = TRUE; + } else if(pval) { - strcpy(value, "objectpointer"); /* 'value' fits 256 bytes */ + value = "objectpointer"; remark = TRUE; } else @@ -81,9 +435,11 @@ CURLcode tool_setopt(CURL *curl, bool str, struct Configurable *config, } else { + /* Value is expected to be curl_off_t */ curl_off_t oval = va_arg(arg, curl_off_t); - snprintf(value, sizeof(value), + snprintf(buf, sizeof(buf), "(curl_off_t)%" CURL_FORMAT_CURL_OFF_T, oval); + value = buf; ret = curl_easy_setopt(curl, tag, oval); if(!oval) @@ -96,32 +452,21 @@ CURLcode tool_setopt(CURL *curl, bool str, struct Configurable *config, /* we only use this for real if --libcurl was used */ if(remark) - bufp = curlx_maprintf("%s set to a %s", name, value); - else - bufp = curlx_maprintf("curl_easy_setopt(hnd, %s, %s);", name, value); - - if(!bufp) - ret = CURLE_OUT_OF_MEMORY; + REM2("%s set to a %s", name, value); else { - struct curl_slist *list = - curl_slist_append(remark?easysrc_remarks:easysrc, bufp); - - curl_free(bufp); - - if(!list) { - curl_slist_free_all(easysrc_remarks); - curl_slist_free_all(easysrc); - easysrc_remarks = NULL; - easysrc = NULL; - ret = CURLE_OUT_OF_MEMORY; + if(escape) { + char *escaped = c_escape(value); + if(!escaped) + goto nomem; + CODE2("curl_easy_setopt(hnd, %s, \"%s\");", name, escaped); + free(escaped); } - else if(remark) - easysrc_remarks = list; else - easysrc = list; + CODE2("curl_easy_setopt(hnd, %s, %s);", name, value); } } + nomem: return ret; } -- cgit v1.2.1 From 8af4b657d0f44bd6f2b1d672666c046e53af0e0c Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Fri, 16 Mar 2012 19:06:34 +0100 Subject: fix some compiler warnings --- src/tool_setopt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/tool_setopt.c') diff --git a/src/tool_setopt.c b/src/tool_setopt.c index 5be4c3b39..d9e200e5f 100644 --- a/src/tool_setopt.c +++ b/src/tool_setopt.c @@ -389,7 +389,7 @@ CURLcode tool_setopt(CURL *curl, bool str, struct Configurable *config, { va_list arg; char buf[256]; - const char *value; + const char *value = NULL; bool remark = FALSE; bool skip = FALSE; bool escape = FALSE; -- cgit v1.2.1 From 862bb7bade597eb73128af5d875788c150ca8fcb Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Fri, 16 Mar 2012 20:10:08 +0100 Subject: tool_setopt.c: fix OOM handling --- src/tool_setopt.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) (limited to 'src/tool_setopt.c') diff --git a/src/tool_setopt.c b/src/tool_setopt.c index d9e200e5f..cd87ecedf 100644 --- a/src/tool_setopt.c +++ b/src/tool_setopt.c @@ -129,12 +129,12 @@ const NameValue setopt_nv_CURLPROTO[] = { ret = easysrc_add args; \ if(ret) \ goto nomem; \ -} while(0) +} WHILE_FALSE #define ADDF(args) do { \ ret = easysrc_addf args; \ if(ret) \ goto nomem; \ -} while(0) +} WHILE_FALSE #define DECL0(s) ADD((&easysrc_decl, s)) #define DECL1(f,a) ADDF((&easysrc_decl, f,a)) @@ -310,8 +310,10 @@ CURLcode tool_setopt_httppost(CURL *curl, struct Configurable *config, * these are linked through the 'more' pointer */ char *e; e = c_escape(pp->contents); - if(!e) + if(!e) { + ret = CURLE_OUT_OF_MEMORY; goto nomem; + } if(pp->flags & HTTPPOST_FILENAME) { /* file upload as for -F @filename */ DATA1(" CURLFORM_FILE, \"%s\",", e); @@ -325,15 +327,19 @@ CURLcode tool_setopt_httppost(CURL *curl, struct Configurable *config, free(e); if(pp->showfilename) { e = c_escape(pp->showfilename); - if(!e) + if(!e) { + ret = CURLE_OUT_OF_MEMORY; goto nomem; + } DATA1(" CURLFORM_FILENAME, \"%s\",", e); free(e); } if(pp->contenttype) { e = c_escape(pp->contenttype); - if(!e) + if(!e) { + ret = CURLE_OUT_OF_MEMORY; goto nomem; + } DATA1(" CURLFORM_CONTENTTYPE, \"%s\",", e); free(e); } @@ -370,8 +376,10 @@ CURLcode tool_setopt_slist(CURL *curl, struct Configurable *config, CLEAN1("slist%d = NULL;", i); for(s=list; s; s=s->next) { char *e = c_escape(s->data); - if(!e) + if(!e) { + ret = CURLE_OUT_OF_MEMORY; goto nomem; + } DATA3("slist%d = curl_slist_append(slist%d, \"%s\");", i, i, e); free(e); } @@ -456,8 +464,10 @@ CURLcode tool_setopt(CURL *curl, bool str, struct Configurable *config, else { if(escape) { char *escaped = c_escape(value); - if(!escaped) + if(!escaped) { + ret = CURLE_OUT_OF_MEMORY; goto nomem; + } CODE2("curl_easy_setopt(hnd, %s, \"%s\");", name, escaped); free(escaped); } -- cgit v1.2.1 From 804da995c5ed9df4d28690fba3d5256f45d75ef8 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Sat, 17 Mar 2012 20:55:15 +0100 Subject: tool_setopt.c: more OOM handling fixes --- src/tool_setopt.c | 46 +++++++++++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 21 deletions(-) (limited to 'src/tool_setopt.c') diff --git a/src/tool_setopt.c b/src/tool_setopt.c index cd87ecedf..94e786f24 100644 --- a/src/tool_setopt.c +++ b/src/tool_setopt.c @@ -284,6 +284,7 @@ CURLcode tool_setopt_httppost(CURL *curl, struct Configurable *config, struct curl_httppost *post) { CURLcode ret = CURLE_OK; + char *escaped = NULL; bool skip = FALSE; ret = curl_easy_setopt(curl, tag, post); @@ -308,40 +309,39 @@ CURLcode tool_setopt_httppost(CURL *curl, struct Configurable *config, for(pp=p; pp; pp=pp->more) { /* May be several files uploaded for one name; * these are linked through the 'more' pointer */ - char *e; - e = c_escape(pp->contents); - if(!e) { + Curl_safefree(escaped); + escaped = c_escape(pp->contents); + if(!escaped) { ret = CURLE_OUT_OF_MEMORY; goto nomem; } if(pp->flags & HTTPPOST_FILENAME) { /* file upload as for -F @filename */ - DATA1(" CURLFORM_FILE, \"%s\",", e); + DATA1(" CURLFORM_FILE, \"%s\",", escaped); } else if(pp->flags & HTTPPOST_READFILE) { /* content from file as for -F showfilename) { - e = c_escape(pp->showfilename); - if(!e) { + Curl_safefree(escaped); + escaped = c_escape(pp->showfilename); + if(!escaped) { ret = CURLE_OUT_OF_MEMORY; goto nomem; } - DATA1(" CURLFORM_FILENAME, \"%s\",", e); - free(e); + DATA1(" CURLFORM_FILENAME, \"%s\",", escaped); } if(pp->contenttype) { - e = c_escape(pp->contenttype); - if(!e) { + Curl_safefree(escaped); + escaped = c_escape(pp->contenttype); + if(!escaped) { ret = CURLE_OUT_OF_MEMORY; goto nomem; } - DATA1(" CURLFORM_CONTENTTYPE, \"%s\",", e); - free(e); + DATA1(" CURLFORM_CONTENTTYPE, \"%s\",", escaped); } } DATA0(" CURLFORM_END);"); @@ -350,6 +350,7 @@ CURLcode tool_setopt_httppost(CURL *curl, struct Configurable *config, } nomem: + Curl_safefree(escaped); return ret; } @@ -359,6 +360,7 @@ CURLcode tool_setopt_slist(CURL *curl, struct Configurable *config, struct curl_slist *list) { CURLcode ret = CURLE_OK; + char *escaped = NULL; bool skip = FALSE; ret = curl_easy_setopt(curl, tag, list); @@ -375,18 +377,19 @@ CURLcode tool_setopt_slist(CURL *curl, struct Configurable *config, CLEAN1("curl_slist_free_all(slist%d);", i); CLEAN1("slist%d = NULL;", i); for(s=list; s; s=s->next) { - char *e = c_escape(s->data); - if(!e) { + Curl_safefree(escaped); + escaped = c_escape(s->data); + if(!escaped) { ret = CURLE_OUT_OF_MEMORY; goto nomem; } - DATA3("slist%d = curl_slist_append(slist%d, \"%s\");", i, i, e); - free(e); + DATA3("slist%d = curl_slist_append(slist%d, \"%s\");", i, i, escaped); } CODE2("curl_easy_setopt(hnd, %s, slist%d);", name, i); } nomem: + Curl_safefree(escaped); return ret; } @@ -401,6 +404,7 @@ CURLcode tool_setopt(CURL *curl, bool str, struct Configurable *config, bool remark = FALSE; bool skip = FALSE; bool escape = FALSE; + char *escaped = NULL; CURLcode ret = CURLE_OK; va_start(arg, tag); @@ -463,13 +467,12 @@ CURLcode tool_setopt(CURL *curl, bool str, struct Configurable *config, REM2("%s set to a %s", name, value); else { if(escape) { - char *escaped = c_escape(value); + escaped = c_escape(value); if(!escaped) { ret = CURLE_OUT_OF_MEMORY; goto nomem; } CODE2("curl_easy_setopt(hnd, %s, \"%s\");", name, escaped); - free(escaped); } else CODE2("curl_easy_setopt(hnd, %s, %s);", name, value); @@ -477,6 +480,7 @@ CURLcode tool_setopt(CURL *curl, bool str, struct Configurable *config, } nomem: + Curl_safefree(escaped); return ret; } -- cgit v1.2.1 From 919c97fa65a5c00f7044e849eeb0095408413505 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Fri, 6 Apr 2012 23:35:15 +0200 Subject: curl tool: use configuration files from lib directory Configuration files such as curl_config.h and all config-*.h no longer exist nor are generated/copied into 'src' directory, now these only exist in 'lib' directory from where curl tool sources uses them. Additionally old src/setup.h has been refactored into src/tool_setup.h which now pulls lib/setup.h The possibility of a makefile needing an include path adjustment exists. --- src/tool_setopt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/tool_setopt.c') diff --git a/src/tool_setopt.c b/src/tool_setopt.c index 94e786f24..d387af181 100644 --- a/src/tool_setopt.c +++ b/src/tool_setopt.c @@ -19,7 +19,7 @@ * KIND, either express or implied. * ***************************************************************************/ -#include "setup.h" +#include "tool_setup.h" #ifndef CURL_DISABLE_LIBCURL_OPTION -- cgit v1.2.1 From 01b0f1061da2bd7a8703f4c8aa846a9088d7ab3e Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Sun, 8 Apr 2012 13:50:18 +0200 Subject: curl tool: make curl.h first header included in tool_setup.h --- src/tool_setopt.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/tool_setopt.c') diff --git a/src/tool_setopt.c b/src/tool_setopt.c index d387af181..0b6207be4 100644 --- a/src/tool_setopt.c +++ b/src/tool_setopt.c @@ -23,8 +23,6 @@ #ifndef CURL_DISABLE_LIBCURL_OPTION -#include - #define ENABLE_CURLX_PRINTF /* use our own printf() functions */ #include "curlx.h" -- cgit v1.2.1 From 94111bbbd4f2c875bc33c9c84f6e365c1a1434d7 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Thu, 19 Apr 2012 16:31:11 +0200 Subject: Take in account that CURLAUTH_* bitmasks are now 'unsigned long' - follow-up MIPSPro compiler detected curl_easy_getinfo() related missing adjustments. SunPro compiler detected curl tool --libcurl option related missing adjustments. --- src/tool_setopt.c | 47 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) (limited to 'src/tool_setopt.c') diff --git a/src/tool_setopt.c b/src/tool_setopt.c index 0b6207be4..9aefc21d5 100644 --- a/src/tool_setopt.c +++ b/src/tool_setopt.c @@ -51,7 +51,7 @@ const NameValue setopt_nv_CURLPROXY[] = { NVEND, }; -const NameValue setopt_nv_CURLAUTH[] = { +const NameValueUnsigned setopt_nv_CURLAUTH[] = { NV(CURLAUTH_ANY), /* combination */ NV(CURLAUTH_ANYSAFE), /* combination */ NV(CURLAUTH_BASIC), @@ -234,7 +234,7 @@ CURLcode tool_setopt_enum(CURL *curl, struct Configurable *config, return ret; } -/* setopt wrapper for bit mask */ +/* setopt wrapper for flags */ CURLcode tool_setopt_flags(CURL *curl, struct Configurable *config, const char *name, CURLoption tag, const NameValue *nvlist, long lval) @@ -276,6 +276,49 @@ CURLcode tool_setopt_flags(CURL *curl, struct Configurable *config, return ret; } +/* setopt wrapper for bitmasks */ +CURLcode tool_setopt_bitmask(CURL *curl, struct Configurable *config, + const char *name, CURLoption tag, + const NameValueUnsigned *nvlist, + long lval) +{ + CURLcode ret = CURLE_OK; + bool skip = FALSE; + + ret = curl_easy_setopt(curl, tag, lval); + if(!lval) + skip = TRUE; + + if(config->libcurl && !skip && !ret) { + /* we only use this for real if --libcurl was used */ + char preamble[80]; + unsigned long rest = (unsigned long)lval; + const NameValueUnsigned *nv = NULL; + snprintf(preamble, sizeof(preamble), + "curl_easy_setopt(hnd, %s, ", name); + for(nv=nvlist; nv->name; nv++) { + if((nv->value & ~ rest) == 0) { + /* all value flags contained in rest */ + rest &= ~ nv->value; /* remove bits handled here */ + CODE3("%s(long)%s%s", + preamble, nv->name, rest ? " |" : ");"); + if(!rest) + break; /* handled them all */ + /* replace with all spaces for continuation line */ + sprintf(preamble, "%*s", strlen(preamble), ""); + } + } + /* If any bits have no definition, output an explicit value. + * This could happen if new bits are defined and used + * but the NameValue list is not updated. */ + if(rest) + CODE2("%s%luUL);", preamble, rest); + } + + nomem: + return ret; +} + /* setopt wrapper for CURLOPT_HTTPPOST */ CURLcode tool_setopt_httppost(CURL *curl, struct Configurable *config, const char *name, CURLoption tag, -- cgit v1.2.1