tizen 2.4 release
[external/curl.git] / lib / easy.c
1 /***************************************************************************
2  *                                  _   _ ____  _
3  *  Project                     ___| | | |  _ \| |
4  *                             / __| | | | |_) | |
5  *                            | (__| |_| |  _ <| |___
6  *                             \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) 1998 - 2014, 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 "curl_setup.h"
24
25 /*
26  * See comment in curl_memory.h for the explanation of this sanity check.
27  */
28
29 #ifdef CURLX_NO_MEMORY_CALLBACKS
30 #error "libcurl shall not ever be built with CURLX_NO_MEMORY_CALLBACKS defined"
31 #endif
32
33 #ifdef HAVE_NETINET_IN_H
34 #include <netinet/in.h>
35 #endif
36 #ifdef HAVE_NETDB_H
37 #include <netdb.h>
38 #endif
39 #ifdef HAVE_ARPA_INET_H
40 #include <arpa/inet.h>
41 #endif
42 #ifdef HAVE_NET_IF_H
43 #include <net/if.h>
44 #endif
45 #ifdef HAVE_SYS_IOCTL_H
46 #include <sys/ioctl.h>
47 #endif
48
49 #ifdef HAVE_SYS_PARAM_H
50 #include <sys/param.h>
51 #endif
52
53 #include "strequal.h"
54 #include "urldata.h"
55 #include <curl/curl.h>
56 #include "transfer.h"
57 #include "vtls/vtls.h"
58 #include "url.h"
59 #include "getinfo.h"
60 #include "hostip.h"
61 #include "share.h"
62 #include "strdup.h"
63 #include "curl_memory.h"
64 #include "progress.h"
65 #include "easyif.h"
66 #include "select.h"
67 #include "sendf.h" /* for failf function prototype */
68 #include "curl_ntlm.h"
69 #include "connect.h" /* for Curl_getconnectinfo */
70 #include "slist.h"
71 #include "amigaos.h"
72 #include "non-ascii.h"
73 #include "warnless.h"
74 #include "conncache.h"
75 #include "multiif.h"
76 #include "sigpipe.h"
77 #include "ssh.h"
78
79 #define _MPRINTF_REPLACE /* use our functions only */
80 #include <curl/mprintf.h>
81
82 /* The last #include file should be: */
83 #include "memdebug.h"
84
85 /* win32_cleanup() is for win32 socket cleanup functionality, the opposite
86    of win32_init() */
87 static void win32_cleanup(void)
88 {
89 #ifdef USE_WINSOCK
90   WSACleanup();
91 #endif
92 #ifdef USE_WINDOWS_SSPI
93   Curl_sspi_global_cleanup();
94 #endif
95 }
96
97 /* win32_init() performs win32 socket initialization to properly setup the
98    stack to allow networking */
99 static CURLcode win32_init(void)
100 {
101 #ifdef USE_WINSOCK
102   WORD wVersionRequested;
103   WSADATA wsaData;
104   int res;
105
106 #if defined(ENABLE_IPV6) && (USE_WINSOCK < 2)
107   Error IPV6_requires_winsock2
108 #endif
109
110   wVersionRequested = MAKEWORD(USE_WINSOCK, USE_WINSOCK);
111
112   res = WSAStartup(wVersionRequested, &wsaData);
113
114   if(res != 0)
115     /* Tell the user that we couldn't find a useable */
116     /* winsock.dll.     */
117     return CURLE_FAILED_INIT;
118
119   /* Confirm that the Windows Sockets DLL supports what we need.*/
120   /* Note that if the DLL supports versions greater */
121   /* than wVersionRequested, it will still return */
122   /* wVersionRequested in wVersion. wHighVersion contains the */
123   /* highest supported version. */
124
125   if(LOBYTE( wsaData.wVersion ) != LOBYTE(wVersionRequested) ||
126      HIBYTE( wsaData.wVersion ) != HIBYTE(wVersionRequested) ) {
127     /* Tell the user that we couldn't find a useable */
128
129     /* winsock.dll. */
130     WSACleanup();
131     return CURLE_FAILED_INIT;
132   }
133   /* The Windows Sockets DLL is acceptable. Proceed. */
134 #elif defined(USE_LWIPSOCK)
135   lwip_init();
136 #endif
137
138 #ifdef USE_WINDOWS_SSPI
139   {
140     CURLcode result = Curl_sspi_global_init();
141     if(result)
142       return result;
143   }
144 #endif
145
146   return CURLE_OK;
147 }
148
149 #ifdef USE_LIBIDN
150 /*
151  * Initialise use of IDNA library.
152  * It falls back to ASCII if $CHARSET isn't defined. This doesn't work for
153  * idna_to_ascii_lz().
154  */
155 static void idna_init (void)
156 {
157 #ifdef WIN32
158   char buf[60];
159   UINT cp = GetACP();
160
161   if(!getenv("CHARSET") && cp > 0) {
162     snprintf(buf, sizeof(buf), "CHARSET=cp%u", cp);
163     putenv(buf);
164   }
165 #else
166   /* to do? */
167 #endif
168 }
169 #endif  /* USE_LIBIDN */
170
171 /* true globals -- for curl_global_init() and curl_global_cleanup() */
172 static unsigned int  initialized;
173 static long          init_flags;
174
175 /*
176  * strdup (and other memory functions) is redefined in complicated
177  * ways, but at this point it must be defined as the system-supplied strdup
178  * so the callback pointer is initialized correctly.
179  */
180 #if defined(_WIN32_WCE)
181 #define system_strdup _strdup
182 #elif !defined(HAVE_STRDUP)
183 #define system_strdup curlx_strdup
184 #else
185 #define system_strdup strdup
186 #endif
187
188 #if defined(_MSC_VER) && defined(_DLL) && !defined(__POCC__)
189 #  pragma warning(disable:4232) /* MSVC extension, dllimport identity */
190 #endif
191
192 #ifndef __SYMBIAN32__
193 /*
194  * If a memory-using function (like curl_getenv) is used before
195  * curl_global_init() is called, we need to have these pointers set already.
196  */
197 curl_malloc_callback Curl_cmalloc = (curl_malloc_callback)malloc;
198 curl_free_callback Curl_cfree = (curl_free_callback)free;
199 curl_realloc_callback Curl_crealloc = (curl_realloc_callback)realloc;
200 curl_strdup_callback Curl_cstrdup = (curl_strdup_callback)system_strdup;
201 curl_calloc_callback Curl_ccalloc = (curl_calloc_callback)calloc;
202 #if defined(WIN32) && defined(UNICODE)
203 curl_wcsdup_callback Curl_cwcsdup = (curl_wcsdup_callback)_wcsdup;
204 #endif
205 #else
206 /*
207  * Symbian OS doesn't support initialization to code in writeable static data.
208  * Initialization will occur in the curl_global_init() call.
209  */
210 curl_malloc_callback Curl_cmalloc;
211 curl_free_callback Curl_cfree;
212 curl_realloc_callback Curl_crealloc;
213 curl_strdup_callback Curl_cstrdup;
214 curl_calloc_callback Curl_ccalloc;
215 #endif
216
217 #if defined(_MSC_VER) && defined(_DLL) && !defined(__POCC__)
218 #  pragma warning(default:4232) /* MSVC extension, dllimport identity */
219 #endif
220
221 /**
222  * curl_global_init() globally initializes cURL given a bitwise set of the
223  * different features of what to initialize.
224  */
225 CURLcode curl_global_init(long flags)
226 {
227   if(initialized++)
228     return CURLE_OK;
229
230   /* Setup the default memory functions here (again) */
231   Curl_cmalloc = (curl_malloc_callback)malloc;
232   Curl_cfree = (curl_free_callback)free;
233   Curl_crealloc = (curl_realloc_callback)realloc;
234   Curl_cstrdup = (curl_strdup_callback)system_strdup;
235   Curl_ccalloc = (curl_calloc_callback)calloc;
236 #if defined(WIN32) && defined(UNICODE)
237   Curl_cwcsdup = (curl_wcsdup_callback)_wcsdup;
238 #endif
239
240   if(flags & CURL_GLOBAL_SSL)
241     if(!Curl_ssl_init()) {
242       DEBUGF(fprintf(stderr, "Error: Curl_ssl_init failed\n"));
243       return CURLE_FAILED_INIT;
244     }
245
246   if(flags & CURL_GLOBAL_WIN32)
247     if(win32_init()) {
248       DEBUGF(fprintf(stderr, "Error: win32_init failed\n"));
249       return CURLE_FAILED_INIT;
250     }
251
252 #ifdef __AMIGA__
253   if(!Curl_amiga_init()) {
254     DEBUGF(fprintf(stderr, "Error: Curl_amiga_init failed\n"));
255     return CURLE_FAILED_INIT;
256   }
257 #endif
258
259 #ifdef NETWARE
260   if(netware_init()) {
261     DEBUGF(fprintf(stderr, "Warning: LONG namespace not available\n"));
262   }
263 #endif
264
265 #ifdef USE_LIBIDN
266   idna_init();
267 #endif
268
269   if(Curl_resolver_global_init()) {
270     DEBUGF(fprintf(stderr, "Error: resolver_global_init failed\n"));
271     return CURLE_FAILED_INIT;
272   }
273
274 #if defined(USE_LIBSSH2) && defined(HAVE_LIBSSH2_INIT)
275   if(libssh2_init(0)) {
276     DEBUGF(fprintf(stderr, "Error: libssh2_init failed\n"));
277     return CURLE_FAILED_INIT;
278   }
279 #endif
280
281   if(flags & CURL_GLOBAL_ACK_EINTR)
282     Curl_ack_eintr = 1;
283
284   init_flags  = flags;
285
286   return CURLE_OK;
287 }
288
289 /*
290  * curl_global_init_mem() globally initializes cURL and also registers the
291  * user provided callback routines.
292  */
293 CURLcode curl_global_init_mem(long flags, curl_malloc_callback m,
294                               curl_free_callback f, curl_realloc_callback r,
295                               curl_strdup_callback s, curl_calloc_callback c)
296 {
297   CURLcode result = CURLE_OK;
298
299   /* Invalid input, return immediately */
300   if(!m || !f || !r || !s || !c)
301     return CURLE_FAILED_INIT;
302
303   if(initialized) {
304     /* Already initialized, don't do it again, but bump the variable anyway to
305        work like curl_global_init() and require the same amount of cleanup
306        calls. */
307     initialized++;
308     return CURLE_OK;
309   }
310
311   /* Call the actual init function first */
312   result = curl_global_init(flags);
313   if(!result) {
314     Curl_cmalloc = m;
315     Curl_cfree = f;
316     Curl_cstrdup = s;
317     Curl_crealloc = r;
318     Curl_ccalloc = c;
319   }
320
321   return result;
322 }
323
324 /**
325  * curl_global_cleanup() globally cleanups cURL, uses the value of
326  * "init_flags" to determine what needs to be cleaned up and what doesn't.
327  */
328 void curl_global_cleanup(void)
329 {
330   if(!initialized)
331     return;
332
333   if(--initialized)
334     return;
335
336   Curl_global_host_cache_dtor();
337
338   if(init_flags & CURL_GLOBAL_SSL)
339     Curl_ssl_cleanup();
340
341   Curl_resolver_global_cleanup();
342
343   if(init_flags & CURL_GLOBAL_WIN32)
344     win32_cleanup();
345
346   Curl_amiga_cleanup();
347
348 #if defined(USE_LIBSSH2) && defined(HAVE_LIBSSH2_EXIT)
349   (void)libssh2_exit();
350 #endif
351
352   init_flags  = 0;
353 }
354
355 /*
356  * curl_easy_init() is the external interface to alloc, setup and init an
357  * easy handle that is returned. If anything goes wrong, NULL is returned.
358  */
359 CURL *curl_easy_init(void)
360 {
361   CURLcode result;
362   struct SessionHandle *data;
363
364   /* Make sure we inited the global SSL stuff */
365   if(!initialized) {
366     result = curl_global_init(CURL_GLOBAL_DEFAULT);
367     if(result) {
368       /* something in the global init failed, return nothing */
369       DEBUGF(fprintf(stderr, "Error: curl_global_init failed\n"));
370       return NULL;
371     }
372   }
373
374   /* We use curl_open() with undefined URL so far */
375   result = Curl_open(&data);
376   if(result) {
377     DEBUGF(fprintf(stderr, "Error: Curl_open failed\n"));
378     return NULL;
379   }
380
381   return data;
382 }
383
384 /*
385  * curl_easy_setopt() is the external interface for setting options on an
386  * easy handle.
387  */
388
389 #undef curl_easy_setopt
390 CURLcode curl_easy_setopt(CURL *curl, CURLoption tag, ...)
391 {
392   va_list arg;
393   struct SessionHandle *data = curl;
394   CURLcode result;
395
396   if(!curl)
397     return CURLE_BAD_FUNCTION_ARGUMENT;
398
399   va_start(arg, tag);
400
401   result = Curl_setopt(data, tag, arg);
402
403   va_end(arg);
404   return result;
405 }
406
407 #ifdef CURLDEBUG
408
409 struct socketmonitor {
410   struct socketmonitor *next; /* the next node in the list or NULL */
411   struct pollfd socket; /* socket info of what to monitor */
412 };
413
414 struct events {
415   long ms;              /* timeout, run the timeout function when reached */
416   bool msbump;          /* set TRUE when timeout is set by callback */
417   int num_sockets;      /* number of nodes in the monitor list */
418   struct socketmonitor *list; /* list of sockets to monitor */
419   int running_handles;  /* store the returned number */
420 };
421
422 /* events_timer
423  *
424  * Callback that gets called with a new value when the timeout should be
425  * updated.
426  */
427
428 static int events_timer(CURLM *multi,    /* multi handle */
429                         long timeout_ms, /* see above */
430                         void *userp)    /* private callback pointer */
431 {
432   struct events *ev = userp;
433   (void)multi;
434   if(timeout_ms == -1)
435     /* timeout removed */
436     timeout_ms = 0;
437   else if(timeout_ms == 0)
438     /* timeout is already reached! */
439     timeout_ms = 1; /* trigger asap */
440
441   ev->ms = timeout_ms;
442   ev->msbump = TRUE;
443   return 0;
444 }
445
446
447 /* poll2cselect
448  *
449  * convert from poll() bit definitions to libcurl's CURL_CSELECT_* ones
450  */
451 static int poll2cselect(int pollmask)
452 {
453   int omask=0;
454   if(pollmask & POLLIN)
455     omask |= CURL_CSELECT_IN;
456   if(pollmask & POLLOUT)
457     omask |= CURL_CSELECT_OUT;
458   if(pollmask & POLLERR)
459     omask |= CURL_CSELECT_ERR;
460   return omask;
461 }
462
463
464 /* socketcb2poll
465  *
466  * convert from libcurl' CURL_POLL_* bit definitions to poll()'s
467  */
468 static short socketcb2poll(int pollmask)
469 {
470   short omask=0;
471   if(pollmask & CURL_POLL_IN)
472     omask |= POLLIN;
473   if(pollmask & CURL_POLL_OUT)
474     omask |= POLLOUT;
475   return omask;
476 }
477
478 /* events_socket
479  *
480  * Callback that gets called with information about socket activity to
481  * monitor.
482  */
483 static int events_socket(CURL *easy,      /* easy handle */
484                          curl_socket_t s, /* socket */
485                          int what,        /* see above */
486                          void *userp,     /* private callback
487                                              pointer */
488                          void *socketp)   /* private socket
489                                              pointer */
490 {
491   struct events *ev = userp;
492   struct socketmonitor *m;
493   struct socketmonitor *prev=NULL;
494
495 #if defined(CURL_DISABLE_VERBOSE_STRINGS)
496   (void) easy;
497 #endif
498   (void)socketp;
499
500   m = ev->list;
501   while(m) {
502     if(m->socket.fd == s) {
503
504       if(what == CURL_POLL_REMOVE) {
505         struct socketmonitor *nxt = m->next;
506         /* remove this node from the list of monitored sockets */
507         if(prev)
508           prev->next = nxt;
509         else
510           ev->list = nxt;
511         free(m);
512         m = nxt;
513         infof(easy, "socket cb: socket %d REMOVED\n", s);
514       }
515       else {
516         /* The socket 's' is already being monitored, update the activity
517            mask. Convert from libcurl bitmask to the poll one. */
518         m->socket.events = socketcb2poll(what);
519         infof(easy, "socket cb: socket %d UPDATED as %s%s\n", s,
520               what&CURL_POLL_IN?"IN":"",
521               what&CURL_POLL_OUT?"OUT":"");
522       }
523       break;
524     }
525     prev = m;
526     m = m->next; /* move to next node */
527   }
528   if(!m) {
529     if(what == CURL_POLL_REMOVE) {
530       /* this happens a bit too often, libcurl fix perhaps? */
531       /* fprintf(stderr,
532          "%s: socket %d asked to be REMOVED but not present!\n",
533                  __func__, s); */
534     }
535     else {
536       m = malloc(sizeof(struct socketmonitor));
537       m->next = ev->list;
538       m->socket.fd = s;
539       m->socket.events = socketcb2poll(what);
540       m->socket.revents = 0;
541       ev->list = m;
542       infof(easy, "socket cb: socket %d ADDED as %s%s\n", s,
543             what&CURL_POLL_IN?"IN":"",
544             what&CURL_POLL_OUT?"OUT":"");
545     }
546   }
547
548   return 0;
549 }
550
551
552 /*
553  * events_setup()
554  *
555  * Do the multi handle setups that only event-based transfers need.
556  */
557 static void events_setup(CURLM *multi, struct events *ev)
558 {
559   /* timer callback */
560   curl_multi_setopt(multi, CURLMOPT_TIMERFUNCTION, events_timer);
561   curl_multi_setopt(multi, CURLMOPT_TIMERDATA, ev);
562
563   /* socket callback */
564   curl_multi_setopt(multi, CURLMOPT_SOCKETFUNCTION, events_socket);
565   curl_multi_setopt(multi, CURLMOPT_SOCKETDATA, ev);
566 }
567
568
569 /* wait_or_timeout()
570  *
571  * waits for activity on any of the given sockets, or the timeout to trigger.
572  */
573
574 static CURLcode wait_or_timeout(struct Curl_multi *multi, struct events *ev)
575 {
576   bool done = FALSE;
577   CURLMcode mcode;
578   CURLcode result = CURLE_OK;
579
580   while(!done) {
581     CURLMsg *msg;
582     struct socketmonitor *m;
583     struct pollfd *f;
584     struct pollfd fds[4];
585     int numfds=0;
586     int pollrc;
587     int i;
588     struct timeval before;
589     struct timeval after;
590
591     /* populate the fds[] array */
592     for(m = ev->list, f=&fds[0]; m; m = m->next) {
593       f->fd = m->socket.fd;
594       f->events = m->socket.events;
595       f->revents = 0;
596       /* fprintf(stderr, "poll() %d check socket %d\n", numfds, f->fd); */
597       f++;
598       numfds++;
599     }
600
601     /* get the time stamp to use to figure out how long poll takes */
602     before = curlx_tvnow();
603
604     /* wait for activity or timeout */
605     pollrc = Curl_poll(fds, numfds, (int)ev->ms);
606
607     after = curlx_tvnow();
608
609     ev->msbump = FALSE; /* reset here */
610
611     if(0 == pollrc) {
612       /* timeout! */
613       ev->ms = 0;
614       /* fprintf(stderr, "call curl_multi_socket_action( TIMEOUT )\n"); */
615       mcode = curl_multi_socket_action(multi, CURL_SOCKET_TIMEOUT, 0,
616                                        &ev->running_handles);
617     }
618     else if(pollrc > 0) {
619       /* loop over the monitored sockets to see which ones had activity */
620       for(i = 0; i< numfds; i++) {
621         if(fds[i].revents) {
622           /* socket activity, tell libcurl */
623           int act = poll2cselect(fds[i].revents); /* convert */
624           infof(multi->easyp, "call curl_multi_socket_action( socket %d )\n",
625                 fds[i].fd);
626           mcode = curl_multi_socket_action(multi, fds[i].fd, act,
627                                            &ev->running_handles);
628         }
629       }
630
631       if(!ev->msbump)
632         /* If nothing updated the timeout, we decrease it by the spent time.
633          * If it was updated, it has the new timeout time stored already.
634          */
635         ev->ms += curlx_tvdiff(after, before);
636
637     }
638     else
639       return CURLE_RECV_ERROR;
640
641     if(mcode)
642       return CURLE_URL_MALFORMAT; /* TODO: return a proper error! */
643
644     /* we don't really care about the "msgs_in_queue" value returned in the
645        second argument */
646     msg = curl_multi_info_read(multi, &pollrc);
647     if(msg) {
648       result = msg->data.result;
649       done = TRUE;
650     }
651   }
652
653   return result;
654 }
655
656
657 /* easy_events()
658  *
659  * Runs a transfer in a blocking manner using the events-based API
660  */
661 static CURLcode easy_events(CURLM *multi)
662 {
663   struct events evs= {2, FALSE, 0, NULL, 0};
664
665   /* if running event-based, do some further multi inits */
666   events_setup(multi, &evs);
667
668   return wait_or_timeout(multi, &evs);
669 }
670 #else /* CURLDEBUG */
671 /* when not built with debug, this function doesn't exist */
672 #define easy_events(x) CURLE_NOT_BUILT_IN
673 #endif
674
675 static CURLcode easy_transfer(CURLM *multi)
676 {
677   bool done = FALSE;
678   CURLMcode mcode = CURLM_OK;
679   CURLcode result = CURLE_OK;
680   struct timeval before;
681   int without_fds = 0;  /* count number of consecutive returns from
682                            curl_multi_wait() without any filedescriptors */
683
684   while(!done && !mcode) {
685     int still_running = 0;
686     int ret;
687
688     before = curlx_tvnow();
689     mcode = curl_multi_wait(multi, NULL, 0, 1000, &ret);
690
691     if(mcode == CURLM_OK) {
692       if(ret == -1) {
693         /* poll() failed not on EINTR, indicate a network problem */
694         result = CURLE_RECV_ERROR;
695         break;
696       }
697       else if(ret == 0) {
698         struct timeval after = curlx_tvnow();
699         /* If it returns without any filedescriptor instantly, we need to
700            avoid busy-looping during periods where it has nothing particular
701            to wait for */
702         if(curlx_tvdiff(after, before) <= 10) {
703           without_fds++;
704           if(without_fds > 2) {
705             int sleep_ms = without_fds < 10 ? (1 << (without_fds-1)): 1000;
706             Curl_wait_ms(sleep_ms);
707           }
708         }
709         else
710           /* it wasn't "instant", restart counter */
711           without_fds = 0;
712       }
713       else
714         /* got file descriptor, restart counter */
715         without_fds = 0;
716
717       mcode = curl_multi_perform(multi, &still_running);
718     }
719
720     /* only read 'still_running' if curl_multi_perform() return OK */
721     if((mcode == CURLM_OK) && !still_running) {
722       int rc;
723       CURLMsg *msg = curl_multi_info_read(multi, &rc);
724       if(msg) {
725         result = msg->data.result;
726         done = TRUE;
727       }
728     }
729   }
730
731   /* Make sure to return some kind of error if there was a multi problem */
732   if(mcode) {
733     return (mcode == CURLM_OUT_OF_MEMORY) ? CURLE_OUT_OF_MEMORY :
734             /* The other multi errors should never happen, so return
735                something suitably generic */
736             CURLE_BAD_FUNCTION_ARGUMENT;
737   }
738
739   return result;
740 }
741
742
743 /*
744  * easy_perform() is the external interface that performs a blocking
745  * transfer as previously setup.
746  *
747  * CONCEPT: This function creates a multi handle, adds the easy handle to it,
748  * runs curl_multi_perform() until the transfer is done, then detaches the
749  * easy handle, destroys the multi handle and returns the easy handle's return
750  * code.
751  *
752  * REALITY: it can't just create and destroy the multi handle that easily. It
753  * needs to keep it around since if this easy handle is used again by this
754  * function, the same multi handle must be re-used so that the same pools and
755  * caches can be used.
756  *
757  * DEBUG: if 'events' is set TRUE, this function will use a replacement engine
758  * instead of curl_multi_perform() and use curl_multi_socket_action().
759  */
760 static CURLcode easy_perform(struct SessionHandle *data, bool events)
761 {
762   CURLM *multi;
763   CURLMcode mcode;
764   CURLcode result = CURLE_OK;
765   SIGPIPE_VARIABLE(pipe_st);
766
767   if(!data)
768     return CURLE_BAD_FUNCTION_ARGUMENT;
769
770   if(data->multi) {
771     failf(data, "easy handle already used in multi handle");
772     return CURLE_FAILED_INIT;
773   }
774
775   if(data->multi_easy)
776     multi = data->multi_easy;
777   else {
778     /* this multi handle will only ever have a single easy handled attached
779        to it, so make it use minimal hashes */
780     multi = Curl_multi_handle(1, 3);
781     if(!multi)
782       return CURLE_OUT_OF_MEMORY;
783     data->multi_easy = multi;
784   }
785
786   /* Copy the MAXCONNECTS option to the multi handle */
787   curl_multi_setopt(multi, CURLMOPT_MAXCONNECTS, data->set.maxconnects);
788
789   mcode = curl_multi_add_handle(multi, data);
790   if(mcode) {
791     curl_multi_cleanup(multi);
792     if(mcode == CURLM_OUT_OF_MEMORY)
793       return CURLE_OUT_OF_MEMORY;
794     else
795       return CURLE_FAILED_INIT;
796   }
797
798   sigpipe_ignore(data, &pipe_st);
799
800   /* assign this after curl_multi_add_handle() since that function checks for
801      it and rejects this handle otherwise */
802   data->multi = multi;
803
804   /* run the transfer */
805   result = events ? easy_events(multi) : easy_transfer(multi);
806
807   /* ignoring the return code isn't nice, but atm we can't really handle
808      a failure here, room for future improvement! */
809   (void)curl_multi_remove_handle(multi, data);
810
811   sigpipe_restore(&pipe_st);
812
813   /* The multi handle is kept alive, owned by the easy handle */
814   return result;
815 }
816
817
818 /*
819  * curl_easy_perform() is the external interface that performs a blocking
820  * transfer as previously setup.
821  */
822 CURLcode curl_easy_perform(CURL *easy)
823 {
824   return easy_perform(easy, FALSE);
825 }
826
827 #ifdef CURLDEBUG
828 /*
829  * curl_easy_perform_ev() is the external interface that performs a blocking
830  * transfer using the event-based API internally.
831  */
832 CURLcode curl_easy_perform_ev(CURL *easy)
833 {
834   return easy_perform(easy, TRUE);
835 }
836
837 #endif
838
839 /*
840  * curl_easy_cleanup() is the external interface to cleaning/freeing the given
841  * easy handle.
842  */
843 void curl_easy_cleanup(CURL *curl)
844 {
845   struct SessionHandle *data = (struct SessionHandle *)curl;
846   SIGPIPE_VARIABLE(pipe_st);
847
848   if(!data)
849     return;
850
851   sigpipe_ignore(data, &pipe_st);
852   Curl_close(data);
853   sigpipe_restore(&pipe_st);
854 }
855
856 /*
857  * curl_easy_getinfo() is an external interface that allows an app to retrieve
858  * information from a performed transfer and similar.
859  */
860 #undef curl_easy_getinfo
861 CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...)
862 {
863   va_list arg;
864   void *paramp;
865   CURLcode result;
866   struct SessionHandle *data = (struct SessionHandle *)curl;
867
868   va_start(arg, info);
869   paramp = va_arg(arg, void *);
870
871   result = Curl_getinfo(data, info, paramp);
872
873   va_end(arg);
874   return result;
875 }
876
877 /*
878  * curl_easy_duphandle() is an external interface to allow duplication of a
879  * given input easy handle. The returned handle will be a new working handle
880  * with all options set exactly as the input source handle.
881  */
882 CURL *curl_easy_duphandle(CURL *incurl)
883 {
884   struct SessionHandle *data=(struct SessionHandle *)incurl;
885
886   struct SessionHandle *outcurl = calloc(1, sizeof(struct SessionHandle));
887   if(NULL == outcurl)
888     goto fail;
889
890   /*
891    * We setup a few buffers we need. We should probably make them
892    * get setup on-demand in the code, as that would probably decrease
893    * the likeliness of us forgetting to init a buffer here in the future.
894    */
895   outcurl->state.headerbuff = malloc(HEADERSIZE);
896   if(!outcurl->state.headerbuff)
897     goto fail;
898   outcurl->state.headersize = HEADERSIZE;
899
900   /* copy all userdefined values */
901   if(Curl_dupset(outcurl, data))
902     goto fail;
903
904   /* the connection cache is setup on demand */
905   outcurl->state.conn_cache = NULL;
906
907   outcurl->state.lastconnect = NULL;
908
909   outcurl->progress.flags    = data->progress.flags;
910   outcurl->progress.callback = data->progress.callback;
911
912   if(data->cookies) {
913     /* If cookies are enabled in the parent handle, we enable them
914        in the clone as well! */
915     outcurl->cookies = Curl_cookie_init(data,
916                                         data->cookies->filename,
917                                         outcurl->cookies,
918                                         data->set.cookiesession);
919     if(!outcurl->cookies)
920       goto fail;
921   }
922
923   /* duplicate all values in 'change' */
924   if(data->change.cookielist) {
925     outcurl->change.cookielist =
926       Curl_slist_duplicate(data->change.cookielist);
927     if(!outcurl->change.cookielist)
928       goto fail;
929   }
930
931   if(data->change.url) {
932     outcurl->change.url = strdup(data->change.url);
933     if(!outcurl->change.url)
934       goto fail;
935     outcurl->change.url_alloc = TRUE;
936   }
937
938   if(data->change.referer) {
939     outcurl->change.referer = strdup(data->change.referer);
940     if(!outcurl->change.referer)
941       goto fail;
942     outcurl->change.referer_alloc = TRUE;
943   }
944
945   /* Clone the resolver handle, if present, for the new handle */
946   if(Curl_resolver_duphandle(&outcurl->state.resolver,
947                              data->state.resolver))
948     goto fail;
949
950   Curl_convert_setup(outcurl);
951
952   outcurl->magic = CURLEASY_MAGIC_NUMBER;
953
954   /* we reach this point and thus we are OK */
955
956   return outcurl;
957
958   fail:
959
960   if(outcurl) {
961     curl_slist_free_all(outcurl->change.cookielist);
962     outcurl->change.cookielist = NULL;
963     Curl_safefree(outcurl->state.headerbuff);
964     Curl_safefree(outcurl->change.url);
965     Curl_safefree(outcurl->change.referer);
966     Curl_freeset(outcurl);
967     free(outcurl);
968   }
969
970   return NULL;
971 }
972
973 /*
974  * curl_easy_reset() is an external interface that allows an app to re-
975  * initialize a session handle to the default values.
976  */
977 void curl_easy_reset(CURL *curl)
978 {
979   struct SessionHandle *data = (struct SessionHandle *)curl;
980
981   Curl_safefree(data->state.pathbuffer);
982
983   data->state.path = NULL;
984
985   Curl_free_request_state(data);
986
987   /* zero out UserDefined data: */
988   Curl_freeset(data);
989   memset(&data->set, 0, sizeof(struct UserDefined));
990   (void)Curl_init_userdefined(&data->set);
991
992   /* zero out Progress data: */
993   memset(&data->progress, 0, sizeof(struct Progress));
994
995   data->progress.flags |= PGRS_HIDE;
996   data->state.current_speed = -1; /* init to negative == impossible */
997 }
998
999 /*
1000  * curl_easy_pause() allows an application to pause or unpause a specific
1001  * transfer and direction. This function sets the full new state for the
1002  * current connection this easy handle operates on.
1003  *
1004  * NOTE: if you have the receiving paused and you call this function to remove
1005  * the pausing, you may get your write callback called at this point.
1006  *
1007  * Action is a bitmask consisting of CURLPAUSE_* bits in curl/curl.h
1008  */
1009 CURLcode curl_easy_pause(CURL *curl, int action)
1010 {
1011   struct SessionHandle *data = (struct SessionHandle *)curl;
1012   struct SingleRequest *k = &data->req;
1013   CURLcode result = CURLE_OK;
1014
1015   /* first switch off both pause bits */
1016   int newstate = k->keepon &~ (KEEP_RECV_PAUSE| KEEP_SEND_PAUSE);
1017
1018   /* set the new desired pause bits */
1019   newstate |= ((action & CURLPAUSE_RECV)?KEEP_RECV_PAUSE:0) |
1020     ((action & CURLPAUSE_SEND)?KEEP_SEND_PAUSE:0);
1021
1022   /* put it back in the keepon */
1023   k->keepon = newstate;
1024
1025   if(!(newstate & KEEP_RECV_PAUSE) && data->state.tempwrite) {
1026     /* we have a buffer for sending that we now seem to be able to deliver
1027        since the receive pausing is lifted! */
1028
1029     /* get the pointer in local copy since the function may return PAUSE
1030        again and then we'll get a new copy allocted and stored in
1031        the tempwrite variables */
1032     char *tempwrite = data->state.tempwrite;
1033
1034     data->state.tempwrite = NULL;
1035     result = Curl_client_chop_write(data->easy_conn, data->state.tempwritetype,
1036                                     tempwrite, data->state.tempwritesize);
1037     free(tempwrite);
1038   }
1039
1040   /* if there's no error and we're not pausing both directions, we want
1041      to have this handle checked soon */
1042   if(!result &&
1043      ((newstate&(KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) !=
1044       (KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) )
1045     Curl_expire(data, 1); /* get this handle going again */
1046
1047   return result;
1048 }
1049
1050
1051 static CURLcode easy_connection(struct SessionHandle *data,
1052                                 curl_socket_t *sfd,
1053                                 struct connectdata **connp)
1054 {
1055   if(data == NULL)
1056     return CURLE_BAD_FUNCTION_ARGUMENT;
1057
1058   /* only allow these to be called on handles with CURLOPT_CONNECT_ONLY */
1059   if(!data->set.connect_only) {
1060     failf(data, "CONNECT_ONLY is required!");
1061     return CURLE_UNSUPPORTED_PROTOCOL;
1062   }
1063
1064   *sfd = Curl_getconnectinfo(data, connp);
1065
1066   if(*sfd == CURL_SOCKET_BAD) {
1067     failf(data, "Failed to get recent socket");
1068     return CURLE_UNSUPPORTED_PROTOCOL;
1069   }
1070
1071   return CURLE_OK;
1072 }
1073
1074 /*
1075  * Receives data from the connected socket. Use after successful
1076  * curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
1077  * Returns CURLE_OK on success, error code on error.
1078  */
1079 CURLcode curl_easy_recv(CURL *curl, void *buffer, size_t buflen, size_t *n)
1080 {
1081   curl_socket_t sfd;
1082   CURLcode result;
1083   ssize_t n1;
1084   struct connectdata *c;
1085   struct SessionHandle *data = (struct SessionHandle *)curl;
1086
1087   result = easy_connection(data, &sfd, &c);
1088   if(result)
1089     return result;
1090
1091   *n = 0;
1092   result = Curl_read(c, sfd, buffer, buflen, &n1);
1093
1094   if(result)
1095     return result;
1096
1097   *n = (size_t)n1;
1098
1099   return CURLE_OK;
1100 }
1101
1102 /*
1103  * Sends data over the connected socket. Use after successful
1104  * curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
1105  */
1106 CURLcode curl_easy_send(CURL *curl, const void *buffer, size_t buflen,
1107                         size_t *n)
1108 {
1109   curl_socket_t sfd;
1110   CURLcode result;
1111   ssize_t n1;
1112   struct connectdata *c = NULL;
1113   struct SessionHandle *data = (struct SessionHandle *)curl;
1114
1115   result = easy_connection(data, &sfd, &c);
1116   if(result)
1117     return result;
1118
1119   *n = 0;
1120   result = Curl_write(c, sfd, buffer, buflen, &n1);
1121
1122   if(n1 == -1)
1123     return CURLE_SEND_ERROR;
1124
1125   /* detect EAGAIN */
1126   if(!result && !n1)
1127     return CURLE_AGAIN;
1128
1129   *n = (size_t)n1;
1130
1131   return result;
1132 }