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