## NAME

         curl_formadd  -  add  a section to a multipart/formdata HTTP
         POST

## SYNOPSIS

         #include <curl/curl.h>

         int curl_formadd(struct HttpPost ** firstitem, struct  Http
         Post ** lastitem, ...);

## DESCRIPTION

         curl_formadd()  is  used  to append sections when building a
         multipart/formdata  HTTP  POST  (sometimes  refered  to   as
         rfc1867-style  posts).  Append  one  section at a time until
         you've added all the sections you want included and then you
         pass the firstitem pointer as parameter to CURLOPT_HTTPPOST.
         lastitem is set after each call and on repeated  invokes  it
         should  be left as set to allow repeated invokes to find the
         end of the list faster.

         After the lastitem pointer follow the  real  arguments.  (If
         the following description confuses you, jump directly to the
         examples):

         CURLFORM_COPYNAME or CURLFORM_PTRNAME followed by  a  string
         is  used for the name of the section. Optionally one may use
         CURLFORM_NAMELENGTH  to  specify  the  length  of  the  name
         (allowing null characters within the name). All options that
         use the word COPY in their names copy  the  given  contents,
         while  the ones with PTR in their names simply points to the
         (static) data you must make sure remain until curl no longer
         needs it.

         The four options for providing values are: CURLFORM_COPYCON
         TENTS,   CURLFORM_PTRCONTENTS,   CURLFORM_FILE,   or   CURL
         FORM_FILECONTENT followed by a char or void pointer (allowed
         for PTRCONTENTS).

         CURLFORM_FILECONTENT does a normal post like  CURLFORM_COPY
         CONTENTS  but  the  actual  value  is read from the filename
         given as a string.

         Other arguments may  be  CURLFORM_CONTENTTYPE  if  the  user
         wishes  to  specify  one  (for  FILE if no type is given the
         library tries to provide the correct one;  for  CONTENTS  no
         Content-Type is sent in this case).

         For  CURLFORM_PTRCONTENTS  or CURLFORM_COPYNAME the user may
         also add CURLFORM_CONTENTSLENGTH followed by the length as a
         long  (if not given the library will use strlen to determine
         the length).

         For CURLFORM_FILE the user may send multiple  files  in  one
         section  by  providing multiple CURLFORM_FILE arguments each
         followed by the filename (and each FILE is allowed to have a
         CONTENTTYPE).

         Another  possibility to send single or multiple files in one
         section  is  to  use  CURLFORM_ARRAY  that  gets  a   struct
         curl_forms  array  pointer as its value. Each structure ele
         ment has a  CURLformoption  and  a  char  pointer.  For  the
         options  only CURLFORM_FILE, CURLFORM_CONTENTTYPE, and CURL
         FORM_END (that is used to determine the end of the array and
         thus  must be the option of the last and no other element of
         the curl_forms array) are allowed. The effect of this param
         eter  is  the  same as giving multiple CURLFORM_FILE options
         possibly with  CURLFORM_CONTENTTYPE  after  or  before  each
         CURLFORM_FILE option.

         Should  you  need to specify extra headers for the form POST
         section, use CURLFORM_CONTENTHEADER. This takes a curl_slist
         prepared  in  the  usual  way  using  curl_slist_append  and
         appends the list of headers to those Curl automatically gen
         erates for CURLFORM_CONTENTTYPE and the content disposition.
         The list must exist while the POST occurs, if  you  free  it
         before the post completes you may experience problems.

         The  last  argument  in  such  an array must always be CURL
         FORM_END.

         The pointers *firstitem and *lastitem should both be  point
         ing  to  NULL  in the first call to this function. All list-
         data will be allocated by the function itself. You must call
         curl_formfree  after the form post has been done to free the
         resources again.

         This function will copy  all  input  data  except  the  data
         pointed to by the arguments after CURLFORM_PTRNAME and CURL
         FORM_PTRCONTENTS and keep its own version  of  it  allocated
         until you call curl_formfree. When you've passed the pointer
         to curl_easy_setopt, you must not free the list until  after
         you've  called curl_easy_cleanup for the curl handle. If you
         provide a pointer as an arguments after CURLFORM_PTRNAME  or
         CURLFORM_PTRCONTENTS  you must ensure that the pointer stays
         valid until you call curl_form_free and curl_easy_cleanup.

         See example below.

