xref: /aosp_15_r20/external/curl/lib/formdata.c (revision 6236dae45794135f37c4eb022389c904c8b0090d)
1*6236dae4SAndroid Build Coastguard Worker /***************************************************************************
2*6236dae4SAndroid Build Coastguard Worker  *                                  _   _ ____  _
3*6236dae4SAndroid Build Coastguard Worker  *  Project                     ___| | | |  _ \| |
4*6236dae4SAndroid Build Coastguard Worker  *                             / __| | | | |_) | |
5*6236dae4SAndroid Build Coastguard Worker  *                            | (__| |_| |  _ <| |___
6*6236dae4SAndroid Build Coastguard Worker  *                             \___|\___/|_| \_\_____|
7*6236dae4SAndroid Build Coastguard Worker  *
8*6236dae4SAndroid Build Coastguard Worker  * Copyright (C) Daniel Stenberg, <[email protected]>, et al.
9*6236dae4SAndroid Build Coastguard Worker  *
10*6236dae4SAndroid Build Coastguard Worker  * This software is licensed as described in the file COPYING, which
11*6236dae4SAndroid Build Coastguard Worker  * you should have received as part of this distribution. The terms
12*6236dae4SAndroid Build Coastguard Worker  * are also available at https://curl.se/docs/copyright.html.
13*6236dae4SAndroid Build Coastguard Worker  *
14*6236dae4SAndroid Build Coastguard Worker  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15*6236dae4SAndroid Build Coastguard Worker  * copies of the Software, and permit persons to whom the Software is
16*6236dae4SAndroid Build Coastguard Worker  * furnished to do so, under the terms of the COPYING file.
17*6236dae4SAndroid Build Coastguard Worker  *
18*6236dae4SAndroid Build Coastguard Worker  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19*6236dae4SAndroid Build Coastguard Worker  * KIND, either express or implied.
20*6236dae4SAndroid Build Coastguard Worker  *
21*6236dae4SAndroid Build Coastguard Worker  * SPDX-License-Identifier: curl
22*6236dae4SAndroid Build Coastguard Worker  *
23*6236dae4SAndroid Build Coastguard Worker  ***************************************************************************/
24*6236dae4SAndroid Build Coastguard Worker 
25*6236dae4SAndroid Build Coastguard Worker #include "curl_setup.h"
26*6236dae4SAndroid Build Coastguard Worker 
27*6236dae4SAndroid Build Coastguard Worker #include <curl/curl.h>
28*6236dae4SAndroid Build Coastguard Worker 
29*6236dae4SAndroid Build Coastguard Worker struct Curl_easy;
30*6236dae4SAndroid Build Coastguard Worker 
31*6236dae4SAndroid Build Coastguard Worker #include "formdata.h"
32*6236dae4SAndroid Build Coastguard Worker #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_FORM_API)
33*6236dae4SAndroid Build Coastguard Worker 
34*6236dae4SAndroid Build Coastguard Worker #if defined(HAVE_LIBGEN_H) && defined(HAVE_BASENAME)
35*6236dae4SAndroid Build Coastguard Worker #include <libgen.h>
36*6236dae4SAndroid Build Coastguard Worker #endif
37*6236dae4SAndroid Build Coastguard Worker 
38*6236dae4SAndroid Build Coastguard Worker #include "urldata.h" /* for struct Curl_easy */
39*6236dae4SAndroid Build Coastguard Worker #include "mime.h"
40*6236dae4SAndroid Build Coastguard Worker #include "vtls/vtls.h"
41*6236dae4SAndroid Build Coastguard Worker #include "strcase.h"
42*6236dae4SAndroid Build Coastguard Worker #include "sendf.h"
43*6236dae4SAndroid Build Coastguard Worker #include "strdup.h"
44*6236dae4SAndroid Build Coastguard Worker #include "rand.h"
45*6236dae4SAndroid Build Coastguard Worker #include "warnless.h"
46*6236dae4SAndroid Build Coastguard Worker /* The last 3 #include files should be in this order */
47*6236dae4SAndroid Build Coastguard Worker #include "curl_printf.h"
48*6236dae4SAndroid Build Coastguard Worker #include "curl_memory.h"
49*6236dae4SAndroid Build Coastguard Worker #include "memdebug.h"
50*6236dae4SAndroid Build Coastguard Worker 
51*6236dae4SAndroid Build Coastguard Worker 
52*6236dae4SAndroid Build Coastguard Worker #define HTTPPOST_PTRNAME CURL_HTTPPOST_PTRNAME
53*6236dae4SAndroid Build Coastguard Worker #define HTTPPOST_FILENAME CURL_HTTPPOST_FILENAME
54*6236dae4SAndroid Build Coastguard Worker #define HTTPPOST_PTRCONTENTS CURL_HTTPPOST_PTRCONTENTS
55*6236dae4SAndroid Build Coastguard Worker #define HTTPPOST_READFILE CURL_HTTPPOST_READFILE
56*6236dae4SAndroid Build Coastguard Worker #define HTTPPOST_PTRBUFFER CURL_HTTPPOST_PTRBUFFER
57*6236dae4SAndroid Build Coastguard Worker #define HTTPPOST_CALLBACK CURL_HTTPPOST_CALLBACK
58*6236dae4SAndroid Build Coastguard Worker #define HTTPPOST_BUFFER CURL_HTTPPOST_BUFFER
59*6236dae4SAndroid Build Coastguard Worker 
60*6236dae4SAndroid Build Coastguard Worker /***************************************************************************
61*6236dae4SAndroid Build Coastguard Worker  *
62*6236dae4SAndroid Build Coastguard Worker  * AddHttpPost()
63*6236dae4SAndroid Build Coastguard Worker  *
64*6236dae4SAndroid Build Coastguard Worker  * Adds an HttpPost structure to the list, if parent_post is given becomes
65*6236dae4SAndroid Build Coastguard Worker  * a subpost of parent_post instead of a direct list element.
66*6236dae4SAndroid Build Coastguard Worker  *
67*6236dae4SAndroid Build Coastguard Worker  * Returns newly allocated HttpPost on success and NULL if malloc failed.
68*6236dae4SAndroid Build Coastguard Worker  *
69*6236dae4SAndroid Build Coastguard Worker  ***************************************************************************/
70*6236dae4SAndroid Build Coastguard Worker static struct curl_httppost *
AddHttpPost(char * name,size_t namelength,char * value,curl_off_t contentslength,char * buffer,size_t bufferlength,char * contenttype,long flags,struct curl_slist * contentHeader,char * showfilename,char * userp,struct curl_httppost * parent_post,struct curl_httppost ** httppost,struct curl_httppost ** last_post)71*6236dae4SAndroid Build Coastguard Worker AddHttpPost(char *name, size_t namelength,
72*6236dae4SAndroid Build Coastguard Worker             char *value, curl_off_t contentslength,
73*6236dae4SAndroid Build Coastguard Worker             char *buffer, size_t bufferlength,
74*6236dae4SAndroid Build Coastguard Worker             char *contenttype,
75*6236dae4SAndroid Build Coastguard Worker             long flags,
76*6236dae4SAndroid Build Coastguard Worker             struct curl_slist *contentHeader,
77*6236dae4SAndroid Build Coastguard Worker             char *showfilename, char *userp,
78*6236dae4SAndroid Build Coastguard Worker             struct curl_httppost *parent_post,
79*6236dae4SAndroid Build Coastguard Worker             struct curl_httppost **httppost,
80*6236dae4SAndroid Build Coastguard Worker             struct curl_httppost **last_post)
81*6236dae4SAndroid Build Coastguard Worker {
82*6236dae4SAndroid Build Coastguard Worker   struct curl_httppost *post;
83*6236dae4SAndroid Build Coastguard Worker   if(!namelength && name)
84*6236dae4SAndroid Build Coastguard Worker     namelength = strlen(name);
85*6236dae4SAndroid Build Coastguard Worker   if((bufferlength > LONG_MAX) || (namelength > LONG_MAX))
86*6236dae4SAndroid Build Coastguard Worker     /* avoid overflow in typecasts below */
87*6236dae4SAndroid Build Coastguard Worker     return NULL;
88*6236dae4SAndroid Build Coastguard Worker   post = calloc(1, sizeof(struct curl_httppost));
89*6236dae4SAndroid Build Coastguard Worker   if(post) {
90*6236dae4SAndroid Build Coastguard Worker     post->name = name;
91*6236dae4SAndroid Build Coastguard Worker     post->namelength = (long)namelength;
92*6236dae4SAndroid Build Coastguard Worker     post->contents = value;
93*6236dae4SAndroid Build Coastguard Worker     post->contentlen = contentslength;
94*6236dae4SAndroid Build Coastguard Worker     post->buffer = buffer;
95*6236dae4SAndroid Build Coastguard Worker     post->bufferlength = (long)bufferlength;
96*6236dae4SAndroid Build Coastguard Worker     post->contenttype = contenttype;
97*6236dae4SAndroid Build Coastguard Worker     post->contentheader = contentHeader;
98*6236dae4SAndroid Build Coastguard Worker     post->showfilename = showfilename;
99*6236dae4SAndroid Build Coastguard Worker     post->userp = userp;
100*6236dae4SAndroid Build Coastguard Worker     post->flags = flags | CURL_HTTPPOST_LARGE;
101*6236dae4SAndroid Build Coastguard Worker   }
102*6236dae4SAndroid Build Coastguard Worker   else
103*6236dae4SAndroid Build Coastguard Worker     return NULL;
104*6236dae4SAndroid Build Coastguard Worker 
105*6236dae4SAndroid Build Coastguard Worker   if(parent_post) {
106*6236dae4SAndroid Build Coastguard Worker     /* now, point our 'more' to the original 'more' */
107*6236dae4SAndroid Build Coastguard Worker     post->more = parent_post->more;
108*6236dae4SAndroid Build Coastguard Worker 
109*6236dae4SAndroid Build Coastguard Worker     /* then move the original 'more' to point to ourselves */
110*6236dae4SAndroid Build Coastguard Worker     parent_post->more = post;
111*6236dae4SAndroid Build Coastguard Worker   }
112*6236dae4SAndroid Build Coastguard Worker   else {
113*6236dae4SAndroid Build Coastguard Worker     /* make the previous point to this */
114*6236dae4SAndroid Build Coastguard Worker     if(*last_post)
115*6236dae4SAndroid Build Coastguard Worker       (*last_post)->next = post;
116*6236dae4SAndroid Build Coastguard Worker     else
117*6236dae4SAndroid Build Coastguard Worker       (*httppost) = post;
118*6236dae4SAndroid Build Coastguard Worker 
119*6236dae4SAndroid Build Coastguard Worker     (*last_post) = post;
120*6236dae4SAndroid Build Coastguard Worker   }
121*6236dae4SAndroid Build Coastguard Worker   return post;
122*6236dae4SAndroid Build Coastguard Worker }
123*6236dae4SAndroid Build Coastguard Worker 
124*6236dae4SAndroid Build Coastguard Worker /***************************************************************************
125*6236dae4SAndroid Build Coastguard Worker  *
126*6236dae4SAndroid Build Coastguard Worker  * AddFormInfo()
127*6236dae4SAndroid Build Coastguard Worker  *
128*6236dae4SAndroid Build Coastguard Worker  * Adds a FormInfo structure to the list presented by parent_form_info.
129*6236dae4SAndroid Build Coastguard Worker  *
130*6236dae4SAndroid Build Coastguard Worker  * Returns newly allocated FormInfo on success and NULL if malloc failed/
131*6236dae4SAndroid Build Coastguard Worker  * parent_form_info is NULL.
132*6236dae4SAndroid Build Coastguard Worker  *
133*6236dae4SAndroid Build Coastguard Worker  ***************************************************************************/
AddFormInfo(char * value,char * contenttype,struct FormInfo * parent_form_info)134*6236dae4SAndroid Build Coastguard Worker static struct FormInfo *AddFormInfo(char *value,
135*6236dae4SAndroid Build Coastguard Worker                                     char *contenttype,
136*6236dae4SAndroid Build Coastguard Worker                                     struct FormInfo *parent_form_info)
137*6236dae4SAndroid Build Coastguard Worker {
138*6236dae4SAndroid Build Coastguard Worker   struct FormInfo *form_info;
139*6236dae4SAndroid Build Coastguard Worker   form_info = calloc(1, sizeof(struct FormInfo));
140*6236dae4SAndroid Build Coastguard Worker   if(!form_info)
141*6236dae4SAndroid Build Coastguard Worker     return NULL;
142*6236dae4SAndroid Build Coastguard Worker   if(value)
143*6236dae4SAndroid Build Coastguard Worker     form_info->value = value;
144*6236dae4SAndroid Build Coastguard Worker   if(contenttype)
145*6236dae4SAndroid Build Coastguard Worker     form_info->contenttype = contenttype;
146*6236dae4SAndroid Build Coastguard Worker   form_info->flags = HTTPPOST_FILENAME;
147*6236dae4SAndroid Build Coastguard Worker 
148*6236dae4SAndroid Build Coastguard Worker   if(parent_form_info) {
149*6236dae4SAndroid Build Coastguard Worker     /* now, point our 'more' to the original 'more' */
150*6236dae4SAndroid Build Coastguard Worker     form_info->more = parent_form_info->more;
151*6236dae4SAndroid Build Coastguard Worker 
152*6236dae4SAndroid Build Coastguard Worker     /* then move the original 'more' to point to ourselves */
153*6236dae4SAndroid Build Coastguard Worker     parent_form_info->more = form_info;
154*6236dae4SAndroid Build Coastguard Worker   }
155*6236dae4SAndroid Build Coastguard Worker 
156*6236dae4SAndroid Build Coastguard Worker   return form_info;
157*6236dae4SAndroid Build Coastguard Worker }
158*6236dae4SAndroid Build Coastguard Worker 
159*6236dae4SAndroid Build Coastguard Worker /***************************************************************************
160*6236dae4SAndroid Build Coastguard Worker  *
161*6236dae4SAndroid Build Coastguard Worker  * FormAdd()
162*6236dae4SAndroid Build Coastguard Worker  *
163*6236dae4SAndroid Build Coastguard Worker  * Stores a formpost parameter and builds the appropriate linked list.
164*6236dae4SAndroid Build Coastguard Worker  *
165*6236dae4SAndroid Build Coastguard Worker  * Has two principal functionalities: using files and byte arrays as
166*6236dae4SAndroid Build Coastguard Worker  * post parts. Byte arrays are either copied or just the pointer is stored
167*6236dae4SAndroid Build Coastguard Worker  * (as the user requests) while for files only the filename and not the
168*6236dae4SAndroid Build Coastguard Worker  * content is stored.
169*6236dae4SAndroid Build Coastguard Worker  *
170*6236dae4SAndroid Build Coastguard Worker  * While you may have only one byte array for each name, multiple filenames
171*6236dae4SAndroid Build Coastguard Worker  * are allowed (and because of this feature CURLFORM_END is needed after
172*6236dae4SAndroid Build Coastguard Worker  * using CURLFORM_FILE).
173*6236dae4SAndroid Build Coastguard Worker  *
174*6236dae4SAndroid Build Coastguard Worker  * Examples:
175*6236dae4SAndroid Build Coastguard Worker  *
176*6236dae4SAndroid Build Coastguard Worker  * Simple name/value pair with copied contents:
177*6236dae4SAndroid Build Coastguard Worker  * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name",
178*6236dae4SAndroid Build Coastguard Worker  * CURLFORM_COPYCONTENTS, "value", CURLFORM_END);
179*6236dae4SAndroid Build Coastguard Worker  *
180*6236dae4SAndroid Build Coastguard Worker  * name/value pair where only the content pointer is remembered:
181*6236dae4SAndroid Build Coastguard Worker  * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name",
182*6236dae4SAndroid Build Coastguard Worker  * CURLFORM_PTRCONTENTS, ptr, CURLFORM_CONTENTSLENGTH, 10, CURLFORM_END);
183*6236dae4SAndroid Build Coastguard Worker  * (if CURLFORM_CONTENTSLENGTH is missing strlen () is used)
184*6236dae4SAndroid Build Coastguard Worker  *
185*6236dae4SAndroid Build Coastguard Worker  * storing a filename (CONTENTTYPE is optional!):
186*6236dae4SAndroid Build Coastguard Worker  * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name",
187*6236dae4SAndroid Build Coastguard Worker  * CURLFORM_FILE, "filename1", CURLFORM_CONTENTTYPE, "plain/text",
188*6236dae4SAndroid Build Coastguard Worker  * CURLFORM_END);
189*6236dae4SAndroid Build Coastguard Worker  *
190*6236dae4SAndroid Build Coastguard Worker  * storing multiple filenames:
191*6236dae4SAndroid Build Coastguard Worker  * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name",
192*6236dae4SAndroid Build Coastguard Worker  * CURLFORM_FILE, "filename1", CURLFORM_FILE, "filename2", CURLFORM_END);
193*6236dae4SAndroid Build Coastguard Worker  *
194*6236dae4SAndroid Build Coastguard Worker  * Returns:
195*6236dae4SAndroid Build Coastguard Worker  * CURL_FORMADD_OK             on success
196*6236dae4SAndroid Build Coastguard Worker  * CURL_FORMADD_MEMORY         if the FormInfo allocation fails
197*6236dae4SAndroid Build Coastguard Worker  * CURL_FORMADD_OPTION_TWICE   if one option is given twice for one Form
198*6236dae4SAndroid Build Coastguard Worker  * CURL_FORMADD_NULL           if a null pointer was given for a char
199*6236dae4SAndroid Build Coastguard Worker  * CURL_FORMADD_MEMORY         if the allocation of a FormInfo struct failed
200*6236dae4SAndroid Build Coastguard Worker  * CURL_FORMADD_UNKNOWN_OPTION if an unknown option was used
201*6236dae4SAndroid Build Coastguard Worker  * CURL_FORMADD_INCOMPLETE     if the some FormInfo is not complete (or error)
202*6236dae4SAndroid Build Coastguard Worker  * CURL_FORMADD_MEMORY         if an HttpPost struct cannot be allocated
203*6236dae4SAndroid Build Coastguard Worker  * CURL_FORMADD_MEMORY         if some allocation for string copying failed.
204*6236dae4SAndroid Build Coastguard Worker  * CURL_FORMADD_ILLEGAL_ARRAY  if an illegal option is used in an array
205*6236dae4SAndroid Build Coastguard Worker  *
206*6236dae4SAndroid Build Coastguard Worker  ***************************************************************************/
207*6236dae4SAndroid Build Coastguard Worker 
208*6236dae4SAndroid Build Coastguard Worker static
FormAdd(struct curl_httppost ** httppost,struct curl_httppost ** last_post,va_list params)209*6236dae4SAndroid Build Coastguard Worker CURLFORMcode FormAdd(struct curl_httppost **httppost,
210*6236dae4SAndroid Build Coastguard Worker                      struct curl_httppost **last_post,
211*6236dae4SAndroid Build Coastguard Worker                      va_list params)
212*6236dae4SAndroid Build Coastguard Worker {
213*6236dae4SAndroid Build Coastguard Worker   struct FormInfo *first_form, *current_form, *form = NULL;
214*6236dae4SAndroid Build Coastguard Worker   CURLFORMcode return_value = CURL_FORMADD_OK;
215*6236dae4SAndroid Build Coastguard Worker   const char *prevtype = NULL;
216*6236dae4SAndroid Build Coastguard Worker   struct curl_httppost *post = NULL;
217*6236dae4SAndroid Build Coastguard Worker   CURLformoption option;
218*6236dae4SAndroid Build Coastguard Worker   struct curl_forms *forms = NULL;
219*6236dae4SAndroid Build Coastguard Worker   char *array_value = NULL; /* value read from an array */
220*6236dae4SAndroid Build Coastguard Worker 
221*6236dae4SAndroid Build Coastguard Worker   /* This is a state variable, that if TRUE means that we are parsing an
222*6236dae4SAndroid Build Coastguard Worker      array that we got passed to us. If FALSE we are parsing the input
223*6236dae4SAndroid Build Coastguard Worker      va_list arguments. */
224*6236dae4SAndroid Build Coastguard Worker   bool array_state = FALSE;
225*6236dae4SAndroid Build Coastguard Worker 
226*6236dae4SAndroid Build Coastguard Worker   /*
227*6236dae4SAndroid Build Coastguard Worker    * We need to allocate the first struct to fill in.
228*6236dae4SAndroid Build Coastguard Worker    */
229*6236dae4SAndroid Build Coastguard Worker   first_form = calloc(1, sizeof(struct FormInfo));
230*6236dae4SAndroid Build Coastguard Worker   if(!first_form)
231*6236dae4SAndroid Build Coastguard Worker     return CURL_FORMADD_MEMORY;
232*6236dae4SAndroid Build Coastguard Worker 
233*6236dae4SAndroid Build Coastguard Worker   current_form = first_form;
234*6236dae4SAndroid Build Coastguard Worker 
235*6236dae4SAndroid Build Coastguard Worker   /*
236*6236dae4SAndroid Build Coastguard Worker    * Loop through all the options set. Break if we have an error to report.
237*6236dae4SAndroid Build Coastguard Worker    */
238*6236dae4SAndroid Build Coastguard Worker   while(return_value == CURL_FORMADD_OK) {
239*6236dae4SAndroid Build Coastguard Worker 
240*6236dae4SAndroid Build Coastguard Worker     /* first see if we have more parts of the array param */
241*6236dae4SAndroid Build Coastguard Worker     if(array_state && forms) {
242*6236dae4SAndroid Build Coastguard Worker       /* get the upcoming option from the given array */
243*6236dae4SAndroid Build Coastguard Worker       option = forms->option;
244*6236dae4SAndroid Build Coastguard Worker       array_value = (char *)forms->value;
245*6236dae4SAndroid Build Coastguard Worker 
246*6236dae4SAndroid Build Coastguard Worker       forms++; /* advance this to next entry */
247*6236dae4SAndroid Build Coastguard Worker       if(CURLFORM_END == option) {
248*6236dae4SAndroid Build Coastguard Worker         /* end of array state */
249*6236dae4SAndroid Build Coastguard Worker         array_state = FALSE;
250*6236dae4SAndroid Build Coastguard Worker         continue;
251*6236dae4SAndroid Build Coastguard Worker       }
252*6236dae4SAndroid Build Coastguard Worker     }
253*6236dae4SAndroid Build Coastguard Worker     else {
254*6236dae4SAndroid Build Coastguard Worker       /* This is not array-state, get next option. This gets an 'int' with
255*6236dae4SAndroid Build Coastguard Worker          va_arg() because CURLformoption might be a smaller type than int and
256*6236dae4SAndroid Build Coastguard Worker          might cause compiler warnings and wrong behavior. */
257*6236dae4SAndroid Build Coastguard Worker       option = (CURLformoption)va_arg(params, int);
258*6236dae4SAndroid Build Coastguard Worker       if(CURLFORM_END == option)
259*6236dae4SAndroid Build Coastguard Worker         break;
260*6236dae4SAndroid Build Coastguard Worker     }
261*6236dae4SAndroid Build Coastguard Worker 
262*6236dae4SAndroid Build Coastguard Worker     switch(option) {
263*6236dae4SAndroid Build Coastguard Worker     case CURLFORM_ARRAY:
264*6236dae4SAndroid Build Coastguard Worker       if(array_state)
265*6236dae4SAndroid Build Coastguard Worker         /* we do not support an array from within an array */
266*6236dae4SAndroid Build Coastguard Worker         return_value = CURL_FORMADD_ILLEGAL_ARRAY;
267*6236dae4SAndroid Build Coastguard Worker       else {
268*6236dae4SAndroid Build Coastguard Worker         forms = va_arg(params, struct curl_forms *);
269*6236dae4SAndroid Build Coastguard Worker         if(forms)
270*6236dae4SAndroid Build Coastguard Worker           array_state = TRUE;
271*6236dae4SAndroid Build Coastguard Worker         else
272*6236dae4SAndroid Build Coastguard Worker           return_value = CURL_FORMADD_NULL;
273*6236dae4SAndroid Build Coastguard Worker       }
274*6236dae4SAndroid Build Coastguard Worker       break;
275*6236dae4SAndroid Build Coastguard Worker 
276*6236dae4SAndroid Build Coastguard Worker       /*
277*6236dae4SAndroid Build Coastguard Worker        * Set the Name property.
278*6236dae4SAndroid Build Coastguard Worker        */
279*6236dae4SAndroid Build Coastguard Worker     case CURLFORM_PTRNAME:
280*6236dae4SAndroid Build Coastguard Worker       current_form->flags |= HTTPPOST_PTRNAME; /* fall through */
281*6236dae4SAndroid Build Coastguard Worker 
282*6236dae4SAndroid Build Coastguard Worker       FALLTHROUGH();
283*6236dae4SAndroid Build Coastguard Worker     case CURLFORM_COPYNAME:
284*6236dae4SAndroid Build Coastguard Worker       if(current_form->name)
285*6236dae4SAndroid Build Coastguard Worker         return_value = CURL_FORMADD_OPTION_TWICE;
286*6236dae4SAndroid Build Coastguard Worker       else {
287*6236dae4SAndroid Build Coastguard Worker         char *name = array_state ?
288*6236dae4SAndroid Build Coastguard Worker           array_value : va_arg(params, char *);
289*6236dae4SAndroid Build Coastguard Worker         if(name)
290*6236dae4SAndroid Build Coastguard Worker           current_form->name = name; /* store for the moment */
291*6236dae4SAndroid Build Coastguard Worker         else
292*6236dae4SAndroid Build Coastguard Worker           return_value = CURL_FORMADD_NULL;
293*6236dae4SAndroid Build Coastguard Worker       }
294*6236dae4SAndroid Build Coastguard Worker       break;
295*6236dae4SAndroid Build Coastguard Worker     case CURLFORM_NAMELENGTH:
296*6236dae4SAndroid Build Coastguard Worker       if(current_form->namelength)
297*6236dae4SAndroid Build Coastguard Worker         return_value = CURL_FORMADD_OPTION_TWICE;
298*6236dae4SAndroid Build Coastguard Worker       else
299*6236dae4SAndroid Build Coastguard Worker         current_form->namelength =
300*6236dae4SAndroid Build Coastguard Worker           array_state ? (size_t)array_value : (size_t)va_arg(params, long);
301*6236dae4SAndroid Build Coastguard Worker       break;
302*6236dae4SAndroid Build Coastguard Worker 
303*6236dae4SAndroid Build Coastguard Worker       /*
304*6236dae4SAndroid Build Coastguard Worker        * Set the contents property.
305*6236dae4SAndroid Build Coastguard Worker        */
306*6236dae4SAndroid Build Coastguard Worker     case CURLFORM_PTRCONTENTS:
307*6236dae4SAndroid Build Coastguard Worker       current_form->flags |= HTTPPOST_PTRCONTENTS;
308*6236dae4SAndroid Build Coastguard Worker       FALLTHROUGH();
309*6236dae4SAndroid Build Coastguard Worker     case CURLFORM_COPYCONTENTS:
310*6236dae4SAndroid Build Coastguard Worker       if(current_form->value)
311*6236dae4SAndroid Build Coastguard Worker         return_value = CURL_FORMADD_OPTION_TWICE;
312*6236dae4SAndroid Build Coastguard Worker       else {
313*6236dae4SAndroid Build Coastguard Worker         char *value =
314*6236dae4SAndroid Build Coastguard Worker           array_state ? array_value : va_arg(params, char *);
315*6236dae4SAndroid Build Coastguard Worker         if(value)
316*6236dae4SAndroid Build Coastguard Worker           current_form->value = value; /* store for the moment */
317*6236dae4SAndroid Build Coastguard Worker         else
318*6236dae4SAndroid Build Coastguard Worker           return_value = CURL_FORMADD_NULL;
319*6236dae4SAndroid Build Coastguard Worker       }
320*6236dae4SAndroid Build Coastguard Worker       break;
321*6236dae4SAndroid Build Coastguard Worker     case CURLFORM_CONTENTSLENGTH:
322*6236dae4SAndroid Build Coastguard Worker       current_form->contentslength =
323*6236dae4SAndroid Build Coastguard Worker         array_state ? (size_t)array_value : (size_t)va_arg(params, long);
324*6236dae4SAndroid Build Coastguard Worker       break;
325*6236dae4SAndroid Build Coastguard Worker 
326*6236dae4SAndroid Build Coastguard Worker     case CURLFORM_CONTENTLEN:
327*6236dae4SAndroid Build Coastguard Worker       current_form->flags |= CURL_HTTPPOST_LARGE;
328*6236dae4SAndroid Build Coastguard Worker       current_form->contentslength =
329*6236dae4SAndroid Build Coastguard Worker         array_state ? (curl_off_t)(size_t)array_value :
330*6236dae4SAndroid Build Coastguard Worker         va_arg(params, curl_off_t);
331*6236dae4SAndroid Build Coastguard Worker       break;
332*6236dae4SAndroid Build Coastguard Worker 
333*6236dae4SAndroid Build Coastguard Worker       /* Get contents from a given filename */
334*6236dae4SAndroid Build Coastguard Worker     case CURLFORM_FILECONTENT:
335*6236dae4SAndroid Build Coastguard Worker       if(current_form->flags & (HTTPPOST_PTRCONTENTS|HTTPPOST_READFILE))
336*6236dae4SAndroid Build Coastguard Worker         return_value = CURL_FORMADD_OPTION_TWICE;
337*6236dae4SAndroid Build Coastguard Worker       else {
338*6236dae4SAndroid Build Coastguard Worker         const char *filename = array_state ?
339*6236dae4SAndroid Build Coastguard Worker           array_value : va_arg(params, char *);
340*6236dae4SAndroid Build Coastguard Worker         if(filename) {
341*6236dae4SAndroid Build Coastguard Worker           current_form->value = strdup(filename);
342*6236dae4SAndroid Build Coastguard Worker           if(!current_form->value)
343*6236dae4SAndroid Build Coastguard Worker             return_value = CURL_FORMADD_MEMORY;
344*6236dae4SAndroid Build Coastguard Worker           else {
345*6236dae4SAndroid Build Coastguard Worker             current_form->flags |= HTTPPOST_READFILE;
346*6236dae4SAndroid Build Coastguard Worker             current_form->value_alloc = TRUE;
347*6236dae4SAndroid Build Coastguard Worker           }
348*6236dae4SAndroid Build Coastguard Worker         }
349*6236dae4SAndroid Build Coastguard Worker         else
350*6236dae4SAndroid Build Coastguard Worker           return_value = CURL_FORMADD_NULL;
351*6236dae4SAndroid Build Coastguard Worker       }
352*6236dae4SAndroid Build Coastguard Worker       break;
353*6236dae4SAndroid Build Coastguard Worker 
354*6236dae4SAndroid Build Coastguard Worker       /* We upload a file */
355*6236dae4SAndroid Build Coastguard Worker     case CURLFORM_FILE:
356*6236dae4SAndroid Build Coastguard Worker       {
357*6236dae4SAndroid Build Coastguard Worker         const char *filename = array_state ? array_value :
358*6236dae4SAndroid Build Coastguard Worker           va_arg(params, char *);
359*6236dae4SAndroid Build Coastguard Worker 
360*6236dae4SAndroid Build Coastguard Worker         if(current_form->value) {
361*6236dae4SAndroid Build Coastguard Worker           if(current_form->flags & HTTPPOST_FILENAME) {
362*6236dae4SAndroid Build Coastguard Worker             if(filename) {
363*6236dae4SAndroid Build Coastguard Worker               char *fname = strdup(filename);
364*6236dae4SAndroid Build Coastguard Worker               if(!fname)
365*6236dae4SAndroid Build Coastguard Worker                 return_value = CURL_FORMADD_MEMORY;
366*6236dae4SAndroid Build Coastguard Worker               else {
367*6236dae4SAndroid Build Coastguard Worker                 form = AddFormInfo(fname, NULL, current_form);
368*6236dae4SAndroid Build Coastguard Worker                 if(!form) {
369*6236dae4SAndroid Build Coastguard Worker                   free(fname);
370*6236dae4SAndroid Build Coastguard Worker                   return_value = CURL_FORMADD_MEMORY;
371*6236dae4SAndroid Build Coastguard Worker                 }
372*6236dae4SAndroid Build Coastguard Worker                 else {
373*6236dae4SAndroid Build Coastguard Worker                   form->value_alloc = TRUE;
374*6236dae4SAndroid Build Coastguard Worker                   current_form = form;
375*6236dae4SAndroid Build Coastguard Worker                   form = NULL;
376*6236dae4SAndroid Build Coastguard Worker                 }
377*6236dae4SAndroid Build Coastguard Worker               }
378*6236dae4SAndroid Build Coastguard Worker             }
379*6236dae4SAndroid Build Coastguard Worker             else
380*6236dae4SAndroid Build Coastguard Worker               return_value = CURL_FORMADD_NULL;
381*6236dae4SAndroid Build Coastguard Worker           }
382*6236dae4SAndroid Build Coastguard Worker           else
383*6236dae4SAndroid Build Coastguard Worker             return_value = CURL_FORMADD_OPTION_TWICE;
384*6236dae4SAndroid Build Coastguard Worker         }
385*6236dae4SAndroid Build Coastguard Worker         else {
386*6236dae4SAndroid Build Coastguard Worker           if(filename) {
387*6236dae4SAndroid Build Coastguard Worker             current_form->value = strdup(filename);
388*6236dae4SAndroid Build Coastguard Worker             if(!current_form->value)
389*6236dae4SAndroid Build Coastguard Worker               return_value = CURL_FORMADD_MEMORY;
390*6236dae4SAndroid Build Coastguard Worker             else {
391*6236dae4SAndroid Build Coastguard Worker               current_form->flags |= HTTPPOST_FILENAME;
392*6236dae4SAndroid Build Coastguard Worker               current_form->value_alloc = TRUE;
393*6236dae4SAndroid Build Coastguard Worker             }
394*6236dae4SAndroid Build Coastguard Worker           }
395*6236dae4SAndroid Build Coastguard Worker           else
396*6236dae4SAndroid Build Coastguard Worker             return_value = CURL_FORMADD_NULL;
397*6236dae4SAndroid Build Coastguard Worker         }
398*6236dae4SAndroid Build Coastguard Worker         break;
399*6236dae4SAndroid Build Coastguard Worker       }
400*6236dae4SAndroid Build Coastguard Worker 
401*6236dae4SAndroid Build Coastguard Worker     case CURLFORM_BUFFERPTR:
402*6236dae4SAndroid Build Coastguard Worker       current_form->flags |= HTTPPOST_PTRBUFFER|HTTPPOST_BUFFER;
403*6236dae4SAndroid Build Coastguard Worker       if(current_form->buffer)
404*6236dae4SAndroid Build Coastguard Worker         return_value = CURL_FORMADD_OPTION_TWICE;
405*6236dae4SAndroid Build Coastguard Worker       else {
406*6236dae4SAndroid Build Coastguard Worker         char *buffer =
407*6236dae4SAndroid Build Coastguard Worker           array_state ? array_value : va_arg(params, char *);
408*6236dae4SAndroid Build Coastguard Worker         if(buffer) {
409*6236dae4SAndroid Build Coastguard Worker           current_form->buffer = buffer; /* store for the moment */
410*6236dae4SAndroid Build Coastguard Worker           current_form->value = buffer; /* make it non-NULL to be accepted
411*6236dae4SAndroid Build Coastguard Worker                                            as fine */
412*6236dae4SAndroid Build Coastguard Worker         }
413*6236dae4SAndroid Build Coastguard Worker         else
414*6236dae4SAndroid Build Coastguard Worker           return_value = CURL_FORMADD_NULL;
415*6236dae4SAndroid Build Coastguard Worker       }
416*6236dae4SAndroid Build Coastguard Worker       break;
417*6236dae4SAndroid Build Coastguard Worker 
418*6236dae4SAndroid Build Coastguard Worker     case CURLFORM_BUFFERLENGTH:
419*6236dae4SAndroid Build Coastguard Worker       if(current_form->bufferlength)
420*6236dae4SAndroid Build Coastguard Worker         return_value = CURL_FORMADD_OPTION_TWICE;
421*6236dae4SAndroid Build Coastguard Worker       else
422*6236dae4SAndroid Build Coastguard Worker         current_form->bufferlength =
423*6236dae4SAndroid Build Coastguard Worker           array_state ? (size_t)array_value : (size_t)va_arg(params, long);
424*6236dae4SAndroid Build Coastguard Worker       break;
425*6236dae4SAndroid Build Coastguard Worker 
426*6236dae4SAndroid Build Coastguard Worker     case CURLFORM_STREAM:
427*6236dae4SAndroid Build Coastguard Worker       current_form->flags |= HTTPPOST_CALLBACK;
428*6236dae4SAndroid Build Coastguard Worker       if(current_form->userp)
429*6236dae4SAndroid Build Coastguard Worker         return_value = CURL_FORMADD_OPTION_TWICE;
430*6236dae4SAndroid Build Coastguard Worker       else {
431*6236dae4SAndroid Build Coastguard Worker         char *userp =
432*6236dae4SAndroid Build Coastguard Worker           array_state ? array_value : va_arg(params, char *);
433*6236dae4SAndroid Build Coastguard Worker         if(userp) {
434*6236dae4SAndroid Build Coastguard Worker           current_form->userp = userp;
435*6236dae4SAndroid Build Coastguard Worker           current_form->value = userp; /* this is not strictly true but we
436*6236dae4SAndroid Build Coastguard Worker                                           derive a value from this later on
437*6236dae4SAndroid Build Coastguard Worker                                           and we need this non-NULL to be
438*6236dae4SAndroid Build Coastguard Worker                                           accepted as a fine form part */
439*6236dae4SAndroid Build Coastguard Worker         }
440*6236dae4SAndroid Build Coastguard Worker         else
441*6236dae4SAndroid Build Coastguard Worker           return_value = CURL_FORMADD_NULL;
442*6236dae4SAndroid Build Coastguard Worker       }
443*6236dae4SAndroid Build Coastguard Worker       break;
444*6236dae4SAndroid Build Coastguard Worker 
445*6236dae4SAndroid Build Coastguard Worker     case CURLFORM_CONTENTTYPE:
446*6236dae4SAndroid Build Coastguard Worker       {
447*6236dae4SAndroid Build Coastguard Worker         const char *contenttype =
448*6236dae4SAndroid Build Coastguard Worker           array_state ? array_value : va_arg(params, char *);
449*6236dae4SAndroid Build Coastguard Worker         if(current_form->contenttype) {
450*6236dae4SAndroid Build Coastguard Worker           if(current_form->flags & HTTPPOST_FILENAME) {
451*6236dae4SAndroid Build Coastguard Worker             if(contenttype) {
452*6236dae4SAndroid Build Coastguard Worker               char *type = strdup(contenttype);
453*6236dae4SAndroid Build Coastguard Worker               if(!type)
454*6236dae4SAndroid Build Coastguard Worker                 return_value = CURL_FORMADD_MEMORY;
455*6236dae4SAndroid Build Coastguard Worker               else {
456*6236dae4SAndroid Build Coastguard Worker                 form = AddFormInfo(NULL, type, current_form);
457*6236dae4SAndroid Build Coastguard Worker                 if(!form) {
458*6236dae4SAndroid Build Coastguard Worker                   free(type);
459*6236dae4SAndroid Build Coastguard Worker                   return_value = CURL_FORMADD_MEMORY;
460*6236dae4SAndroid Build Coastguard Worker                 }
461*6236dae4SAndroid Build Coastguard Worker                 else {
462*6236dae4SAndroid Build Coastguard Worker                   form->contenttype_alloc = TRUE;
463*6236dae4SAndroid Build Coastguard Worker                   current_form = form;
464*6236dae4SAndroid Build Coastguard Worker                   form = NULL;
465*6236dae4SAndroid Build Coastguard Worker                 }
466*6236dae4SAndroid Build Coastguard Worker               }
467*6236dae4SAndroid Build Coastguard Worker             }
468*6236dae4SAndroid Build Coastguard Worker             else
469*6236dae4SAndroid Build Coastguard Worker               return_value = CURL_FORMADD_NULL;
470*6236dae4SAndroid Build Coastguard Worker           }
471*6236dae4SAndroid Build Coastguard Worker           else
472*6236dae4SAndroid Build Coastguard Worker             return_value = CURL_FORMADD_OPTION_TWICE;
473*6236dae4SAndroid Build Coastguard Worker         }
474*6236dae4SAndroid Build Coastguard Worker         else {
475*6236dae4SAndroid Build Coastguard Worker           if(contenttype) {
476*6236dae4SAndroid Build Coastguard Worker             current_form->contenttype = strdup(contenttype);
477*6236dae4SAndroid Build Coastguard Worker             if(!current_form->contenttype)
478*6236dae4SAndroid Build Coastguard Worker               return_value = CURL_FORMADD_MEMORY;
479*6236dae4SAndroid Build Coastguard Worker             else
480*6236dae4SAndroid Build Coastguard Worker               current_form->contenttype_alloc = TRUE;
481*6236dae4SAndroid Build Coastguard Worker           }
482*6236dae4SAndroid Build Coastguard Worker           else
483*6236dae4SAndroid Build Coastguard Worker             return_value = CURL_FORMADD_NULL;
484*6236dae4SAndroid Build Coastguard Worker         }
485*6236dae4SAndroid Build Coastguard Worker         break;
486*6236dae4SAndroid Build Coastguard Worker       }
487*6236dae4SAndroid Build Coastguard Worker     case CURLFORM_CONTENTHEADER:
488*6236dae4SAndroid Build Coastguard Worker       {
489*6236dae4SAndroid Build Coastguard Worker         /* this "cast increases required alignment of target type" but
490*6236dae4SAndroid Build Coastguard Worker            we consider it OK anyway */
491*6236dae4SAndroid Build Coastguard Worker         struct curl_slist *list = array_state ?
492*6236dae4SAndroid Build Coastguard Worker           (struct curl_slist *)(void *)array_value :
493*6236dae4SAndroid Build Coastguard Worker           va_arg(params, struct curl_slist *);
494*6236dae4SAndroid Build Coastguard Worker 
495*6236dae4SAndroid Build Coastguard Worker         if(current_form->contentheader)
496*6236dae4SAndroid Build Coastguard Worker           return_value = CURL_FORMADD_OPTION_TWICE;
497*6236dae4SAndroid Build Coastguard Worker         else
498*6236dae4SAndroid Build Coastguard Worker           current_form->contentheader = list;
499*6236dae4SAndroid Build Coastguard Worker 
500*6236dae4SAndroid Build Coastguard Worker         break;
501*6236dae4SAndroid Build Coastguard Worker       }
502*6236dae4SAndroid Build Coastguard Worker     case CURLFORM_FILENAME:
503*6236dae4SAndroid Build Coastguard Worker     case CURLFORM_BUFFER:
504*6236dae4SAndroid Build Coastguard Worker       {
505*6236dae4SAndroid Build Coastguard Worker         const char *filename = array_state ? array_value :
506*6236dae4SAndroid Build Coastguard Worker           va_arg(params, char *);
507*6236dae4SAndroid Build Coastguard Worker         if(current_form->showfilename)
508*6236dae4SAndroid Build Coastguard Worker           return_value = CURL_FORMADD_OPTION_TWICE;
509*6236dae4SAndroid Build Coastguard Worker         else {
510*6236dae4SAndroid Build Coastguard Worker           current_form->showfilename = strdup(filename);
511*6236dae4SAndroid Build Coastguard Worker           if(!current_form->showfilename)
512*6236dae4SAndroid Build Coastguard Worker             return_value = CURL_FORMADD_MEMORY;
513*6236dae4SAndroid Build Coastguard Worker           else
514*6236dae4SAndroid Build Coastguard Worker             current_form->showfilename_alloc = TRUE;
515*6236dae4SAndroid Build Coastguard Worker         }
516*6236dae4SAndroid Build Coastguard Worker         break;
517*6236dae4SAndroid Build Coastguard Worker       }
518*6236dae4SAndroid Build Coastguard Worker     default:
519*6236dae4SAndroid Build Coastguard Worker       return_value = CURL_FORMADD_UNKNOWN_OPTION;
520*6236dae4SAndroid Build Coastguard Worker       break;
521*6236dae4SAndroid Build Coastguard Worker     }
522*6236dae4SAndroid Build Coastguard Worker   }
523*6236dae4SAndroid Build Coastguard Worker 
524*6236dae4SAndroid Build Coastguard Worker   if(CURL_FORMADD_OK != return_value) {
525*6236dae4SAndroid Build Coastguard Worker     /* On error, free allocated fields for all nodes of the FormInfo linked
526*6236dae4SAndroid Build Coastguard Worker        list without deallocating nodes. List nodes are deallocated later on */
527*6236dae4SAndroid Build Coastguard Worker     struct FormInfo *ptr;
528*6236dae4SAndroid Build Coastguard Worker     for(ptr = first_form; ptr != NULL; ptr = ptr->more) {
529*6236dae4SAndroid Build Coastguard Worker       if(ptr->name_alloc) {
530*6236dae4SAndroid Build Coastguard Worker         Curl_safefree(ptr->name);
531*6236dae4SAndroid Build Coastguard Worker         ptr->name_alloc = FALSE;
532*6236dae4SAndroid Build Coastguard Worker       }
533*6236dae4SAndroid Build Coastguard Worker       if(ptr->value_alloc) {
534*6236dae4SAndroid Build Coastguard Worker         Curl_safefree(ptr->value);
535*6236dae4SAndroid Build Coastguard Worker         ptr->value_alloc = FALSE;
536*6236dae4SAndroid Build Coastguard Worker       }
537*6236dae4SAndroid Build Coastguard Worker       if(ptr->contenttype_alloc) {
538*6236dae4SAndroid Build Coastguard Worker         Curl_safefree(ptr->contenttype);
539*6236dae4SAndroid Build Coastguard Worker         ptr->contenttype_alloc = FALSE;
540*6236dae4SAndroid Build Coastguard Worker       }
541*6236dae4SAndroid Build Coastguard Worker       if(ptr->showfilename_alloc) {
542*6236dae4SAndroid Build Coastguard Worker         Curl_safefree(ptr->showfilename);
543*6236dae4SAndroid Build Coastguard Worker         ptr->showfilename_alloc = FALSE;
544*6236dae4SAndroid Build Coastguard Worker       }
545*6236dae4SAndroid Build Coastguard Worker     }
546*6236dae4SAndroid Build Coastguard Worker   }
547*6236dae4SAndroid Build Coastguard Worker 
548*6236dae4SAndroid Build Coastguard Worker   if(CURL_FORMADD_OK == return_value) {
549*6236dae4SAndroid Build Coastguard Worker     /* go through the list, check for completeness and if everything is
550*6236dae4SAndroid Build Coastguard Worker      * alright add the HttpPost item otherwise set return_value accordingly */
551*6236dae4SAndroid Build Coastguard Worker 
552*6236dae4SAndroid Build Coastguard Worker     post = NULL;
553*6236dae4SAndroid Build Coastguard Worker     for(form = first_form;
554*6236dae4SAndroid Build Coastguard Worker         form != NULL;
555*6236dae4SAndroid Build Coastguard Worker         form = form->more) {
556*6236dae4SAndroid Build Coastguard Worker       if(((!form->name || !form->value) && !post) ||
557*6236dae4SAndroid Build Coastguard Worker          ( (form->contentslength) &&
558*6236dae4SAndroid Build Coastguard Worker            (form->flags & HTTPPOST_FILENAME) ) ||
559*6236dae4SAndroid Build Coastguard Worker          ( (form->flags & HTTPPOST_FILENAME) &&
560*6236dae4SAndroid Build Coastguard Worker            (form->flags & HTTPPOST_PTRCONTENTS) ) ||
561*6236dae4SAndroid Build Coastguard Worker 
562*6236dae4SAndroid Build Coastguard Worker          ( (!form->buffer) &&
563*6236dae4SAndroid Build Coastguard Worker            (form->flags & HTTPPOST_BUFFER) &&
564*6236dae4SAndroid Build Coastguard Worker            (form->flags & HTTPPOST_PTRBUFFER) ) ||
565*6236dae4SAndroid Build Coastguard Worker 
566*6236dae4SAndroid Build Coastguard Worker          ( (form->flags & HTTPPOST_READFILE) &&
567*6236dae4SAndroid Build Coastguard Worker            (form->flags & HTTPPOST_PTRCONTENTS) )
568*6236dae4SAndroid Build Coastguard Worker         ) {
569*6236dae4SAndroid Build Coastguard Worker         return_value = CURL_FORMADD_INCOMPLETE;
570*6236dae4SAndroid Build Coastguard Worker         break;
571*6236dae4SAndroid Build Coastguard Worker       }
572*6236dae4SAndroid Build Coastguard Worker       if(((form->flags & HTTPPOST_FILENAME) ||
573*6236dae4SAndroid Build Coastguard Worker           (form->flags & HTTPPOST_BUFFER)) &&
574*6236dae4SAndroid Build Coastguard Worker          !form->contenttype) {
575*6236dae4SAndroid Build Coastguard Worker         char *f = (form->flags & HTTPPOST_BUFFER) ?
576*6236dae4SAndroid Build Coastguard Worker           form->showfilename : form->value;
577*6236dae4SAndroid Build Coastguard Worker         char const *type;
578*6236dae4SAndroid Build Coastguard Worker         type = Curl_mime_contenttype(f);
579*6236dae4SAndroid Build Coastguard Worker         if(!type)
580*6236dae4SAndroid Build Coastguard Worker           type = prevtype;
581*6236dae4SAndroid Build Coastguard Worker         if(!type)
582*6236dae4SAndroid Build Coastguard Worker           type = FILE_CONTENTTYPE_DEFAULT;
583*6236dae4SAndroid Build Coastguard Worker 
584*6236dae4SAndroid Build Coastguard Worker         /* our contenttype is missing */
585*6236dae4SAndroid Build Coastguard Worker         form->contenttype = strdup(type);
586*6236dae4SAndroid Build Coastguard Worker         if(!form->contenttype) {
587*6236dae4SAndroid Build Coastguard Worker           return_value = CURL_FORMADD_MEMORY;
588*6236dae4SAndroid Build Coastguard Worker           break;
589*6236dae4SAndroid Build Coastguard Worker         }
590*6236dae4SAndroid Build Coastguard Worker         form->contenttype_alloc = TRUE;
591*6236dae4SAndroid Build Coastguard Worker       }
592*6236dae4SAndroid Build Coastguard Worker       if(form->name && form->namelength) {
593*6236dae4SAndroid Build Coastguard Worker         /* Name should not contain nul bytes. */
594*6236dae4SAndroid Build Coastguard Worker         size_t i;
595*6236dae4SAndroid Build Coastguard Worker         for(i = 0; i < form->namelength; i++)
596*6236dae4SAndroid Build Coastguard Worker           if(!form->name[i]) {
597*6236dae4SAndroid Build Coastguard Worker             return_value = CURL_FORMADD_NULL;
598*6236dae4SAndroid Build Coastguard Worker             break;
599*6236dae4SAndroid Build Coastguard Worker           }
600*6236dae4SAndroid Build Coastguard Worker         if(return_value != CURL_FORMADD_OK)
601*6236dae4SAndroid Build Coastguard Worker           break;
602*6236dae4SAndroid Build Coastguard Worker       }
603*6236dae4SAndroid Build Coastguard Worker       if(!(form->flags & HTTPPOST_PTRNAME) &&
604*6236dae4SAndroid Build Coastguard Worker          (form == first_form) ) {
605*6236dae4SAndroid Build Coastguard Worker         /* Note that there is small risk that form->name is NULL here if the
606*6236dae4SAndroid Build Coastguard Worker            app passed in a bad combo, so we better check for that first. */
607*6236dae4SAndroid Build Coastguard Worker         if(form->name) {
608*6236dae4SAndroid Build Coastguard Worker           /* copy name (without strdup; possibly not null-terminated) */
609*6236dae4SAndroid Build Coastguard Worker           form->name = Curl_memdup0(form->name, form->namelength ?
610*6236dae4SAndroid Build Coastguard Worker                                     form->namelength :
611*6236dae4SAndroid Build Coastguard Worker                                     strlen(form->name));
612*6236dae4SAndroid Build Coastguard Worker         }
613*6236dae4SAndroid Build Coastguard Worker         if(!form->name) {
614*6236dae4SAndroid Build Coastguard Worker           return_value = CURL_FORMADD_MEMORY;
615*6236dae4SAndroid Build Coastguard Worker           break;
616*6236dae4SAndroid Build Coastguard Worker         }
617*6236dae4SAndroid Build Coastguard Worker         form->name_alloc = TRUE;
618*6236dae4SAndroid Build Coastguard Worker       }
619*6236dae4SAndroid Build Coastguard Worker       if(!(form->flags & (HTTPPOST_FILENAME | HTTPPOST_READFILE |
620*6236dae4SAndroid Build Coastguard Worker                           HTTPPOST_PTRCONTENTS | HTTPPOST_PTRBUFFER |
621*6236dae4SAndroid Build Coastguard Worker                           HTTPPOST_CALLBACK)) && form->value) {
622*6236dae4SAndroid Build Coastguard Worker         /* copy value (without strdup; possibly contains null characters) */
623*6236dae4SAndroid Build Coastguard Worker         size_t clen  = (size_t) form->contentslength;
624*6236dae4SAndroid Build Coastguard Worker         if(!clen)
625*6236dae4SAndroid Build Coastguard Worker           clen = strlen(form->value) + 1;
626*6236dae4SAndroid Build Coastguard Worker 
627*6236dae4SAndroid Build Coastguard Worker         form->value = Curl_memdup(form->value, clen);
628*6236dae4SAndroid Build Coastguard Worker 
629*6236dae4SAndroid Build Coastguard Worker         if(!form->value) {
630*6236dae4SAndroid Build Coastguard Worker           return_value = CURL_FORMADD_MEMORY;
631*6236dae4SAndroid Build Coastguard Worker           break;
632*6236dae4SAndroid Build Coastguard Worker         }
633*6236dae4SAndroid Build Coastguard Worker         form->value_alloc = TRUE;
634*6236dae4SAndroid Build Coastguard Worker       }
635*6236dae4SAndroid Build Coastguard Worker       post = AddHttpPost(form->name, form->namelength,
636*6236dae4SAndroid Build Coastguard Worker                          form->value, form->contentslength,
637*6236dae4SAndroid Build Coastguard Worker                          form->buffer, form->bufferlength,
638*6236dae4SAndroid Build Coastguard Worker                          form->contenttype, form->flags,
639*6236dae4SAndroid Build Coastguard Worker                          form->contentheader, form->showfilename,
640*6236dae4SAndroid Build Coastguard Worker                          form->userp,
641*6236dae4SAndroid Build Coastguard Worker                          post, httppost,
642*6236dae4SAndroid Build Coastguard Worker                          last_post);
643*6236dae4SAndroid Build Coastguard Worker 
644*6236dae4SAndroid Build Coastguard Worker       if(!post) {
645*6236dae4SAndroid Build Coastguard Worker         return_value = CURL_FORMADD_MEMORY;
646*6236dae4SAndroid Build Coastguard Worker         break;
647*6236dae4SAndroid Build Coastguard Worker       }
648*6236dae4SAndroid Build Coastguard Worker 
649*6236dae4SAndroid Build Coastguard Worker       if(form->contenttype)
650*6236dae4SAndroid Build Coastguard Worker         prevtype = form->contenttype;
651*6236dae4SAndroid Build Coastguard Worker     }
652*6236dae4SAndroid Build Coastguard Worker     if(CURL_FORMADD_OK != return_value) {
653*6236dae4SAndroid Build Coastguard Worker       /* On error, free allocated fields for nodes of the FormInfo linked
654*6236dae4SAndroid Build Coastguard Worker          list which are not already owned by the httppost linked list
655*6236dae4SAndroid Build Coastguard Worker          without deallocating nodes. List nodes are deallocated later on */
656*6236dae4SAndroid Build Coastguard Worker       struct FormInfo *ptr;
657*6236dae4SAndroid Build Coastguard Worker       for(ptr = form; ptr != NULL; ptr = ptr->more) {
658*6236dae4SAndroid Build Coastguard Worker         if(ptr->name_alloc) {
659*6236dae4SAndroid Build Coastguard Worker           Curl_safefree(ptr->name);
660*6236dae4SAndroid Build Coastguard Worker           ptr->name_alloc = FALSE;
661*6236dae4SAndroid Build Coastguard Worker         }
662*6236dae4SAndroid Build Coastguard Worker         if(ptr->value_alloc) {
663*6236dae4SAndroid Build Coastguard Worker           Curl_safefree(ptr->value);
664*6236dae4SAndroid Build Coastguard Worker           ptr->value_alloc = FALSE;
665*6236dae4SAndroid Build Coastguard Worker         }
666*6236dae4SAndroid Build Coastguard Worker         if(ptr->contenttype_alloc) {
667*6236dae4SAndroid Build Coastguard Worker           Curl_safefree(ptr->contenttype);
668*6236dae4SAndroid Build Coastguard Worker           ptr->contenttype_alloc = FALSE;
669*6236dae4SAndroid Build Coastguard Worker         }
670*6236dae4SAndroid Build Coastguard Worker         if(ptr->showfilename_alloc) {
671*6236dae4SAndroid Build Coastguard Worker           Curl_safefree(ptr->showfilename);
672*6236dae4SAndroid Build Coastguard Worker           ptr->showfilename_alloc = FALSE;
673*6236dae4SAndroid Build Coastguard Worker         }
674*6236dae4SAndroid Build Coastguard Worker       }
675*6236dae4SAndroid Build Coastguard Worker     }
676*6236dae4SAndroid Build Coastguard Worker   }
677*6236dae4SAndroid Build Coastguard Worker 
678*6236dae4SAndroid Build Coastguard Worker   /* Always deallocate FormInfo linked list nodes without touching node
679*6236dae4SAndroid Build Coastguard Worker      fields given that these have either been deallocated or are owned
680*6236dae4SAndroid Build Coastguard Worker      now by the httppost linked list */
681*6236dae4SAndroid Build Coastguard Worker   while(first_form) {
682*6236dae4SAndroid Build Coastguard Worker     struct FormInfo *ptr = first_form->more;
683*6236dae4SAndroid Build Coastguard Worker     free(first_form);
684*6236dae4SAndroid Build Coastguard Worker     first_form = ptr;
685*6236dae4SAndroid Build Coastguard Worker   }
686*6236dae4SAndroid Build Coastguard Worker 
687*6236dae4SAndroid Build Coastguard Worker   return return_value;
688*6236dae4SAndroid Build Coastguard Worker }
689*6236dae4SAndroid Build Coastguard Worker 
690*6236dae4SAndroid Build Coastguard Worker /*
691*6236dae4SAndroid Build Coastguard Worker  * curl_formadd() is a public API to add a section to the multipart formpost.
692*6236dae4SAndroid Build Coastguard Worker  *
693*6236dae4SAndroid Build Coastguard Worker  * @unittest: 1308
694*6236dae4SAndroid Build Coastguard Worker  */
695*6236dae4SAndroid Build Coastguard Worker 
curl_formadd(struct curl_httppost ** httppost,struct curl_httppost ** last_post,...)696*6236dae4SAndroid Build Coastguard Worker CURLFORMcode curl_formadd(struct curl_httppost **httppost,
697*6236dae4SAndroid Build Coastguard Worker                           struct curl_httppost **last_post,
698*6236dae4SAndroid Build Coastguard Worker                           ...)
699*6236dae4SAndroid Build Coastguard Worker {
700*6236dae4SAndroid Build Coastguard Worker   va_list arg;
701*6236dae4SAndroid Build Coastguard Worker   CURLFORMcode result;
702*6236dae4SAndroid Build Coastguard Worker   va_start(arg, last_post);
703*6236dae4SAndroid Build Coastguard Worker   result = FormAdd(httppost, last_post, arg);
704*6236dae4SAndroid Build Coastguard Worker   va_end(arg);
705*6236dae4SAndroid Build Coastguard Worker   return result;
706*6236dae4SAndroid Build Coastguard Worker }
707*6236dae4SAndroid Build Coastguard Worker 
708*6236dae4SAndroid Build Coastguard Worker /*
709*6236dae4SAndroid Build Coastguard Worker  * curl_formget()
710*6236dae4SAndroid Build Coastguard Worker  * Serialize a curl_httppost struct.
711*6236dae4SAndroid Build Coastguard Worker  * Returns 0 on success.
712*6236dae4SAndroid Build Coastguard Worker  *
713*6236dae4SAndroid Build Coastguard Worker  * @unittest: 1308
714*6236dae4SAndroid Build Coastguard Worker  */
curl_formget(struct curl_httppost * form,void * arg,curl_formget_callback append)715*6236dae4SAndroid Build Coastguard Worker int curl_formget(struct curl_httppost *form, void *arg,
716*6236dae4SAndroid Build Coastguard Worker                  curl_formget_callback append)
717*6236dae4SAndroid Build Coastguard Worker {
718*6236dae4SAndroid Build Coastguard Worker   CURLcode result;
719*6236dae4SAndroid Build Coastguard Worker   curl_mimepart toppart;
720*6236dae4SAndroid Build Coastguard Worker 
721*6236dae4SAndroid Build Coastguard Worker   Curl_mime_initpart(&toppart); /* default form is empty */
722*6236dae4SAndroid Build Coastguard Worker   result = Curl_getformdata(NULL, &toppart, form, NULL);
723*6236dae4SAndroid Build Coastguard Worker   if(!result)
724*6236dae4SAndroid Build Coastguard Worker     result = Curl_mime_prepare_headers(NULL, &toppart, "multipart/form-data",
725*6236dae4SAndroid Build Coastguard Worker                                        NULL, MIMESTRATEGY_FORM);
726*6236dae4SAndroid Build Coastguard Worker 
727*6236dae4SAndroid Build Coastguard Worker   while(!result) {
728*6236dae4SAndroid Build Coastguard Worker     char buffer[8192];
729*6236dae4SAndroid Build Coastguard Worker     size_t nread = Curl_mime_read(buffer, 1, sizeof(buffer), &toppart);
730*6236dae4SAndroid Build Coastguard Worker 
731*6236dae4SAndroid Build Coastguard Worker     if(!nread)
732*6236dae4SAndroid Build Coastguard Worker       break;
733*6236dae4SAndroid Build Coastguard Worker 
734*6236dae4SAndroid Build Coastguard Worker     if(nread > sizeof(buffer) || append(arg, buffer, nread) != nread) {
735*6236dae4SAndroid Build Coastguard Worker       result = CURLE_READ_ERROR;
736*6236dae4SAndroid Build Coastguard Worker       if(nread == CURL_READFUNC_ABORT)
737*6236dae4SAndroid Build Coastguard Worker         result = CURLE_ABORTED_BY_CALLBACK;
738*6236dae4SAndroid Build Coastguard Worker     }
739*6236dae4SAndroid Build Coastguard Worker   }
740*6236dae4SAndroid Build Coastguard Worker 
741*6236dae4SAndroid Build Coastguard Worker   Curl_mime_cleanpart(&toppart);
742*6236dae4SAndroid Build Coastguard Worker   return (int) result;
743*6236dae4SAndroid Build Coastguard Worker }
744*6236dae4SAndroid Build Coastguard Worker 
745*6236dae4SAndroid Build Coastguard Worker /*
746*6236dae4SAndroid Build Coastguard Worker  * curl_formfree() is an external function to free up a whole form post
747*6236dae4SAndroid Build Coastguard Worker  * chain
748*6236dae4SAndroid Build Coastguard Worker  */
curl_formfree(struct curl_httppost * form)749*6236dae4SAndroid Build Coastguard Worker void curl_formfree(struct curl_httppost *form)
750*6236dae4SAndroid Build Coastguard Worker {
751*6236dae4SAndroid Build Coastguard Worker   struct curl_httppost *next;
752*6236dae4SAndroid Build Coastguard Worker 
753*6236dae4SAndroid Build Coastguard Worker   if(!form)
754*6236dae4SAndroid Build Coastguard Worker     /* no form to free, just get out of this */
755*6236dae4SAndroid Build Coastguard Worker     return;
756*6236dae4SAndroid Build Coastguard Worker 
757*6236dae4SAndroid Build Coastguard Worker   do {
758*6236dae4SAndroid Build Coastguard Worker     next = form->next;  /* the following form line */
759*6236dae4SAndroid Build Coastguard Worker 
760*6236dae4SAndroid Build Coastguard Worker     /* recurse to sub-contents */
761*6236dae4SAndroid Build Coastguard Worker     curl_formfree(form->more);
762*6236dae4SAndroid Build Coastguard Worker 
763*6236dae4SAndroid Build Coastguard Worker     if(!(form->flags & HTTPPOST_PTRNAME))
764*6236dae4SAndroid Build Coastguard Worker       free(form->name); /* free the name */
765*6236dae4SAndroid Build Coastguard Worker     if(!(form->flags &
766*6236dae4SAndroid Build Coastguard Worker          (HTTPPOST_PTRCONTENTS|HTTPPOST_BUFFER|HTTPPOST_CALLBACK))
767*6236dae4SAndroid Build Coastguard Worker       )
768*6236dae4SAndroid Build Coastguard Worker       free(form->contents); /* free the contents */
769*6236dae4SAndroid Build Coastguard Worker     free(form->contenttype); /* free the content type */
770*6236dae4SAndroid Build Coastguard Worker     free(form->showfilename); /* free the faked filename */
771*6236dae4SAndroid Build Coastguard Worker     free(form);       /* free the struct */
772*6236dae4SAndroid Build Coastguard Worker     form = next;
773*6236dae4SAndroid Build Coastguard Worker   } while(form); /* continue */
774*6236dae4SAndroid Build Coastguard Worker }
775*6236dae4SAndroid Build Coastguard Worker 
776*6236dae4SAndroid Build Coastguard Worker 
777*6236dae4SAndroid Build Coastguard Worker /* Set mime part name, taking care of non null-terminated name string. */
setname(curl_mimepart * part,const char * name,size_t len)778*6236dae4SAndroid Build Coastguard Worker static CURLcode setname(curl_mimepart *part, const char *name, size_t len)
779*6236dae4SAndroid Build Coastguard Worker {
780*6236dae4SAndroid Build Coastguard Worker   char *zname;
781*6236dae4SAndroid Build Coastguard Worker   CURLcode res;
782*6236dae4SAndroid Build Coastguard Worker 
783*6236dae4SAndroid Build Coastguard Worker   if(!name || !len)
784*6236dae4SAndroid Build Coastguard Worker     return curl_mime_name(part, name);
785*6236dae4SAndroid Build Coastguard Worker   zname = Curl_memdup0(name, len);
786*6236dae4SAndroid Build Coastguard Worker   if(!zname)
787*6236dae4SAndroid Build Coastguard Worker     return CURLE_OUT_OF_MEMORY;
788*6236dae4SAndroid Build Coastguard Worker   res = curl_mime_name(part, zname);
789*6236dae4SAndroid Build Coastguard Worker   free(zname);
790*6236dae4SAndroid Build Coastguard Worker   return res;
791*6236dae4SAndroid Build Coastguard Worker }
792*6236dae4SAndroid Build Coastguard Worker 
793*6236dae4SAndroid Build Coastguard Worker /* wrap call to fseeko so it matches the calling convention of callback */
fseeko_wrapper(void * stream,curl_off_t offset,int whence)794*6236dae4SAndroid Build Coastguard Worker static int fseeko_wrapper(void *stream, curl_off_t offset, int whence)
795*6236dae4SAndroid Build Coastguard Worker {
796*6236dae4SAndroid Build Coastguard Worker #if defined(HAVE__FSEEKI64)
797*6236dae4SAndroid Build Coastguard Worker   return _fseeki64(stream, (__int64)offset, whence);
798*6236dae4SAndroid Build Coastguard Worker #elif defined(HAVE_FSEEKO) && defined(HAVE_DECL_FSEEKO)
799*6236dae4SAndroid Build Coastguard Worker   return fseeko(stream, (off_t)offset, whence);
800*6236dae4SAndroid Build Coastguard Worker #else
801*6236dae4SAndroid Build Coastguard Worker   if(offset > LONG_MAX)
802*6236dae4SAndroid Build Coastguard Worker     return -1;
803*6236dae4SAndroid Build Coastguard Worker   return fseek(stream, (long)offset, whence);
804*6236dae4SAndroid Build Coastguard Worker #endif
805*6236dae4SAndroid Build Coastguard Worker }
806*6236dae4SAndroid Build Coastguard Worker 
807*6236dae4SAndroid Build Coastguard Worker /*
808*6236dae4SAndroid Build Coastguard Worker  * Curl_getformdata() converts a linked list of "meta data" into a mime
809*6236dae4SAndroid Build Coastguard Worker  * structure. The input list is in 'post', while the output is stored in
810*6236dae4SAndroid Build Coastguard Worker  * mime part at '*finalform'.
811*6236dae4SAndroid Build Coastguard Worker  *
812*6236dae4SAndroid Build Coastguard Worker  * This function will not do a failf() for the potential memory failures but
813*6236dae4SAndroid Build Coastguard Worker  * should for all other errors it spots. Just note that this function MAY get
814*6236dae4SAndroid Build Coastguard Worker  * a NULL pointer in the 'data' argument.
815*6236dae4SAndroid Build Coastguard Worker  */
816*6236dae4SAndroid Build Coastguard Worker 
Curl_getformdata(CURL * data,curl_mimepart * finalform,struct curl_httppost * post,curl_read_callback fread_func)817*6236dae4SAndroid Build Coastguard Worker CURLcode Curl_getformdata(CURL *data,
818*6236dae4SAndroid Build Coastguard Worker                           curl_mimepart *finalform,
819*6236dae4SAndroid Build Coastguard Worker                           struct curl_httppost *post,
820*6236dae4SAndroid Build Coastguard Worker                           curl_read_callback fread_func)
821*6236dae4SAndroid Build Coastguard Worker {
822*6236dae4SAndroid Build Coastguard Worker   CURLcode result = CURLE_OK;
823*6236dae4SAndroid Build Coastguard Worker   curl_mime *form = NULL;
824*6236dae4SAndroid Build Coastguard Worker   curl_mimepart *part;
825*6236dae4SAndroid Build Coastguard Worker   struct curl_httppost *file;
826*6236dae4SAndroid Build Coastguard Worker 
827*6236dae4SAndroid Build Coastguard Worker   Curl_mime_cleanpart(finalform); /* default form is empty */
828*6236dae4SAndroid Build Coastguard Worker 
829*6236dae4SAndroid Build Coastguard Worker   if(!post)
830*6236dae4SAndroid Build Coastguard Worker     return result; /* no input => no output! */
831*6236dae4SAndroid Build Coastguard Worker 
832*6236dae4SAndroid Build Coastguard Worker   form = curl_mime_init(data);
833*6236dae4SAndroid Build Coastguard Worker   if(!form)
834*6236dae4SAndroid Build Coastguard Worker     result = CURLE_OUT_OF_MEMORY;
835*6236dae4SAndroid Build Coastguard Worker 
836*6236dae4SAndroid Build Coastguard Worker   if(!result)
837*6236dae4SAndroid Build Coastguard Worker     result = curl_mime_subparts(finalform, form);
838*6236dae4SAndroid Build Coastguard Worker 
839*6236dae4SAndroid Build Coastguard Worker   /* Process each top part. */
840*6236dae4SAndroid Build Coastguard Worker   for(; !result && post; post = post->next) {
841*6236dae4SAndroid Build Coastguard Worker     /* If we have more than a file here, create a mime subpart and fill it. */
842*6236dae4SAndroid Build Coastguard Worker     curl_mime *multipart = form;
843*6236dae4SAndroid Build Coastguard Worker     if(post->more) {
844*6236dae4SAndroid Build Coastguard Worker       part = curl_mime_addpart(form);
845*6236dae4SAndroid Build Coastguard Worker       if(!part)
846*6236dae4SAndroid Build Coastguard Worker         result = CURLE_OUT_OF_MEMORY;
847*6236dae4SAndroid Build Coastguard Worker       if(!result)
848*6236dae4SAndroid Build Coastguard Worker         result = setname(part, post->name, post->namelength);
849*6236dae4SAndroid Build Coastguard Worker       if(!result) {
850*6236dae4SAndroid Build Coastguard Worker         multipart = curl_mime_init(data);
851*6236dae4SAndroid Build Coastguard Worker         if(!multipart)
852*6236dae4SAndroid Build Coastguard Worker           result = CURLE_OUT_OF_MEMORY;
853*6236dae4SAndroid Build Coastguard Worker       }
854*6236dae4SAndroid Build Coastguard Worker       if(!result)
855*6236dae4SAndroid Build Coastguard Worker         result = curl_mime_subparts(part, multipart);
856*6236dae4SAndroid Build Coastguard Worker     }
857*6236dae4SAndroid Build Coastguard Worker 
858*6236dae4SAndroid Build Coastguard Worker     /* Generate all the part contents. */
859*6236dae4SAndroid Build Coastguard Worker     for(file = post; !result && file; file = file->more) {
860*6236dae4SAndroid Build Coastguard Worker       /* Create the part. */
861*6236dae4SAndroid Build Coastguard Worker       part = curl_mime_addpart(multipart);
862*6236dae4SAndroid Build Coastguard Worker       if(!part)
863*6236dae4SAndroid Build Coastguard Worker         result = CURLE_OUT_OF_MEMORY;
864*6236dae4SAndroid Build Coastguard Worker 
865*6236dae4SAndroid Build Coastguard Worker       /* Set the headers. */
866*6236dae4SAndroid Build Coastguard Worker       if(!result)
867*6236dae4SAndroid Build Coastguard Worker         result = curl_mime_headers(part, file->contentheader, 0);
868*6236dae4SAndroid Build Coastguard Worker 
869*6236dae4SAndroid Build Coastguard Worker       /* Set the content type. */
870*6236dae4SAndroid Build Coastguard Worker       if(!result && file->contenttype)
871*6236dae4SAndroid Build Coastguard Worker         result = curl_mime_type(part, file->contenttype);
872*6236dae4SAndroid Build Coastguard Worker 
873*6236dae4SAndroid Build Coastguard Worker       /* Set field name. */
874*6236dae4SAndroid Build Coastguard Worker       if(!result && !post->more)
875*6236dae4SAndroid Build Coastguard Worker         result = setname(part, post->name, post->namelength);
876*6236dae4SAndroid Build Coastguard Worker 
877*6236dae4SAndroid Build Coastguard Worker       /* Process contents. */
878*6236dae4SAndroid Build Coastguard Worker       if(!result) {
879*6236dae4SAndroid Build Coastguard Worker         curl_off_t clen = post->contentslength;
880*6236dae4SAndroid Build Coastguard Worker 
881*6236dae4SAndroid Build Coastguard Worker         if(post->flags & CURL_HTTPPOST_LARGE)
882*6236dae4SAndroid Build Coastguard Worker           clen = post->contentlen;
883*6236dae4SAndroid Build Coastguard Worker 
884*6236dae4SAndroid Build Coastguard Worker         if(post->flags & (HTTPPOST_FILENAME | HTTPPOST_READFILE)) {
885*6236dae4SAndroid Build Coastguard Worker           if(!strcmp(file->contents, "-")) {
886*6236dae4SAndroid Build Coastguard Worker             /* There are a few cases where the code below will not work; in
887*6236dae4SAndroid Build Coastguard Worker                particular, freopen(stdin) by the caller is not guaranteed
888*6236dae4SAndroid Build Coastguard Worker                to result as expected. This feature has been kept for backward
889*6236dae4SAndroid Build Coastguard Worker                compatibility: use of "-" pseudo filename should be avoided. */
890*6236dae4SAndroid Build Coastguard Worker             result = curl_mime_data_cb(part, (curl_off_t) -1,
891*6236dae4SAndroid Build Coastguard Worker                                        (curl_read_callback) fread,
892*6236dae4SAndroid Build Coastguard Worker                                        fseeko_wrapper,
893*6236dae4SAndroid Build Coastguard Worker                                        NULL, (void *) stdin);
894*6236dae4SAndroid Build Coastguard Worker           }
895*6236dae4SAndroid Build Coastguard Worker           else
896*6236dae4SAndroid Build Coastguard Worker             result = curl_mime_filedata(part, file->contents);
897*6236dae4SAndroid Build Coastguard Worker           if(!result && (post->flags & HTTPPOST_READFILE))
898*6236dae4SAndroid Build Coastguard Worker             result = curl_mime_filename(part, NULL);
899*6236dae4SAndroid Build Coastguard Worker         }
900*6236dae4SAndroid Build Coastguard Worker         else if(post->flags & HTTPPOST_BUFFER)
901*6236dae4SAndroid Build Coastguard Worker           result = curl_mime_data(part, post->buffer,
902*6236dae4SAndroid Build Coastguard Worker                                   post->bufferlength ?
903*6236dae4SAndroid Build Coastguard Worker                                   post->bufferlength : -1);
904*6236dae4SAndroid Build Coastguard Worker         else if(post->flags & HTTPPOST_CALLBACK) {
905*6236dae4SAndroid Build Coastguard Worker           /* the contents should be read with the callback and the size is set
906*6236dae4SAndroid Build Coastguard Worker              with the contentslength */
907*6236dae4SAndroid Build Coastguard Worker           if(!clen)
908*6236dae4SAndroid Build Coastguard Worker             clen = -1;
909*6236dae4SAndroid Build Coastguard Worker           result = curl_mime_data_cb(part, clen,
910*6236dae4SAndroid Build Coastguard Worker                                      fread_func, NULL, NULL, post->userp);
911*6236dae4SAndroid Build Coastguard Worker         }
912*6236dae4SAndroid Build Coastguard Worker         else {
913*6236dae4SAndroid Build Coastguard Worker           size_t uclen;
914*6236dae4SAndroid Build Coastguard Worker           if(!clen)
915*6236dae4SAndroid Build Coastguard Worker             uclen = CURL_ZERO_TERMINATED;
916*6236dae4SAndroid Build Coastguard Worker           else
917*6236dae4SAndroid Build Coastguard Worker             uclen = (size_t)clen;
918*6236dae4SAndroid Build Coastguard Worker           result = curl_mime_data(part, post->contents, uclen);
919*6236dae4SAndroid Build Coastguard Worker         }
920*6236dae4SAndroid Build Coastguard Worker       }
921*6236dae4SAndroid Build Coastguard Worker 
922*6236dae4SAndroid Build Coastguard Worker       /* Set fake filename. */
923*6236dae4SAndroid Build Coastguard Worker       if(!result && post->showfilename)
924*6236dae4SAndroid Build Coastguard Worker         if(post->more || (post->flags & (HTTPPOST_FILENAME | HTTPPOST_BUFFER |
925*6236dae4SAndroid Build Coastguard Worker                                         HTTPPOST_CALLBACK)))
926*6236dae4SAndroid Build Coastguard Worker           result = curl_mime_filename(part, post->showfilename);
927*6236dae4SAndroid Build Coastguard Worker     }
928*6236dae4SAndroid Build Coastguard Worker   }
929*6236dae4SAndroid Build Coastguard Worker 
930*6236dae4SAndroid Build Coastguard Worker   if(result)
931*6236dae4SAndroid Build Coastguard Worker     Curl_mime_cleanpart(finalform);
932*6236dae4SAndroid Build Coastguard Worker 
933*6236dae4SAndroid Build Coastguard Worker   return result;
934*6236dae4SAndroid Build Coastguard Worker }
935*6236dae4SAndroid Build Coastguard Worker 
936*6236dae4SAndroid Build Coastguard Worker #else
937*6236dae4SAndroid Build Coastguard Worker /* if disabled */
curl_formadd(struct curl_httppost ** httppost,struct curl_httppost ** last_post,...)938*6236dae4SAndroid Build Coastguard Worker CURLFORMcode curl_formadd(struct curl_httppost **httppost,
939*6236dae4SAndroid Build Coastguard Worker                           struct curl_httppost **last_post,
940*6236dae4SAndroid Build Coastguard Worker                           ...)
941*6236dae4SAndroid Build Coastguard Worker {
942*6236dae4SAndroid Build Coastguard Worker   (void)httppost;
943*6236dae4SAndroid Build Coastguard Worker   (void)last_post;
944*6236dae4SAndroid Build Coastguard Worker   return CURL_FORMADD_DISABLED;
945*6236dae4SAndroid Build Coastguard Worker }
946*6236dae4SAndroid Build Coastguard Worker 
curl_formget(struct curl_httppost * form,void * arg,curl_formget_callback append)947*6236dae4SAndroid Build Coastguard Worker int curl_formget(struct curl_httppost *form, void *arg,
948*6236dae4SAndroid Build Coastguard Worker                  curl_formget_callback append)
949*6236dae4SAndroid Build Coastguard Worker {
950*6236dae4SAndroid Build Coastguard Worker   (void) form;
951*6236dae4SAndroid Build Coastguard Worker   (void) arg;
952*6236dae4SAndroid Build Coastguard Worker   (void) append;
953*6236dae4SAndroid Build Coastguard Worker   return CURL_FORMADD_DISABLED;
954*6236dae4SAndroid Build Coastguard Worker }
955*6236dae4SAndroid Build Coastguard Worker 
curl_formfree(struct curl_httppost * form)956*6236dae4SAndroid Build Coastguard Worker void curl_formfree(struct curl_httppost *form)
957*6236dae4SAndroid Build Coastguard Worker {
958*6236dae4SAndroid Build Coastguard Worker   (void)form;
959*6236dae4SAndroid Build Coastguard Worker   /* Nothing to do. */
960*6236dae4SAndroid Build Coastguard Worker }
961*6236dae4SAndroid Build Coastguard Worker 
962*6236dae4SAndroid Build Coastguard Worker #endif  /* if disabled */
963