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