source cleanup: unify look, style and indent levels
[platform/upstream/curl.git] / lib / formdata.c
1 /***************************************************************************
2  *                                  _   _ ____  _
3  *  Project                     ___| | | |  _ \| |
4  *                             / __| | | | |_) | |
5  *                            | (__| |_| |  _ <| |___
6  *                             \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
9  *
10  * This software is licensed as described in the file COPYING, which
11  * you should have received as part of this distribution. The terms
12  * are also available at http://curl.haxx.se/docs/copyright.html.
13  *
14  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15  * copies of the Software, and permit persons to whom the Software is
16  * furnished to do so, under the terms of the COPYING file.
17  *
18  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19  * KIND, either express or implied.
20  *
21  ***************************************************************************/
22
23 #include "setup.h"
24 #include <curl/curl.h>
25
26 /* Length of the random boundary string. */
27 #define BOUNDARY_LENGTH 40
28
29 #if !defined(CURL_DISABLE_HTTP) || defined(USE_SSLEAY)
30
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <stdarg.h>
35 #include <time.h>
36 #if defined(HAVE_LIBGEN_H) && defined(HAVE_BASENAME)
37 #include <libgen.h>
38 #endif
39 #include "urldata.h" /* for struct SessionHandle */
40 #include "formdata.h"
41 #include "curl_rand.h"
42 #include "strequal.h"
43 #include "curl_memory.h"
44 #include "sendf.h"
45
46 #define _MPRINTF_REPLACE /* use our functions only */
47 #include <curl/mprintf.h>
48
49 /* The last #include file should be: */
50 #include "memdebug.h"
51
52 #endif  /* !defined(CURL_DISABLE_HTTP) || defined(USE_SSLEAY) */
53
54 #ifndef CURL_DISABLE_HTTP
55
56 #ifndef HAVE_BASENAME
57 static char *Curl_basename(char *path);
58 #define basename(x)  Curl_basename((x))
59 #endif
60
61 static size_t readfromfile(struct Form *form, char *buffer, size_t size);
62
63 /* What kind of Content-Type to use on un-specified files with unrecognized
64    extensions. */
65 #define HTTPPOST_CONTENTTYPE_DEFAULT "application/octet-stream"
66
67 #define FORM_FILE_SEPARATOR ','
68 #define FORM_TYPE_SEPARATOR ';'
69
70 /***************************************************************************
71  *
72  * AddHttpPost()
73  *
74  * Adds a HttpPost structure to the list, if parent_post is given becomes
75  * a subpost of parent_post instead of a direct list element.
76  *
77  * Returns newly allocated HttpPost on success and NULL if malloc failed.
78  *
79  ***************************************************************************/
80 static struct curl_httppost *
81 AddHttpPost(char *name, size_t namelength,
82             char *value, size_t contentslength,
83             char *buffer, size_t bufferlength,
84             char *contenttype,
85             long flags,
86             struct curl_slist* contentHeader,
87             char *showfilename, char *userp,
88             struct curl_httppost *parent_post,
89             struct curl_httppost **httppost,
90             struct curl_httppost **last_post)
91 {
92   struct curl_httppost *post;
93   post = calloc(1, sizeof(struct curl_httppost));
94   if(post) {
95     post->name = name;
96     post->namelength = (long)(name?(namelength?namelength:strlen(name)):0);
97     post->contents = value;
98     post->contentslength = (long)contentslength;
99     post->buffer = buffer;
100     post->bufferlength = (long)bufferlength;
101     post->contenttype = contenttype;
102     post->contentheader = contentHeader;
103     post->showfilename = showfilename;
104     post->userp = userp,
105     post->flags = flags;
106   }
107   else
108     return NULL;
109
110   if(parent_post) {
111     /* now, point our 'more' to the original 'more' */
112     post->more = parent_post->more;
113
114     /* then move the original 'more' to point to ourselves */
115     parent_post->more = post;
116   }
117   else {
118     /* make the previous point to this */
119     if(*last_post)
120       (*last_post)->next = post;
121     else
122       (*httppost) = post;
123
124     (*last_post) = post;
125   }
126   return post;
127 }
128
129 /***************************************************************************
130  *
131  * AddFormInfo()
132  *
133  * Adds a FormInfo structure to the list presented by parent_form_info.
134  *
135  * Returns newly allocated FormInfo on success and NULL if malloc failed/
136  * parent_form_info is NULL.
137  *
138  ***************************************************************************/
139 static FormInfo * AddFormInfo(char *value,
140                               char *contenttype,
141                               FormInfo *parent_form_info)
142 {
143   FormInfo *form_info;
144   form_info = calloc(1, sizeof(struct FormInfo));
145   if(form_info) {
146     if(value)
147       form_info->value = value;
148     if(contenttype)
149       form_info->contenttype = contenttype;
150     form_info->flags = HTTPPOST_FILENAME;
151   }
152   else
153     return NULL;
154
155   if(parent_form_info) {
156     /* now, point our 'more' to the original 'more' */
157     form_info->more = parent_form_info->more;
158
159     /* then move the original 'more' to point to ourselves */
160     parent_form_info->more = form_info;
161   }
162   else
163     return NULL;
164
165   return form_info;
166 }
167
168 /***************************************************************************
169  *
170  * ContentTypeForFilename()
171  *
172  * Provides content type for filename if one of the known types (else
173  * (either the prevtype or the default is returned).
174  *
175  * Returns some valid contenttype for filename.
176  *
177  ***************************************************************************/
178 static const char * ContentTypeForFilename (const char *filename,
179                                             const char *prevtype)
180 {
181   const char *contenttype = NULL;
182   unsigned int i;
183   /*
184    * No type was specified, we scan through a few well-known
185    * extensions and pick the first we match!
186    */
187   struct ContentType {
188     char extension[6];
189     const char *type;
190   };
191   static const struct ContentType ctts[]={
192     {".gif",  "image/gif"},
193     {".jpg",  "image/jpeg"},
194     {".jpeg", "image/jpeg"},
195     {".txt",  "text/plain"},
196     {".html", "text/html"},
197     {".xml", "application/xml"}
198   };
199
200   if(prevtype)
201     /* default to the previously set/used! */
202     contenttype = prevtype;
203   else
204     contenttype = HTTPPOST_CONTENTTYPE_DEFAULT;
205
206   if(filename) { /* in case a NULL was passed in */
207     for(i=0; i<sizeof(ctts)/sizeof(ctts[0]); i++) {
208       if(strlen(filename) >= strlen(ctts[i].extension)) {
209         if(strequal(filename +
210                     strlen(filename) - strlen(ctts[i].extension),
211                     ctts[i].extension)) {
212           contenttype = ctts[i].type;
213           break;
214         }
215       }
216     }
217   }
218   /* we have a contenttype by now */
219   return contenttype;
220 }
221
222 /***************************************************************************
223  *
224  * memdup()
225  *
226  * Copies the 'source' data to a newly allocated buffer buffer (that is
227  * returned). Uses buffer_length if not null, else uses strlen to determine
228  * the length of the buffer to be copied
229  *
230  * Returns the new pointer or NULL on failure.
231  *
232  ***************************************************************************/
233 static char *memdup(const char *src, size_t buffer_length)
234 {
235   size_t length;
236   bool add = FALSE;
237   char *buffer;
238
239   if(buffer_length)
240     length = buffer_length;
241   else if(src) {
242     length = strlen(src);
243     add = TRUE;
244   }
245   else
246     /* no length and a NULL src pointer! */
247     return strdup("");
248
249   buffer = malloc(length+add);
250   if(!buffer)
251     return NULL; /* fail */
252
253   memcpy(buffer, src, length);
254
255   /* if length unknown do null termination */
256   if(add)
257     buffer[length] = '\0';
258
259   return buffer;
260 }
261
262 /***************************************************************************
263  *
264  * FormAdd()
265  *
266  * Stores a formpost parameter and builds the appropriate linked list.
267  *
268  * Has two principal functionalities: using files and byte arrays as
269  * post parts. Byte arrays are either copied or just the pointer is stored
270  * (as the user requests) while for files only the filename and not the
271  * content is stored.
272  *
273  * While you may have only one byte array for each name, multiple filenames
274  * are allowed (and because of this feature CURLFORM_END is needed after
275  * using CURLFORM_FILE).
276  *
277  * Examples:
278  *
279  * Simple name/value pair with copied contents:
280  * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name",
281  * CURLFORM_COPYCONTENTS, "value", CURLFORM_END);
282  *
283  * name/value pair where only the content pointer is remembered:
284  * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name",
285  * CURLFORM_PTRCONTENTS, ptr, CURLFORM_CONTENTSLENGTH, 10, CURLFORM_END);
286  * (if CURLFORM_CONTENTSLENGTH is missing strlen () is used)
287  *
288  * storing a filename (CONTENTTYPE is optional!):
289  * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name",
290  * CURLFORM_FILE, "filename1", CURLFORM_CONTENTTYPE, "plain/text",
291  * CURLFORM_END);
292  *
293  * storing multiple filenames:
294  * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name",
295  * CURLFORM_FILE, "filename1", CURLFORM_FILE, "filename2", CURLFORM_END);
296  *
297  * Returns:
298  * CURL_FORMADD_OK             on success
299  * CURL_FORMADD_MEMORY         if the FormInfo allocation fails
300  * CURL_FORMADD_OPTION_TWICE   if one option is given twice for one Form
301  * CURL_FORMADD_NULL           if a null pointer was given for a char
302  * CURL_FORMADD_MEMORY         if the allocation of a FormInfo struct failed
303  * CURL_FORMADD_UNKNOWN_OPTION if an unknown option was used
304  * CURL_FORMADD_INCOMPLETE     if the some FormInfo is not complete (or error)
305  * CURL_FORMADD_MEMORY         if a HttpPost struct cannot be allocated
306  * CURL_FORMADD_MEMORY         if some allocation for string copying failed.
307  * CURL_FORMADD_ILLEGAL_ARRAY  if an illegal option is used in an array
308  *
309  ***************************************************************************/
310
311 static
312 CURLFORMcode FormAdd(struct curl_httppost **httppost,
313                      struct curl_httppost **last_post,
314                      va_list params)
315 {
316   FormInfo *first_form, *current_form, *form = NULL;
317   CURLFORMcode return_value = CURL_FORMADD_OK;
318   const char *prevtype = NULL;
319   struct curl_httppost *post = NULL;
320   CURLformoption option;
321   struct curl_forms *forms = NULL;
322   char *array_value=NULL; /* value read from an array */
323
324   /* This is a state variable, that if TRUE means that we're parsing an
325      array that we got passed to us. If FALSE we're parsing the input
326      va_list arguments. */
327   bool array_state = FALSE;
328
329   /*
330    * We need to allocate the first struct to fill in.
331    */
332   first_form = calloc(1, sizeof(struct FormInfo));
333   if(!first_form)
334     return CURL_FORMADD_MEMORY;
335
336   current_form = first_form;
337
338   /*
339    * Loop through all the options set. Break if we have an error to report.
340    */
341   while(return_value == CURL_FORMADD_OK) {
342
343     /* first see if we have more parts of the array param */
344     if( array_state && forms ) {
345       /* get the upcoming option from the given array */
346       option = forms->option;
347       array_value = (char *)forms->value;
348
349       forms++; /* advance this to next entry */
350       if(CURLFORM_END == option) {
351         /* end of array state */
352         array_state = FALSE;
353         continue;
354       }
355     }
356     else {
357       /* This is not array-state, get next option */
358       option = va_arg(params, CURLformoption);
359       if(CURLFORM_END == option)
360         break;
361     }
362
363     switch (option) {
364     case CURLFORM_ARRAY:
365       if(array_state)
366         /* we don't support an array from within an array */
367         return_value = CURL_FORMADD_ILLEGAL_ARRAY;
368       else {
369         forms = va_arg(params, struct curl_forms *);
370         if(forms)
371           array_state = TRUE;
372         else
373           return_value = CURL_FORMADD_NULL;
374       }
375       break;
376
377       /*
378        * Set the Name property.
379        */
380     case CURLFORM_PTRNAME:
381 #ifdef CURL_DOES_CONVERSIONS
382       /* Treat CURLFORM_PTR like CURLFORM_COPYNAME so that libcurl will copy
383        * the data in all cases so that we'll have safe memory for the eventual
384        * conversion.
385        */
386 #else
387       current_form->flags |= HTTPPOST_PTRNAME; /* fall through */
388 #endif
389     case CURLFORM_COPYNAME:
390       if(current_form->name)
391         return_value = CURL_FORMADD_OPTION_TWICE;
392       else {
393         char *name = array_state?
394           array_value:va_arg(params, char *);
395         if(name)
396           current_form->name = name; /* store for the moment */
397         else
398           return_value = CURL_FORMADD_NULL;
399       }
400       break;
401     case CURLFORM_NAMELENGTH:
402       if(current_form->namelength)
403         return_value = CURL_FORMADD_OPTION_TWICE;
404       else
405         current_form->namelength =
406           array_state?(size_t)array_value:(size_t)va_arg(params, long);
407       break;
408
409       /*
410        * Set the contents property.
411        */
412     case CURLFORM_PTRCONTENTS:
413       current_form->flags |= HTTPPOST_PTRCONTENTS; /* fall through */
414     case CURLFORM_COPYCONTENTS:
415       if(current_form->value)
416         return_value = CURL_FORMADD_OPTION_TWICE;
417       else {
418         char *value =
419           array_state?array_value:va_arg(params, char *);
420         if(value)
421           current_form->value = value; /* store for the moment */
422         else
423           return_value = CURL_FORMADD_NULL;
424       }
425       break;
426     case CURLFORM_CONTENTSLENGTH:
427       if(current_form->contentslength)
428         return_value = CURL_FORMADD_OPTION_TWICE;
429       else
430         current_form->contentslength =
431           array_state?(size_t)array_value:(size_t)va_arg(params, long);
432       break;
433
434       /* Get contents from a given file name */
435     case CURLFORM_FILECONTENT:
436       if(current_form->flags != 0)
437         return_value = CURL_FORMADD_OPTION_TWICE;
438       else {
439         const char *filename = array_state?
440           array_value:va_arg(params, char *);
441         if(filename) {
442           current_form->value = strdup(filename);
443           if(!current_form->value)
444             return_value = CURL_FORMADD_MEMORY;
445           else {
446             current_form->flags |= HTTPPOST_READFILE;
447             current_form->value_alloc = TRUE;
448           }
449         }
450         else
451           return_value = CURL_FORMADD_NULL;
452       }
453       break;
454
455       /* We upload a file */
456     case CURLFORM_FILE:
457       {
458         const char *filename = array_state?array_value:
459           va_arg(params, char *);
460
461         if(current_form->value) {
462           if(current_form->flags & HTTPPOST_FILENAME) {
463             if(filename) {
464               if((current_form = AddFormInfo(strdup(filename),
465                                               NULL, current_form)) == NULL)
466                 return_value = CURL_FORMADD_MEMORY;
467             }
468             else
469               return_value = CURL_FORMADD_NULL;
470           }
471           else
472             return_value = CURL_FORMADD_OPTION_TWICE;
473         }
474         else {
475           if(filename) {
476             current_form->value = strdup(filename);
477             if(!current_form->value)
478               return_value = CURL_FORMADD_MEMORY;
479             else {
480               current_form->flags |= HTTPPOST_FILENAME;
481               current_form->value_alloc = TRUE;
482             }
483           }
484           else
485             return_value = CURL_FORMADD_NULL;
486         }
487         break;
488       }
489
490     case CURLFORM_BUFFER:
491       {
492         const char *filename = array_state?array_value:
493           va_arg(params, char *);
494
495         if(current_form->value) {
496           if(current_form->flags & HTTPPOST_BUFFER) {
497             if(filename) {
498               if((current_form = AddFormInfo(strdup(filename),
499                                               NULL, current_form)) == NULL)
500                 return_value = CURL_FORMADD_MEMORY;
501             }
502             else
503               return_value = CURL_FORMADD_NULL;
504           }
505           else
506             return_value = CURL_FORMADD_OPTION_TWICE;
507         }
508         else {
509           if(filename) {
510             current_form->value = strdup(filename);
511             if(!current_form->value)
512               return_value = CURL_FORMADD_MEMORY;
513           }
514           else
515             return_value = CURL_FORMADD_NULL;
516           current_form->flags |= HTTPPOST_BUFFER;
517         }
518         break;
519       }
520
521     case CURLFORM_BUFFERPTR:
522       current_form->flags |= HTTPPOST_PTRBUFFER;
523       if(current_form->buffer)
524         return_value = CURL_FORMADD_OPTION_TWICE;
525       else {
526         char *buffer =
527           array_state?array_value:va_arg(params, char *);
528         if(buffer)
529           current_form->buffer = buffer; /* store for the moment */
530         else
531           return_value = CURL_FORMADD_NULL;
532       }
533       break;
534
535     case CURLFORM_BUFFERLENGTH:
536       if(current_form->bufferlength)
537         return_value = CURL_FORMADD_OPTION_TWICE;
538       else
539         current_form->bufferlength =
540           array_state?(size_t)array_value:(size_t)va_arg(params, long);
541       break;
542
543     case CURLFORM_STREAM:
544       current_form->flags |= HTTPPOST_CALLBACK;
545       if(current_form->userp)
546         return_value = CURL_FORMADD_OPTION_TWICE;
547       else {
548         char *userp =
549           array_state?array_value:va_arg(params, char *);
550         if(userp) {
551           current_form->userp = userp;
552           current_form->value = userp; /* this isn't strictly true but we
553                                           derive a value from this later on
554                                           and we need this non-NULL to be
555                                           accepted as a fine form part */
556         }
557         else
558           return_value = CURL_FORMADD_NULL;
559       }
560       break;
561
562     case CURLFORM_CONTENTTYPE:
563       {
564         const char *contenttype =
565           array_state?array_value:va_arg(params, char *);
566         if(current_form->contenttype) {
567           if(current_form->flags & HTTPPOST_FILENAME) {
568             if(contenttype) {
569               if((current_form = AddFormInfo(NULL,
570                                               strdup(contenttype),
571                                               current_form)) == NULL)
572                 return_value = CURL_FORMADD_MEMORY;
573             }
574             else
575               return_value = CURL_FORMADD_NULL;
576           }
577           else
578             return_value = CURL_FORMADD_OPTION_TWICE;
579         }
580         else {
581           if(contenttype) {
582             current_form->contenttype = strdup(contenttype);
583             if(!current_form->contenttype)
584               return_value = CURL_FORMADD_MEMORY;
585             else
586               current_form->contenttype_alloc = TRUE;
587           }
588           else
589             return_value = CURL_FORMADD_NULL;
590         }
591         break;
592       }
593     case CURLFORM_CONTENTHEADER:
594       {
595         /* this "cast increases required alignment of target type" but
596            we consider it OK anyway */
597         struct curl_slist* list = array_state?
598           (struct curl_slist*)array_value:
599           va_arg(params, struct curl_slist*);
600
601         if( current_form->contentheader )
602           return_value = CURL_FORMADD_OPTION_TWICE;
603         else
604           current_form->contentheader = list;
605
606         break;
607       }
608     case CURLFORM_FILENAME:
609       {
610         const char *filename = array_state?array_value:
611           va_arg(params, char *);
612         if( current_form->showfilename )
613           return_value = CURL_FORMADD_OPTION_TWICE;
614         else {
615           current_form->showfilename = strdup(filename);
616           if(!current_form->showfilename)
617             return_value = CURL_FORMADD_MEMORY;
618           else
619             current_form->showfilename_alloc = TRUE;
620         }
621         break;
622       }
623     default:
624       return_value = CURL_FORMADD_UNKNOWN_OPTION;
625     }
626   }
627
628   if(CURL_FORMADD_OK == return_value) {
629     /* go through the list, check for completeness and if everything is
630      * alright add the HttpPost item otherwise set return_value accordingly */
631
632     post = NULL;
633     for(form = first_form;
634         form != NULL;
635         form = form->more) {
636       if( ((!form->name || !form->value) && !post) ||
637           ( (form->contentslength) &&
638             (form->flags & HTTPPOST_FILENAME) ) ||
639           ( (form->flags & HTTPPOST_FILENAME) &&
640             (form->flags & HTTPPOST_PTRCONTENTS) ) ||
641
642           ( (!form->buffer) &&
643             (form->flags & HTTPPOST_BUFFER) &&
644             (form->flags & HTTPPOST_PTRBUFFER) ) ||
645
646           ( (form->flags & HTTPPOST_READFILE) &&
647             (form->flags & HTTPPOST_PTRCONTENTS) )
648         ) {
649         return_value = CURL_FORMADD_INCOMPLETE;
650         break;
651       }
652       else {
653         if( ((form->flags & HTTPPOST_FILENAME) ||
654               (form->flags & HTTPPOST_BUFFER)) &&
655              !form->contenttype ) {
656           /* our contenttype is missing */
657           form->contenttype
658             = strdup(ContentTypeForFilename(form->value, prevtype));
659           if(!form->contenttype) {
660             return_value = CURL_FORMADD_MEMORY;
661             break;
662           }
663           form->contenttype_alloc = TRUE;
664         }
665         if( !(form->flags & HTTPPOST_PTRNAME) &&
666              (form == first_form) ) {
667           /* Note that there's small risk that form->name is NULL here if the
668              app passed in a bad combo, so we better check for that first. */
669           if(form->name)
670             /* copy name (without strdup; possibly contains null characters) */
671             form->name = memdup(form->name, form->namelength);
672           if(!form->name) {
673             return_value = CURL_FORMADD_MEMORY;
674             break;
675           }
676           form->name_alloc = TRUE;
677         }
678         if( !(form->flags & (HTTPPOST_FILENAME | HTTPPOST_READFILE |
679                              HTTPPOST_PTRCONTENTS | HTTPPOST_PTRBUFFER |
680                              HTTPPOST_CALLBACK)) ) {
681           /* copy value (without strdup; possibly contains null characters) */
682           form->value = memdup(form->value, form->contentslength);
683           if(!form->value) {
684             return_value = CURL_FORMADD_MEMORY;
685             break;
686           }
687           form->value_alloc = TRUE;
688         }
689         post = AddHttpPost(form->name, form->namelength,
690                            form->value, form->contentslength,
691                            form->buffer, form->bufferlength,
692                            form->contenttype, form->flags,
693                            form->contentheader, form->showfilename,
694                            form->userp,
695                            post, httppost,
696                            last_post);
697
698         if(!post) {
699           return_value = CURL_FORMADD_MEMORY;
700           break;
701         }
702
703         if(form->contenttype)
704           prevtype = form->contenttype;
705       }
706     }
707   }
708
709   if(return_value) {
710     /* we return on error, free possibly allocated fields */
711     if(!form)
712       form = current_form;
713     if(form) {
714       if(form->name_alloc)
715         free(form->name);
716       if(form->value_alloc)
717         free(form->value);
718       if(form->contenttype_alloc)
719         free(form->contenttype);
720       if(form->showfilename_alloc)
721         free(form->showfilename);
722     }
723   }
724
725   /* always delete the allocated memory before returning */
726   form = first_form;
727   while(form != NULL) {
728     FormInfo *delete_form;
729
730     delete_form = form;
731     form = form->more;
732     free (delete_form);
733   }
734
735   return return_value;
736 }
737
738 /*
739  * curl_formadd() is a public API to add a section to the multipart formpost.
740  */
741
742 CURLFORMcode curl_formadd(struct curl_httppost **httppost,
743                           struct curl_httppost **last_post,
744                           ...)
745 {
746   va_list arg;
747   CURLFORMcode result;
748   va_start(arg, last_post);
749   result = FormAdd(httppost, last_post, arg);
750   va_end(arg);
751   return result;
752 }
753
754 /*
755  * AddFormData() adds a chunk of data to the FormData linked list.
756  *
757  * size is incremented by the chunk length, unless it is NULL
758  */
759 static CURLcode AddFormData(struct FormData **formp,
760                             enum formtype type,
761                             const void *line,
762                             size_t length,
763                             curl_off_t *size)
764 {
765   struct FormData *newform = malloc(sizeof(struct FormData));
766   if(!newform)
767     return CURLE_OUT_OF_MEMORY;
768   newform->next = NULL;
769
770   if(type <= FORM_CONTENT) {
771     /* we make it easier for plain strings: */
772     if(!length)
773       length = strlen((char *)line);
774
775     newform->line = malloc(length+1);
776     if(!newform->line) {
777       free(newform);
778       return CURLE_OUT_OF_MEMORY;
779     }
780     memcpy(newform->line, line, length);
781     newform->length = length;
782     newform->line[length]=0; /* zero terminate for easier debugging */
783   }
784   else
785     /* For callbacks and files we don't have any actual data so we just keep a
786        pointer to whatever this points to */
787     newform->line = (char *)line;
788
789   newform->type = type;
790
791   if(*formp) {
792     (*formp)->next = newform;
793     *formp = newform;
794   }
795   else
796     *formp = newform;
797
798   if(size) {
799     if(type != FORM_FILE)
800       /* for static content as well as callback data we add the size given
801          as input argument */
802       *size += length;
803     else {
804       /* Since this is a file to be uploaded here, add the size of the actual
805          file */
806       if(!strequal("-", newform->line)) {
807         struct_stat file;
808         if(!stat(newform->line, &file)) {
809           *size += file.st_size;
810         }
811       }
812     }
813   }
814   return CURLE_OK;
815 }
816
817 /*
818  * AddFormDataf() adds printf()-style formatted data to the formdata chain.
819  */
820
821 static CURLcode AddFormDataf(struct FormData **formp,
822                              curl_off_t *size,
823                              const char *fmt, ...)
824 {
825   char s[4096];
826   va_list ap;
827   va_start(ap, fmt);
828   vsnprintf(s, sizeof(s), fmt, ap);
829   va_end(ap);
830
831   return AddFormData(formp, FORM_DATA, s, 0, size);
832 }
833
834 /*
835  * Curl_formclean() is used from http.c, this cleans a built FormData linked
836  * list
837  */
838 void Curl_formclean(struct FormData **form_ptr)
839 {
840   struct FormData *next, *form;
841
842   form = *form_ptr;
843   if(!form)
844     return;
845
846   do {
847     next=form->next;  /* the following form line */
848     if(form->type <= FORM_CONTENT)
849       free(form->line); /* free the line */
850     free(form);       /* free the struct */
851
852   } while((form = next) != NULL); /* continue */
853
854   *form_ptr = NULL;
855 }
856
857 /*
858  * curl_formget()
859  * Serialize a curl_httppost struct.
860  * Returns 0 on success.
861  */
862 int curl_formget(struct curl_httppost *form, void *arg,
863                  curl_formget_callback append)
864 {
865   CURLcode rc;
866   curl_off_t size;
867   struct FormData *data, *ptr;
868
869   rc = Curl_getformdata(NULL, &data, form, NULL, &size);
870   if(rc != CURLE_OK)
871     return (int)rc;
872
873   for(ptr = data; ptr; ptr = ptr->next) {
874     if(ptr->type == FORM_FILE) {
875       char buffer[8192];
876       size_t nread;
877       struct Form temp;
878
879       Curl_FormInit(&temp, ptr);
880
881       do {
882         nread = readfromfile(&temp, buffer, sizeof(buffer));
883         if((nread == (size_t) -1) || (nread != append(arg, buffer, nread))) {
884           if(temp.fp) {
885             fclose(temp.fp);
886           }
887           Curl_formclean(&data);
888           return -1;
889         }
890       } while(nread == sizeof(buffer));
891     }
892     else {
893       if(ptr->length != append(arg, ptr->line, ptr->length)) {
894         Curl_formclean(&data);
895         return -1;
896       }
897     }
898   }
899   Curl_formclean(&data);
900   return 0;
901 }
902
903 /*
904  * curl_formfree() is an external function to free up a whole form post
905  * chain
906  */
907 void curl_formfree(struct curl_httppost *form)
908 {
909   struct curl_httppost *next;
910
911   if(!form)
912     /* no form to free, just get out of this */
913     return;
914
915   do {
916     next=form->next;  /* the following form line */
917
918     /* recurse to sub-contents */
919     if(form->more)
920       curl_formfree(form->more);
921
922     if( !(form->flags & HTTPPOST_PTRNAME) && form->name)
923       free(form->name); /* free the name */
924     if( !(form->flags & (HTTPPOST_PTRCONTENTS|HTTPPOST_CALLBACK)) &&
925         form->contents)
926       free(form->contents); /* free the contents */
927     if(form->contenttype)
928       free(form->contenttype); /* free the content type */
929     if(form->showfilename)
930       free(form->showfilename); /* free the faked file name */
931     free(form);       /* free the struct */
932
933   } while((form = next) != NULL); /* continue */
934 }
935
936 #ifndef HAVE_BASENAME
937 /*
938   (Quote from The Open Group Base Specifications Issue 6 IEEE Std 1003.1, 2004
939   Edition)
940
941   The basename() function shall take the pathname pointed to by path and
942   return a pointer to the final component of the pathname, deleting any
943   trailing '/' characters.
944
945   If the string pointed to by path consists entirely of the '/' character,
946   basename() shall return a pointer to the string "/". If the string pointed
947   to by path is exactly "//", it is implementation-defined whether '/' or "//"
948   is returned.
949
950   If path is a null pointer or points to an empty string, basename() shall
951   return a pointer to the string ".".
952
953   The basename() function may modify the string pointed to by path, and may
954   return a pointer to static storage that may then be overwritten by a
955   subsequent call to basename().
956
957   The basename() function need not be reentrant. A function that is not
958   required to be reentrant is not required to be thread-safe.
959
960 */
961 static char *Curl_basename(char *path)
962 {
963   /* Ignore all the details above for now and make a quick and simple
964      implementaion here */
965   char *s1;
966   char *s2;
967
968   s1=strrchr(path, '/');
969   s2=strrchr(path, '\\');
970
971   if(s1 && s2) {
972     path = (s1 > s2? s1 : s2)+1;
973   }
974   else if(s1)
975     path = s1 + 1;
976   else if(s2)
977     path = s2 + 1;
978
979   return path;
980 }
981 #endif
982
983 static char *strippath(const char *fullfile)
984 {
985   char *filename;
986   char *base;
987   filename = strdup(fullfile); /* duplicate since basename() may ruin the
988                                   buffer it works on */
989   if(!filename)
990     return NULL;
991   base = strdup(basename(filename));
992
993   free(filename); /* free temporary buffer */
994
995   return base; /* returns an allocated string or NULL ! */
996 }
997
998 /*
999  * Curl_getformdata() converts a linked list of "meta data" into a complete
1000  * (possibly huge) multipart formdata. The input list is in 'post', while the
1001  * output resulting linked lists gets stored in '*finalform'. *sizep will get
1002  * the total size of the whole POST.
1003  * A multipart/form_data content-type is built, unless a custom content-type
1004  * is passed in 'custom_content_type'.
1005  *
1006  * This function will not do a failf() for the potential memory failures but
1007  * should for all other errors it spots. Just note that this function MAY get
1008  * a NULL pointer in the 'data' argument.
1009  */
1010
1011 CURLcode Curl_getformdata(struct SessionHandle *data,
1012                           struct FormData **finalform,
1013                           struct curl_httppost *post,
1014                           const char *custom_content_type,
1015                           curl_off_t *sizep)
1016 {
1017   struct FormData *form = NULL;
1018   struct FormData *firstform;
1019   struct curl_httppost *file;
1020   CURLcode result = CURLE_OK;
1021
1022   curl_off_t size=0; /* support potentially ENORMOUS formposts */
1023   char *boundary;
1024   char *fileboundary=NULL;
1025   struct curl_slist* curList;
1026
1027   *finalform=NULL; /* default form is empty */
1028
1029   if(!post)
1030     return result; /* no input => no output! */
1031
1032   boundary = Curl_FormBoundary();
1033   if(!boundary)
1034     return CURLE_OUT_OF_MEMORY;
1035
1036   /* Make the first line of the output */
1037   result = AddFormDataf(&form, NULL,
1038                         "%s; boundary=%s\r\n",
1039                         custom_content_type?custom_content_type:
1040                         "Content-Type: multipart/form-data",
1041                         boundary);
1042
1043   if(result) {
1044     free(boundary);
1045     return result;
1046   }
1047   /* we DO NOT include that line in the total size of the POST, since it'll be
1048      part of the header! */
1049
1050   firstform = form;
1051
1052   do {
1053
1054     if(size) {
1055       result = AddFormDataf(&form, &size, "\r\n");
1056       if(result)
1057         break;
1058     }
1059
1060     /* boundary */
1061     result = AddFormDataf(&form, &size, "--%s\r\n", boundary);
1062     if(result)
1063       break;
1064
1065     /* Maybe later this should be disabled when a custom_content_type is
1066        passed, since Content-Disposition is not meaningful for all multipart
1067        types.
1068     */
1069     result = AddFormDataf(&form, &size,
1070                           "Content-Disposition: form-data; name=\"");
1071     if(result)
1072       break;
1073
1074     result = AddFormData(&form, FORM_DATA, post->name, post->namelength,
1075                          &size);
1076     if(result)
1077       break;
1078
1079     result = AddFormDataf(&form, &size, "\"");
1080     if(result)
1081       break;
1082
1083     if(post->more) {
1084       /* If used, this is a link to more file names, we must then do
1085          the magic to include several files with the same field name */
1086
1087       fileboundary = Curl_FormBoundary();
1088
1089       result = AddFormDataf(&form, &size,
1090                             "\r\nContent-Type: multipart/mixed,"
1091                             " boundary=%s\r\n",
1092                             fileboundary);
1093       if(result)
1094         break;
1095     }
1096
1097     file = post;
1098
1099     do {
1100
1101       /* If 'showfilename' is set, that is a faked name passed on to us
1102          to use to in the formpost. If that is not set, the actually used
1103          local file name should be added. */
1104
1105       if(post->more) {
1106         /* if multiple-file */
1107         char *filebasename= NULL;
1108         if(!file->showfilename) {
1109           filebasename = strippath(file->contents);
1110           if(!filebasename) {
1111             Curl_formclean(&firstform);
1112             free(boundary);
1113             return CURLE_OUT_OF_MEMORY;
1114           }
1115         }
1116
1117         result = AddFormDataf(&form, &size,
1118                               "\r\n--%s\r\nContent-Disposition: "
1119                               "attachment; filename=\"%s\"",
1120                               fileboundary,
1121                               (file->showfilename?file->showfilename:
1122                                filebasename));
1123         if(filebasename)
1124           free(filebasename);
1125         if(result)
1126           break;
1127       }
1128       else if(post->flags & (HTTPPOST_FILENAME|HTTPPOST_BUFFER|
1129                              HTTPPOST_CALLBACK)) {
1130         /* it should be noted that for the HTTPPOST_FILENAME and
1131            HTTPPOST_CALLBACK cases the ->showfilename struct member is always
1132            assigned at this point */
1133         char *filebasename=
1134           (!post->showfilename)?strippath(post->contents):NULL;
1135
1136         result = AddFormDataf(&form, &size,
1137                               "; filename=\"%s\"",
1138                               (post->showfilename?post->showfilename:
1139                                filebasename));
1140         if(filebasename)
1141           free(filebasename);
1142
1143         if(result)
1144           break;
1145       }
1146
1147       if(file->contenttype) {
1148         /* we have a specified type */
1149         result = AddFormDataf(&form, &size,
1150                               "\r\nContent-Type: %s",
1151                               file->contenttype);
1152         if(result)
1153           break;
1154       }
1155
1156       curList = file->contentheader;
1157       while( curList ) {
1158         /* Process the additional headers specified for this form */
1159         result = AddFormDataf( &form, &size, "\r\n%s", curList->data );
1160         if(result)
1161           break;
1162         curList = curList->next;
1163       }
1164       if(result) {
1165         Curl_formclean(&firstform);
1166         free(boundary);
1167         return result;
1168       }
1169
1170       result = AddFormDataf(&form, &size, "\r\n\r\n");
1171       if(result)
1172         break;
1173
1174       if((post->flags & HTTPPOST_FILENAME) ||
1175          (post->flags & HTTPPOST_READFILE)) {
1176         /* we should include the contents from the specified file */
1177         FILE *fileread;
1178
1179         fileread = strequal("-", file->contents)?
1180           stdin:fopen(file->contents, "rb"); /* binary read for win32  */
1181
1182         /*
1183          * VMS: This only allows for stream files on VMS.  Stream files are
1184          * OK, as are FIXED & VAR files WITHOUT implied CC For implied CC,
1185          * every record needs to have a \n appended & 1 added to SIZE
1186          */
1187
1188         if(fileread) {
1189           if(fileread != stdin) {
1190             /* close the file again */
1191             fclose(fileread);
1192             /* add the file name only - for later reading from this */
1193             result = AddFormData(&form, FORM_FILE, file->contents, 0, &size);
1194           }
1195           else {
1196             /* When uploading from stdin, we can't know the size of the file,
1197              * thus must read the full file as before. We *could* use chunked
1198              * transfer-encoding, but that only works for HTTP 1.1 and we
1199              * can't be sure we work with such a server.
1200              */
1201             size_t nread;
1202             char buffer[512];
1203             while((nread = fread(buffer, 1, sizeof(buffer), fileread)) != 0) {
1204               result = AddFormData(&form, FORM_CONTENT, buffer, nread, &size);
1205               if(result)
1206                 break;
1207             }
1208           }
1209         }
1210         else {
1211           if(data)
1212             failf(data, "couldn't open file \"%s\"\n", file->contents);
1213           *finalform = NULL;
1214           result = CURLE_READ_ERROR;
1215         }
1216       }
1217       else if(post->flags & HTTPPOST_BUFFER)
1218         /* include contents of buffer */
1219         result = AddFormData(&form, FORM_CONTENT, post->buffer,
1220                              post->bufferlength, &size);
1221       else if(post->flags & HTTPPOST_CALLBACK)
1222         /* the contents should be read with the callback and the size
1223            is set with the contentslength */
1224         result = AddFormData(&form, FORM_CALLBACK, post->userp,
1225                              post->contentslength, &size);
1226       else
1227         /* include the contents we got */
1228         result = AddFormData(&form, FORM_CONTENT, post->contents,
1229                              post->contentslength, &size);
1230
1231       file = file->more;
1232     } while(file && !result); /* for each specified file for this field */
1233
1234     if(result) {
1235       Curl_formclean(&firstform);
1236       free(boundary);
1237       return result;
1238     }
1239
1240     if(post->more) {
1241       /* this was a multiple-file inclusion, make a termination file
1242          boundary: */
1243       result = AddFormDataf(&form, &size,
1244                            "\r\n--%s--",
1245                            fileboundary);
1246       free(fileboundary);
1247       if(result)
1248         break;
1249     }
1250
1251   } while((post = post->next) != NULL); /* for each field */
1252   if(result) {
1253     Curl_formclean(&firstform);
1254     free(boundary);
1255     return result;
1256   }
1257
1258   /* end-boundary for everything */
1259   result = AddFormDataf(&form, &size,
1260                        "\r\n--%s--\r\n",
1261                        boundary);
1262   if(result) {
1263     Curl_formclean(&firstform);
1264     free(boundary);
1265     return result;
1266   }
1267
1268   *sizep = size;
1269
1270   free(boundary);
1271
1272   *finalform=firstform;
1273
1274   return result;
1275 }
1276
1277 /*
1278  * Curl_FormInit() inits the struct 'form' points to with the 'formdata'
1279  * and resets the 'sent' counter.
1280  */
1281 int Curl_FormInit(struct Form *form, struct FormData *formdata )
1282 {
1283   if(!formdata)
1284     return 1; /* error */
1285
1286   form->data = formdata;
1287   form->sent = 0;
1288   form->fp = NULL;
1289   form->fread_func = ZERO_NULL;
1290
1291   return 0;
1292 }
1293
1294 static size_t readfromfile(struct Form *form, char *buffer,
1295                            size_t size)
1296 {
1297   size_t nread;
1298   bool callback = (bool)(form->data->type == FORM_CALLBACK);
1299
1300   if(callback)
1301     nread = form->fread_func(buffer, 1, size, form->data->line);
1302   else {
1303     if(!form->fp) {
1304       /* this file hasn't yet been opened */
1305       form->fp = fopen(form->data->line, "rb"); /* b is for binary */
1306       if(!form->fp)
1307         return (size_t)-1; /* failure */
1308     }
1309     nread = fread(buffer, 1, size, form->fp);
1310   }
1311   if(!nread || nread > size) {
1312     /* this is the last chunk from the file, move on */
1313     if(!callback) {
1314       fclose(form->fp);
1315       form->fp = NULL;
1316     }
1317     form->data = form->data->next;
1318   }
1319
1320   return nread;
1321 }
1322
1323 /*
1324  * Curl_FormReader() is the fread() emulation function that will be used to
1325  * deliver the formdata to the transfer loop and then sent away to the peer.
1326  */
1327 size_t Curl_FormReader(char *buffer,
1328                        size_t size,
1329                        size_t nitems,
1330                        FILE *mydata)
1331 {
1332   struct Form *form;
1333   size_t wantedsize;
1334   size_t gotsize = 0;
1335
1336   form=(struct Form *)mydata;
1337
1338   wantedsize = size * nitems;
1339
1340   if(!form->data)
1341     return 0; /* nothing, error, empty */
1342
1343   if((form->data->type == FORM_FILE) ||
1344      (form->data->type == FORM_CALLBACK)) {
1345     gotsize = readfromfile(form, buffer, wantedsize);
1346
1347     if(gotsize)
1348       /* If positive or -1, return. If zero, continue! */
1349       return gotsize;
1350   }
1351   do {
1352
1353     if( (form->data->length - form->sent ) > wantedsize - gotsize) {
1354
1355       memcpy(buffer + gotsize , form->data->line + form->sent,
1356              wantedsize - gotsize);
1357
1358       form->sent += wantedsize-gotsize;
1359
1360       return wantedsize;
1361     }
1362
1363     memcpy(buffer+gotsize,
1364            form->data->line + form->sent,
1365            (form->data->length - form->sent) );
1366     gotsize += form->data->length - form->sent;
1367
1368     form->sent = 0;
1369
1370     form->data = form->data->next; /* advance */
1371
1372   } while(form->data && (form->data->type < FORM_CALLBACK));
1373   /* If we got an empty line and we have more data, we proceed to the next
1374      line immediately to avoid returning zero before we've reached the end. */
1375
1376   return gotsize;
1377 }
1378
1379 /*
1380  * Curl_formpostheader() returns the first line of the formpost, the
1381  * request-header part (which is not part of the request-body like the rest of
1382  * the post).
1383  */
1384 char *Curl_formpostheader(void *formp, size_t *len)
1385 {
1386   char *header;
1387   struct Form *form=(struct Form *)formp;
1388
1389   if(!form->data)
1390     return 0; /* nothing, ERROR! */
1391
1392   header = form->data->line;
1393   *len = form->data->length;
1394
1395   form->data = form->data->next; /* advance */
1396
1397   return header;
1398 }
1399
1400 #else  /* CURL_DISABLE_HTTP */
1401 CURLFORMcode curl_formadd(struct curl_httppost **httppost,
1402                           struct curl_httppost **last_post,
1403                           ...)
1404 {
1405   (void)httppost;
1406   (void)last_post;
1407   return CURL_FORMADD_DISABLED;
1408 }
1409
1410 int curl_formget(struct curl_httppost *form, void *arg,
1411                  curl_formget_callback append)
1412 {
1413   (void) form;
1414   (void) arg;
1415   (void) append;
1416   return CURL_FORMADD_DISABLED;
1417 }
1418
1419 void curl_formfree(struct curl_httppost *form)
1420 {
1421   (void)form;
1422   /* does nothing HTTP is disabled */
1423 }
1424
1425 #endif  /* CURL_DISABLE_HTTP */
1426
1427 #if !defined(CURL_DISABLE_HTTP) || defined(USE_SSLEAY)
1428
1429 /*
1430  * Curl_FormBoundary() creates a suitable boundary string and returns an
1431  * allocated one. This is also used by SSL-code so it must be present even
1432  * if HTTP is disabled!
1433  */
1434 char *Curl_FormBoundary(void)
1435 {
1436   char *retstring;
1437   size_t i;
1438
1439   static const char table16[]="0123456789abcdef";
1440
1441   retstring = malloc(BOUNDARY_LENGTH+1);
1442
1443   if(!retstring)
1444     return NULL; /* failed */
1445
1446   strcpy(retstring, "----------------------------");
1447
1448   for(i=strlen(retstring); i<BOUNDARY_LENGTH; i++)
1449     retstring[i] = table16[Curl_rand()%16];
1450
1451   /* 28 dashes and 12 hexadecimal digits makes 12^16 (184884258895036416)
1452      combinations */
1453   retstring[BOUNDARY_LENGTH]=0; /* zero terminate */
1454
1455   return retstring;
1456 }
1457
1458 #endif  /* !defined(CURL_DISABLE_HTTP) || defined(USE_SSLEAY) */