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