## RETURN VALUE

         Returns non-zero if an error occurs.

## EXAMPLE

          struct HttpPost* post = NULL;
          struct HttpPost* last = NULL;
          char namebuffer[] = "name buffer";
          long namelength = strlen(namebuffer);
          char buffer[] = "test buffer";
          char htmlbuffer[] = "<HTML>test buffer</HTML>";
          long htmlbufferlength = strlen(htmlbuffer);
          struct curl_forms forms[3];
          char file1[] = "my-face.jpg";
          char file2[] = "your-face.jpg";
          /* add null character into htmlbuffer, to demonstrate that
             transfers of buffers containing null characters actually work
          */
          htmlbuffer[8] = '\0';

          /* Add simple name/content section */
          curl_formadd(&post, &last, CURLFORM_COPYNAME, "name",
                       CURLFORM_COPYCONTENTS, "content", CURLFORM_END);

          /* Add simple name/content/contenttype section */
          curl_formadd(&post, &last, CURLFORM_COPYNAME, "htmlcode",
                       CURLFORM_COPYCONTENTS, "<HTML></HTML>",
                       CURLFORM_CONTENTTYPE, "text/html", CURLFORM_END);

          /* Add name/ptrcontent section */
          curl_formadd(&post, &last, CURLFORM_COPYNAME, "name_for_ptrcontent",
                       CURLFORM_PTRCONTENTS, buffer, CURLFORM_END);

          /* Add ptrname/ptrcontent section */
          curl_formadd(&post, &last, CURLFORM_PTRNAME, namebuffer,
                    CURLFORM_PTRCONTENTS, buffer, CURLFORM_NAMELENGTH,
                    namelength, CURLFORM_END);

          /* Add name/ptrcontent/contenttype section */
          curl_formadd(&post, &last, CURLFORM_COPYNAME, "html_code_with_hole",
                       CURLFORM_PTRCONTENTS, htmlbuffer,
                       CURLFORM_CONTENTSLENGTH, htmlbufferlength,
                       CURLFORM_CONTENTTYPE, "text/html", CURLFORM_END);

          /* Add simple file section */
          curl_formadd(&post, &last, CURLFORM_COPYNAME, "picture",
                       CURLFORM_FILE, "my-face.jpg", CURLFORM_END);

          /* Add file/contenttype section */
          curl_formadd(&post, &last, CURLFORM_COPYNAME, "picture",
                       CURLFORM_FILE, "my-face.jpg",
                       CURLFORM_CONTENTTYPE, "image/jpeg", CURLFORM_END);

          /* Add two file section */
          curl_formadd(&post, &last, CURLFORM_COPYNAME, "pictures",
                       CURLFORM_FILE, "my-face.jpg",
                       CURLFORM_FILE, "your-face.jpg", CURLFORM_END);

          /* Add two file section using CURLFORM_ARRAY */
          forms[0].option = CURLFORM_FILE;
          forms[0].value  = file1;
          forms[1].option = CURLFORM_FILE;
          forms[1].value  = file2;
          forms[2].option  = CURLFORM_END;

          /* no option needed for the end marker */
          curl_formadd(&post, &last, CURLFORM_COPYNAME, "pictures",
                       CURLFORM_ARRAY, forms, CURLFORM_END);
          /* Add the content of a file as a normal post text value */
          curl_formadd(&post, &last, CURLFORM_COPYNAME, "filecontent",
                       CURLFORM_FILECONTENT, ".bashrc", CURLFORM_END);
          /* Set the form info */
          curl_easy_setopt(curl, CURLOPT_HTTPPOST, post);

## SEE ALSO

         curl_easy_setopt(3),     curl_formparse(3)     [deprecated],
         curl_formfree(3)

## BUGS

         Surely there are some, you tell me!