summaryrefslogtreecommitdiff
path: root/src/tool_setopt.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/tool_setopt.c')
-rw-r--r--src/tool_setopt.c300
1 files changed, 156 insertions, 144 deletions
diff --git a/src/tool_setopt.c b/src/tool_setopt.c
index cd28ad829..745b4546e 100644
--- a/src/tool_setopt.c
+++ b/src/tool_setopt.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -32,7 +32,6 @@
#include "tool_setopt.h"
#include "tool_convert.h"
-#include "mime.h"
#include "memdebug.h" /* keep this as LAST include */
/* Lookup tables for converting setopt values back to symbols */
@@ -187,6 +186,12 @@ static const NameValue setopt_nv_CURLNONZERODEFAULTS[] = {
if(ret) \
goto nomem; \
} WHILE_FALSE
+#define NULL_CHECK(p) do { \
+ if(!p) { \
+ ret = CURLE_OUT_OF_MEMORY; \
+ goto nomem; \
+ } \
+} WHILE_FALSE
#define DECL0(s) ADD((&easysrc_decl, s))
#define DECL1(f,a) ADDF((&easysrc_decl, f,a))
@@ -406,174 +411,184 @@ static CURLcode libcurl_generate_slist(struct curl_slist *slist, int *slistno)
return ret;
}
-/* Generate source code for a mime structure. */
-static CURLcode libcurl_generate_mime(curl_mime *mime, int *mimeno)
+static CURLcode libcurl_generate_mime(CURL *curl,
+ struct GlobalConfig *config,
+ tool_mime *toolmime,
+ int *mimeno); /* Forward. */
+
+/* Wrapper to generate source code for a mime part. */
+static CURLcode libcurl_generate_mime_part(CURL *curl,
+ struct GlobalConfig *config,
+ tool_mime *part,
+ int mimeno)
{
CURLcode ret = CURLE_OK;
- int i;
- curl_off_t size;
- curl_mimepart *part;
- char *filename;
+ int submimeno = 0;
char *escaped = NULL;
- char *cp;
- char *data;
+ const char *data = NULL;
+ const char *filename = part->filename;
+
+ /* Parts are linked in reverse order. */
+ if(part->prev) {
+ ret = libcurl_generate_mime_part(curl, config, part->prev, mimeno);
+ if(ret)
+ return ret;
+ }
- /* May need several mime variables, so invent name */
- *mimeno = ++easysrc_mime_count;
+ /* Create the part. */
+ CODE2("part%d = curl_mime_addpart(mime%d);", mimeno, mimeno);
- DECL1("curl_mime *mime%d;", *mimeno);
- DATA1("mime%d = NULL;", *mimeno);
- CODE1("mime%d = curl_mime_init(hnd);", *mimeno);
- CLEAN1("curl_mime_free(mime%d);", *mimeno);
- CLEAN1("mime%d = NULL;", *mimeno);
- if(mime->firstpart) {
- DECL1("curl_mimepart *part%d;", *mimeno);
- for(part = mime->firstpart; part; part = part->nextpart) {
- CODE2("part%d = curl_mime_addpart(mime%d);", *mimeno, *mimeno);
- filename = part->filename;
- switch(part->kind) {
- case MIMEKIND_FILE:
- Curl_safefree(escaped);
- escaped = c_escape(part->data, CURL_ZERO_TERMINATED);
- if(!escaped)
- return CURLE_OUT_OF_MEMORY;
- CODE2("curl_mime_filedata(part%d, \"%s\");", *mimeno, escaped);
- if(!filename)
- CODE1("curl_mime_filename(part%d, NULL);", *mimeno);
- else {
- /* Fast check to see if remote file name is base name. */
- filename = part->data;
- for(cp = filename; *cp; cp++)
- if(*cp == '/' || *cp == '\\')
- filename = cp + 1;
- if(!part->filename || !strcmp(filename, part->filename))
- filename = NULL;
- else
- filename = part->filename;
- }
- break;
- case MIMEKIND_CALLBACK:
- /* Can only be reading stdin in the current context. */
- CODE1("curl_mime_data_cb(part%d, -1, (curl_read_callback) fread, \\",
- *mimeno);
- CODE0(" (curl_seek_callback) fseek, NULL, stdin);");
- break;
- case MIMEKIND_DATA:
-#ifdef CURL_DOES_CONVERSIONS
- /* Data is stored in ASCII and we want in in the host character
- code. Convert it back for output. */
- data = malloc(part->datasize + 1);
- if(!data) {
- ret = CURLE_OUT_OF_MEMORY;
- goto nomem;
- }
- memcpy(data, part->data, part->datasize + 1);
- ret = convert_from_network(data, strlen(data));
- if(ret) {
- Curl_safefree(data);
- goto nomem;
- }
-#else
- data = part->data;
-#endif
+ switch(part->kind) {
+ case TOOLMIME_PARTS:
+ ret = libcurl_generate_mime(curl, config, part, &submimeno);
+ if(!ret) {
+ CODE2("curl_mime_subparts(part%d, mime%d);", mimeno, submimeno);
+ CODE1("mime%d = NULL;", submimeno); /* Avoid freeing in CLEAN. */
+ }
+ break;
- /* Are there any nul byte in data? */
- for(cp = data; *cp; cp++)
- ;
- size = (cp == data + part->datasize)? (curl_off_t) -1: part->datasize;
- Curl_safefree(escaped);
- escaped = c_escape(data, (size_t) part->datasize);
+ case TOOLMIME_DATA:
#ifdef CURL_DOES_CONVERSIONS
- Curl_safefree(data);
+ /* Data will be set in ASCII, thus issue a comment with clear text. */
+ escaped = c_escape(part->data, CURL_ZERO_TERMINATED);
+ NULL_CHECK(escaped);
+ CODE1("/* \"%s\" */", escaped);
+
+ /* Our data is always textual: convert it to ASCII. */
+ {
+ size_t size = strlen(part->data);
+ char *cp = malloc(size + 1);
+
+ NULL_CHECK(cp);
+ memcpy(cp, part->data, size + 1);
+ ret = convert_to_network(cp, size);
+ data = cp;
+ }
+#else
+ data = part->data;
#endif
- if(!escaped)
- return CURLE_OUT_OF_MEMORY;
- if(size >= 0)
- CODE3("curl_mime_data(part%d, \"%s\", %" CURL_FORMAT_CURL_OFF_T ");",
- *mimeno, escaped, size);
- else
- CODE2("curl_mime_data(part%d, \"%s\", CURL_ZERO_TERMINATED);",
- *mimeno, escaped);
- break;
- case MIMEKIND_MULTIPART:
- ret = libcurl_generate_mime(part->arg, &i);
- if(ret)
- goto nomem;
- CODE2("curl_mime_subparts(part%d, mime%d);", *mimeno, i);
- CODE1("mime%d = NULL;", i); /* Avoid freeing in CLEAN sequence. */
- break;
- default:
- /* Other cases not possible in this context. */
- break;
- }
+ if(!ret) {
+ Curl_safefree(escaped);
+ escaped = c_escape(data, CURL_ZERO_TERMINATED);
+ NULL_CHECK(escaped);
+ CODE2("curl_mime_data(part%d, \"%s\", CURL_ZERO_TERMINATED);",
+ mimeno, escaped);
+ }
+ break;
+
+ case TOOLMIME_FILE:
+ case TOOLMIME_FILEDATA:
+ escaped = c_escape(part->data, CURL_ZERO_TERMINATED);
+ NULL_CHECK(escaped);
+ CODE2("curl_mime_filedata(part%d, \"%s\");", mimeno, escaped);
+ if(part->kind == TOOLMIME_FILEDATA && !filename) {
+ CODE1("curl_mime_filename(part%d, NULL);", mimeno);
+ }
+ break;
+
+ case TOOLMIME_STDIN:
+ if(!filename)
+ filename = "-";
+ /* FALLTHROUGH */
+ case TOOLMIME_STDINDATA:
+ /* Can only be reading stdin in the current context. */
+ CODE1("curl_mime_data_cb(part%d, -1, (curl_read_callback) fread, \\",
+ mimeno);
+ CODE0(" (curl_seek_callback) fseek, NULL, stdin);");
+ break;
+ default:
+ /* Other cases not possible in this context. */
+ break;
+ }
- if(part->encoder) {
- Curl_safefree(escaped);
- escaped = c_escape(part->encoder->name, CURL_ZERO_TERMINATED);
- if(!escaped)
- return CURLE_OUT_OF_MEMORY;
- CODE2("curl_mime_encoder(part%d, \"%s\");", *mimeno, escaped);
- }
+ if(!ret && part->encoder) {
+ Curl_safefree(escaped);
+ escaped = c_escape(part->encoder, CURL_ZERO_TERMINATED);
+ NULL_CHECK(escaped);
+ CODE2("curl_mime_encoder(part%d, \"%s\");", mimeno, escaped);
+ }
- if(filename) {
- Curl_safefree(escaped);
- escaped = c_escape(filename, CURL_ZERO_TERMINATED);
- if(!escaped)
- return CURLE_OUT_OF_MEMORY;
- CODE2("curl_mime_filename(part%d, \"%s\");", *mimeno, escaped);
- }
+ if(!ret && filename) {
+ Curl_safefree(escaped);
+ escaped = c_escape(filename, CURL_ZERO_TERMINATED);
+ NULL_CHECK(escaped);
+ CODE2("curl_mime_filename(part%d, \"%s\");", mimeno, escaped);
+ }
- if(part->name) {
- Curl_safefree(escaped);
- escaped = c_escape(part->name, CURL_ZERO_TERMINATED);
- if(!escaped)
- return CURLE_OUT_OF_MEMORY;
- CODE2("curl_mime_name(part%d, \"%s\");", *mimeno, escaped);
- }
+ if(!ret && part->name) {
+ Curl_safefree(escaped);
+ escaped = c_escape(part->name, CURL_ZERO_TERMINATED);
+ NULL_CHECK(escaped);
+ CODE2("curl_mime_name(part%d, \"%s\");", mimeno, escaped);
+ }
- if(part->mimetype) {
- Curl_safefree(escaped);
- escaped = c_escape(part->mimetype, CURL_ZERO_TERMINATED);
- if(!escaped)
- return CURLE_OUT_OF_MEMORY;
- CODE2("curl_mime_type(part%d, \"%s\");", *mimeno, escaped);
- }
+ if(!ret && part->type) {
+ Curl_safefree(escaped);
+ escaped = c_escape(part->type, CURL_ZERO_TERMINATED);
+ NULL_CHECK(escaped);
+ CODE2("curl_mime_type(part%d, \"%s\");", mimeno, escaped);
+ }
- if(part->userheaders) {
- int ownership = part->flags & MIME_USERHEADERS_OWNER? 1: 0;
+ if(!ret && part->headers) {
+ int slistno;
- ret = libcurl_generate_slist(part->userheaders, &i);
- if(ret)
- goto nomem;
- CODE3("curl_mime_headers(part%d, slist%d, %d);",
- *mimeno, i, ownership);
- if(ownership)
- CODE1("slist%d = NULL;", i); /* Prevent freeing in CLEAN sequence. */
- }
+ ret = libcurl_generate_slist(part->headers, &slistno);
+ if(!ret) {
+ CODE2("curl_mime_headers(part%d, slist%d, 1);", mimeno, slistno);
+ CODE1("slist%d = NULL;", slistno); /* Prevent CLEANing. */
}
}
nomem:
+#ifdef CURL_DOES_CONVERSIONS
+ if(data)
+ free((char *) data);
+#endif
+
Curl_safefree(escaped);
return ret;
}
+/* Wrapper to generate source code for a mime structure. */
+static CURLcode libcurl_generate_mime(CURL *curl,
+ struct GlobalConfig *config,
+ tool_mime *toolmime,
+ int *mimeno)
+{
+ CURLcode ret = CURLE_OK;
+
+ /* May need several mime variables, so invent name. */
+ *mimeno = ++easysrc_mime_count;
+ DECL1("curl_mime *mime%d;", *mimeno);
+ DATA1("mime%d = NULL;", *mimeno);
+ CODE1("mime%d = curl_mime_init(hnd);", *mimeno);
+ CLEAN1("curl_mime_free(mime%d);", *mimeno);
+ CLEAN1("mime%d = NULL;", *mimeno);
+
+ if(toolmime->subparts) {
+ DECL1("curl_mimepart *part%d;", *mimeno);
+ ret = libcurl_generate_mime_part(curl, config,
+ toolmime->subparts, *mimeno);
+ }
+
+nomem:
+ return ret;
+}
+
/* setopt wrapper for CURLOPT_MIMEPOST */
CURLcode tool_setopt_mimepost(CURL *curl, struct GlobalConfig *config,
const char *name, CURLoption tag,
curl_mime *mimepost)
{
- CURLcode ret = CURLE_OK;
-
- ret = curl_easy_setopt(curl, tag, mimepost);
-
- if(config->libcurl && mimepost && !ret) {
- int i;
+ CURLcode ret = curl_easy_setopt(curl, tag, mimepost);
+ int mimeno = 0;
- ret = libcurl_generate_mime(mimepost, &i);
+ if(!ret && config->libcurl) {
+ ret = libcurl_generate_mime(curl, config,
+ config->current->mimeroot, &mimeno);
if(!ret)
- CODE2("curl_easy_setopt(hnd, %s, mime%d);", name, i);
+ CODE2("curl_easy_setopt(hnd, %s, mime%d);", name, mimeno);
}
nomem:
@@ -685,10 +700,7 @@ CURLcode tool_setopt(CURL *curl, bool str, struct GlobalConfig *config,
else {
if(escape) {
escaped = c_escape(value, CURL_ZERO_TERMINATED);
- if(!escaped) {
- ret = CURLE_OUT_OF_MEMORY;
- goto nomem;
- }
+ NULL_CHECK(escaped);
CODE2("curl_easy_setopt(hnd, %s, \"%s\");", name, escaped);
}
else