tool_mime_free(mime->subparts);
if(mime->prev)
tool_mime_free(mime->prev);
- curl_mime_free(mime->handle);
CONST_SAFEFREE(mime->name);
CONST_SAFEFREE(mime->filename);
CONST_SAFEFREE(mime->type);
return CURL_SEEKFUNC_OK;
}
+/* Translate an internal mime tree into a libcurl mime tree. */
+
+static CURLcode tool2curlparts(CURL *curl, tool_mime *m, curl_mime *mime)
+{
+ CURLcode ret = CURLE_OK;
+ curl_mimepart *part = NULL;
+ curl_mime *submime = NULL;
+ const char *filename = NULL;
+
+ if(m) {
+ ret = tool2curlparts(curl, m->prev, mime);
+ if(!ret) {
+ part = curl_mime_addpart(mime);
+ if(!part)
+ ret = CURLE_OUT_OF_MEMORY;
+ }
+ if(!ret) {
+ filename = m->filename;
+ switch(m->kind) {
+ case TOOLMIME_PARTS:
+ ret = tool2curlmime(curl, m, &submime);
+ if(!ret) {
+ ret = curl_mime_subparts(part, submime);
+ if(ret)
+ curl_mime_free(submime);
+ }
+ break;
+
+ case TOOLMIME_DATA:
+#ifdef CURL_DOES_CONVERSIONS
+ /* Our data is always textual: convert it to ASCII. */
+ {
+ size_t size = strlen(m->data);
+ char *cp = malloc(size + 1);
+
+ if(!cp)
+ ret = CURLE_OUT_OF_MEMORY;
+ else {
+ memcpy(cp, m->data, size + 1);
+ ret = convert_to_network(cp, size);
+ if(!ret)
+ ret = curl_mime_data(part, cp, CURL_ZERO_TERMINATED);
+ free(cp);
+ }
+ }
+#else
+ ret = curl_mime_data(part, m->data, CURL_ZERO_TERMINATED);
+#endif
+ break;
+
+ case TOOLMIME_FILE:
+ case TOOLMIME_FILEDATA:
+ ret = curl_mime_filedata(part, m->data);
+ if(!ret && m->kind == TOOLMIME_FILEDATA && !filename)
+ ret = curl_mime_filename(part, NULL);
+ break;
+
+ case TOOLMIME_STDIN:
+ if(!filename)
+ filename = "-";
+ /* FALLTHROUGH */
+ case TOOLMIME_STDINDATA:
+ ret = curl_mime_data_cb(part, m->size,
+ (curl_read_callback) tool_mime_stdin_read,
+ (curl_seek_callback) tool_mime_stdin_seek,
+ NULL, m);
+ break;
+
+ default:
+ /* Other cases not possible in this context. */
+ break;
+ }
+ }
+ if(!ret && filename)
+ ret = curl_mime_filename(part, filename);
+ if(!ret)
+ ret = curl_mime_type(part, m->type);
+ if(!ret)
+ ret = curl_mime_headers(part, m->headers, 0);
+ if(!ret)
+ ret = curl_mime_encoder(part, m->encoder);
+ if(!ret)
+ ret = curl_mime_name(part, m->name);
+ }
+ return ret;
+}
+
+CURLcode tool2curlmime(CURL *curl, tool_mime *m, curl_mime **mime)
+{
+ CURLcode ret = CURLE_OK;
+
+ *mime = curl_mime_init(curl);
+ if(!*mime)
+ ret = CURLE_OUT_OF_MEMORY;
+ else
+ ret = tool2curlparts(curl, m->subparts, *mime);
+ if(ret) {
+ curl_mime_free(*mime);
+ *mime = NULL;
+ }
+ return ret;
+}
+
/*
* helper function to get a word from form param
* after call get_parm_word, str either point to string end
int formparse(struct OperationConfig *config,
const char *input,
- tool_mime **mimepost,
+ tool_mime **mimeroot,
tool_mime **mimecurrent,
bool literal_value)
{
/* Allocate the main mime structure if needed. */
if(!*mimecurrent) {
- NULL_CHECK(*mimepost, tool_mime_new_parts(NULL), 1);
- *mimecurrent = *mimepost;
+ NULL_CHECK(*mimeroot, tool_mime_new_parts(NULL), 1);
+ *mimecurrent = *mimeroot;
}
/* Make a copy we can overwrite. */
}
else if(!name && !strcmp(contp, ")") && !literal_value) {
/* Ending a multipart. */
- if(*mimecurrent == *mimepost) {
+ if(*mimecurrent == *mimeroot) {
warnf(config->global, "no multipart to terminate!\n");
Curl_safefree(contents);
return 6;
tool_mime_new_filedata(subparts, data, TRUE, &res), 9);
part->headers = headers;
headers = NULL;
+ part->config = config->global;
if(res == CURLE_READ_ERROR) {
/* An error occurred while reading stdin: if read has started,
issue the error now. Else, delay it until processed by
&res), 15);
part->headers = headers;
headers = NULL;
+ part->config = config->global;
if(res == CURLE_READ_ERROR) {
/* An error occurred while reading stdin: if read has started,
issue the error now. Else, delay it until processed by
static CURLcode libcurl_generate_mime(CURL *curl,
struct GlobalConfig *config,
tool_mime *toolmime,
- curl_mime **mime,
int *mimeno); /* Forward. */
-/* Wrapper to build and generate source code for a mime part. */
+/* Wrapper to generate source code for a mime part. */
static CURLcode libcurl_generate_mime_part(CURL *curl,
struct GlobalConfig *config,
tool_mime *part,
- curl_mime *mime,
int mimeno)
{
CURLcode ret = CURLE_OK;
- curl_mimepart *mimepart;
int submimeno = 0;
- curl_mime *submime = NULL;
char *escaped = NULL;
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, mime, mimeno);
+ ret = libcurl_generate_mime_part(curl, config, part->prev, mimeno);
if(ret)
return ret;
}
/* Create the part. */
- mimepart = curl_mime_addpart(mime);
- NULL_CHECK(mimepart);
- if(config->libcurl)
- CODE2("part%d = curl_mime_addpart(mime%d);", mimeno, mimeno);
+ CODE2("part%d = curl_mime_addpart(mime%d);", mimeno, mimeno);
switch(part->kind) {
case TOOLMIME_PARTS:
- ret = libcurl_generate_mime(curl, config, part, &submime, &submimeno);
+ ret = libcurl_generate_mime(curl, config, part, &submimeno);
if(!ret) {
- ret = curl_mime_subparts(mimepart, submime);
- if(!ret) {
- submime = NULL;
- if(config->libcurl) {
- CODE2("curl_mime_subparts(part%d, mime%d);", mimeno, submimeno);
- CODE1("mime%d = NULL;", submimeno); /* Avoid freeing in CLEAN. */
- }
- }
+ CODE2("curl_mime_subparts(part%d, mime%d);", mimeno, submimeno);
+ CODE1("mime%d = NULL;", submimeno); /* Avoid freeing in CLEAN. */
}
break;
case TOOLMIME_DATA:
#ifdef CURL_DOES_CONVERSIONS
- if(config->libcurl) {
- /* 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);
- }
+ /* 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. */
{
#else
data = part->data;
#endif
- if(!ret)
- ret = curl_mime_data(mimepart, data, CURL_ZERO_TERMINATED);
- if(!ret && config->libcurl) {
+ if(!ret) {
Curl_safefree(escaped);
escaped = c_escape(data, CURL_ZERO_TERMINATED);
NULL_CHECK(escaped);
case TOOLMIME_FILE:
case TOOLMIME_FILEDATA:
- ret = curl_mime_filedata(mimepart, part->data);
- if(!ret && config->libcurl) {
- escaped = c_escape(part->data, CURL_ZERO_TERMINATED);
- NULL_CHECK(escaped);
- CODE2("curl_mime_filedata(part%d, \"%s\");", mimeno, escaped);
- }
- if(!ret && part->kind == TOOLMIME_FILEDATA && !filename) {
- ret = curl_mime_filename(mimepart, NULL);
- if(!ret && config->libcurl)
- CODE1("curl_mime_filename(part%d, NULL);", mimeno);
+ 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;
filename = "-";
/* FALLTHROUGH */
case TOOLMIME_STDINDATA:
- part->config = config;
- ret = curl_mime_data_cb(mimepart, part->size,
- (curl_read_callback) tool_mime_stdin_read,
- (curl_seek_callback) tool_mime_stdin_seek,
- NULL, part);
- if(!ret && config->libcurl) {
- /* 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);");
- }
+ /* 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. */
}
if(!ret && part->encoder) {
- ret = curl_mime_encoder(mimepart, part->encoder);
- if(!ret && config->libcurl) {
- Curl_safefree(escaped);
- escaped = c_escape(part->encoder, CURL_ZERO_TERMINATED);
- NULL_CHECK(escaped);
- CODE2("curl_mime_encoder(part%d, \"%s\");", mimeno, escaped);
- }
+ Curl_safefree(escaped);
+ escaped = c_escape(part->encoder, CURL_ZERO_TERMINATED);
+ NULL_CHECK(escaped);
+ CODE2("curl_mime_encoder(part%d, \"%s\");", mimeno, escaped);
}
if(!ret && filename) {
- ret = curl_mime_filename(mimepart, filename);
- if(!ret && config->libcurl) {
- Curl_safefree(escaped);
- escaped = c_escape(filename, CURL_ZERO_TERMINATED);
- NULL_CHECK(escaped);
- CODE2("curl_mime_filename(part%d, \"%s\");", mimeno, escaped);
- }
+ Curl_safefree(escaped);
+ escaped = c_escape(filename, CURL_ZERO_TERMINATED);
+ NULL_CHECK(escaped);
+ CODE2("curl_mime_filename(part%d, \"%s\");", mimeno, escaped);
}
if(!ret && part->name) {
- ret = curl_mime_name(mimepart, part->name);
- if(!ret && config->libcurl) {
- Curl_safefree(escaped);
- escaped = c_escape(part->name, CURL_ZERO_TERMINATED);
- NULL_CHECK(escaped);
- CODE2("curl_mime_name(part%d, \"%s\");", mimeno, escaped);
- }
+ Curl_safefree(escaped);
+ escaped = c_escape(part->name, CURL_ZERO_TERMINATED);
+ NULL_CHECK(escaped);
+ CODE2("curl_mime_name(part%d, \"%s\");", mimeno, escaped);
}
if(!ret && part->type) {
- ret = curl_mime_type(mimepart, part->type);
- if(!ret && config->libcurl) {
- Curl_safefree(escaped);
- escaped = c_escape(part->type, CURL_ZERO_TERMINATED);
- NULL_CHECK(escaped);
- CODE2("curl_mime_type(part%d, \"%s\");", mimeno, escaped);
- }
+ Curl_safefree(escaped);
+ escaped = c_escape(part->type, CURL_ZERO_TERMINATED);
+ NULL_CHECK(escaped);
+ CODE2("curl_mime_type(part%d, \"%s\");", mimeno, escaped);
}
if(!ret && part->headers) {
- ret = curl_mime_headers(mimepart, part->headers, 0);
- if(!ret && config->libcurl) {
- int slistno;
-
- 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. */
- }
+ int slistno;
+
+ 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. */
}
}
free((char *) data);
#endif
- curl_mime_free(submime);
Curl_safefree(escaped);
return ret;
}
-/* Wrapper to build and generate source code for a mime structure. */
+/* Wrapper to generate source code for a mime structure. */
static CURLcode libcurl_generate_mime(CURL *curl,
struct GlobalConfig *config,
tool_mime *toolmime,
- curl_mime **mime,
int *mimeno)
{
CURLcode ret = CURLE_OK;
- *mime = curl_mime_init(curl);
- NULL_CHECK(*mime);
-
- if(config->libcurl) {
- /* 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);
- }
+ /* 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) {
- if(config->libcurl)
- DECL1("curl_mimepart *part%d;", *mimeno);
+ DECL1("curl_mimepart *part%d;", *mimeno);
ret = libcurl_generate_mime_part(curl, config,
- toolmime->subparts, *mime, *mimeno);
+ toolmime->subparts, *mimeno);
}
nomem:
/* setopt wrapper for CURLOPT_MIMEPOST */
CURLcode tool_setopt_mimepost(CURL *curl, struct GlobalConfig *config,
const char *name, CURLoption tag,
- tool_mime *mimepost)
+ curl_mime *mimepost)
{
- CURLcode ret = CURLE_OK;
+ CURLcode ret = curl_easy_setopt(curl, tag, mimepost);
int mimeno = 0;
- ret = libcurl_generate_mime(curl, config, mimepost,
- &mimepost->handle, &mimeno);
-
- if(!ret) {
- ret = curl_easy_setopt(curl, tag, mimepost->handle);
+ if(!ret && config->libcurl) {
+ ret = libcurl_generate_mime(curl, config,
+ config->current->mimeroot, &mimeno);
- if(config->libcurl && !ret)
+ if(!ret)
CODE2("curl_easy_setopt(hnd, %s, mime%d);", name, mimeno);
}