/*****************************************************************************
 *                                  _   _ ____  _
 *  Project                     ___| | | |  _ \| |
 *                             / __| | | | |_) | |
 *                            | (__| |_| |  _ <| |___
 *                             \___|\___/|_| \_\_____|
 *
 * $Id: multi-post.c,v 1.1 2002/05/06 13:38:28 bagder Exp $
 *
 * This is an example application source code using the multi interface
 * to do a multipart formpost without "blocking".
 */
#include <stdio.h>
#include <string.h>
#include <sys/time.h>

#include <curl/curl.h>

int main( int argc, char *argv[] ) {
	CURL *curl;
	CURLcode res;

	CURLM *multi_handle;
	int still_running;

	struct HttpPost *formpost = NULL;
	struct HttpPost *lastptr = NULL;
	struct curl_slist *headerlist = NULL;
	char buf[] = "Expect:";

	/* Fill in the file upload field */
	curl_formadd( &formpost,
				  &lastptr,
				  CURLFORM_COPYNAME, "sendfile",
				  CURLFORM_FILE, "postit2.c",
				  CURLFORM_END );

	/* Fill in the filename field */
	curl_formadd( &formpost,
				  &lastptr,
				  CURLFORM_COPYNAME, "filename",
				  CURLFORM_COPYCONTENTS, "postit2.c",
				  CURLFORM_END );


	/* Fill in the submit field too, even if this is rarely needed */
	curl_formadd( &formpost,
				  &lastptr,
				  CURLFORM_COPYNAME, "submit",
				  CURLFORM_COPYCONTENTS, "send",
				  CURLFORM_END );

	curl = curl_easy_init();
	multi_handle = curl_multi_init();

	/* initalize custom header list (stating that Expect: 100-continue is not
	   wanted */
	headerlist = curl_slist_append( headerlist, buf );
	if ( curl && multi_handle ) {
		int perform = 0;

		/* what URL that receives this POST */
		curl_easy_setopt( curl, CURLOPT_URL,
						  "http://www.fillinyoururl.com/upload.cgi" );
		curl_easy_setopt( curl, CURLOPT_VERBOSE, 1 );

		curl_easy_setopt( curl, CURLOPT_HTTPHEADER, headerlist );
		curl_easy_setopt( curl, CURLOPT_HTTPPOST, formpost );

		curl_multi_add_handle( multi_handle, curl );

		while ( CURLM_CALL_MULTI_PERFORM ==
				curl_multi_perform( multi_handle, &still_running ) ) ;

		while ( still_running ) {
			struct timeval timeout;
			int rc; /* select() return code */

			fd_set fdread;
			fd_set fdwrite;
			fd_set fdexcep;
			int maxfd;

			FD_ZERO( &fdread );
			FD_ZERO( &fdwrite );
			FD_ZERO( &fdexcep );

			/* set a suitable timeout to play around with */
			timeout.tv_sec = 1;
			timeout.tv_usec = 0;

			/* get file descriptors from the transfers */
			curl_multi_fdset( multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd );

			rc = select( maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout );

			switch ( rc ) {
			case - 1:
				/* select error */
				break;
			case 0:
				printf( "timeout!\n" );
			default:
				/* timeout or readable/writable sockets */
				printf( "perform!\n" );
				while ( CURLM_CALL_MULTI_PERFORM ==
						curl_multi_perform( multi_handle, &still_running ) ) ;
				printf( "running: %d!\n", still_running );
				break;
			}
		}

		curl_multi_cleanup( multi_handle );

		/* always cleanup */
		curl_easy_cleanup( curl );

		/* then cleanup the formpost chain */
		curl_formfree( formpost );

		/* free slist */
		curl_slist_free_all( headerlist );
	}
	return 0;
}
