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