1/***************************************************************************
2 *                                  _   _ ____  _
3 *  Project                     ___| | | |  _ \| |
4 *                             / __| | | | |_) | |
5 *                            | (__| |_| |  _ <| |___
6 *                             \___|\___/|_| \_\_____|
7 *
8 * Copyright (C) 1998 - 2013, 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  /* Already initialized, don't do it again */
303  if(initialized)
304    return CURLE_OK;
305
306  /* Call the actual init function first */
307  code = curl_global_init(flags);
308  if(code == CURLE_OK) {
309    Curl_cmalloc = m;
310    Curl_cfree = f;
311    Curl_cstrdup = s;
312    Curl_crealloc = r;
313    Curl_ccalloc = c;
314  }
315
316  return code;
317}
318
319/**
320 * curl_global_cleanup() globally cleanups cURL, uses the value of
321 * "init_flags" to determine what needs to be cleaned up and what doesn't.
322 */
323void curl_global_cleanup(void)
324{
325  if(!initialized)
326    return;
327
328  if(--initialized)
329    return;
330
331  Curl_global_host_cache_dtor();
332
333  if(init_flags & CURL_GLOBAL_SSL)
334    Curl_ssl_cleanup();
335
336  Curl_resolver_global_cleanup();
337
338  if(init_flags & CURL_GLOBAL_WIN32)
339    win32_cleanup();
340
341  Curl_amiga_cleanup();
342
343#if defined(USE_LIBSSH2) && defined(HAVE_LIBSSH2_EXIT)
344  (void)libssh2_exit();
345#endif
346
347  init_flags  = 0;
348}
349
350/*
351 * curl_easy_init() is the external interface to alloc, setup and init an
352 * easy handle that is returned. If anything goes wrong, NULL is returned.
353 */
354CURL *curl_easy_init(void)
355{
356  CURLcode res;
357  struct SessionHandle *data;
358
359  /* Make sure we inited the global SSL stuff */
360  if(!initialized) {
361    res = curl_global_init(CURL_GLOBAL_DEFAULT);
362    if(res) {
363      /* something in the global init failed, return nothing */
364      DEBUGF(fprintf(stderr, "Error: curl_global_init failed\n"));
365      return NULL;
366    }
367  }
368
369  /* We use curl_open() with undefined URL so far */
370  res = Curl_open(&data);
371  if(res != CURLE_OK) {
372    DEBUGF(fprintf(stderr, "Error: Curl_open failed\n"));
373    return NULL;
374  }
375
376  return data;
377}
378
379/*
380 * curl_easy_setopt() is the external interface for setting options on an
381 * easy handle.
382 */
383
384#undef curl_easy_setopt
385CURLcode curl_easy_setopt(CURL *curl, CURLoption tag, ...)
386{
387  va_list arg;
388  struct SessionHandle *data = curl;
389  CURLcode ret;
390
391  if(!curl)
392    return CURLE_BAD_FUNCTION_ARGUMENT;
393
394  va_start(arg, tag);
395
396  ret = Curl_setopt(data, tag, arg);
397
398  va_end(arg);
399  return ret;
400}
401
402#ifdef CURLDEBUG
403
404struct socketmonitor {
405  struct socketmonitor *next; /* the next node in the list or NULL */
406  struct pollfd socket; /* socket info of what to monitor */
407};
408
409struct events {
410  long ms;              /* timeout, run the timeout function when reached */
411  bool msbump;          /* set TRUE when timeout is set by callback */
412  int num_sockets;      /* number of nodes in the monitor list */
413  struct socketmonitor *list; /* list of sockets to monitor */
414  int running_handles;  /* store the returned number */
415};
416
417/* events_timer
418 *
419 * Callback that gets called with a new value when the timeout should be
420 * updated.
421 */
422
423static int events_timer(CURLM *multi,    /* multi handle */
424                        long timeout_ms, /* see above */
425                        void *userp)    /* private callback pointer */
426{
427  struct events *ev = userp;
428  (void)multi;
429  if(timeout_ms == -1)
430    /* timeout removed */
431    timeout_ms = 0;
432  else if(timeout_ms == 0)
433    /* timeout is already reached! */
434    timeout_ms = 1; /* trigger asap */
435
436  ev->ms = timeout_ms;
437  ev->msbump = TRUE;
438  return 0;
439}
440
441
442/* poll2cselect
443 *
444 * convert from poll() bit definitions to libcurl's CURL_CSELECT_* ones
445 */
446static int poll2cselect(int pollmask)
447{
448  int omask=0;
449  if(pollmask & POLLIN)
450    omask |= CURL_CSELECT_IN;
451  if(pollmask & POLLOUT)
452    omask |= CURL_CSELECT_OUT;
453  if(pollmask & POLLERR)
454    omask |= CURL_CSELECT_ERR;
455  return omask;
456}
457
458
459/* socketcb2poll
460 *
461 * convert from libcurl' CURL_POLL_* bit definitions to poll()'s
462 */
463static short socketcb2poll(int pollmask)
464{
465  short omask=0;
466  if(pollmask & CURL_POLL_IN)
467    omask |= POLLIN;
468  if(pollmask & CURL_POLL_OUT)
469    omask |= POLLOUT;
470  return omask;
471}
472
473/* events_socket
474 *
475 * Callback that gets called with information about socket activity to
476 * monitor.
477 */
478static int events_socket(CURL *easy,      /* easy handle */
479                         curl_socket_t s, /* socket */
480                         int what,        /* see above */
481                         void *userp,     /* private callback
482                                             pointer */
483                         void *socketp)   /* private socket
484                                             pointer */
485{
486  struct events *ev = userp;
487  struct socketmonitor *m;
488  struct socketmonitor *prev=NULL;
489  (void)socketp;
490
491  m = ev->list;
492  while(m) {
493    if(m->socket.fd == s) {
494
495      if(what == CURL_POLL_REMOVE) {
496        struct socketmonitor *nxt = m->next;
497        /* remove this node from the list of monitored sockets */
498        if(prev)
499          prev->next = nxt;
500        else
501          ev->list = nxt;
502        free(m);
503        m = nxt;
504        infof(easy, "socket cb: socket %d REMOVED\n", s);
505      }
506      else {
507        /* The socket 's' is already being monitored, update the activity
508           mask. Convert from libcurl bitmask to the poll one. */
509        m->socket.events = socketcb2poll(what);
510        infof(easy, "socket cb: socket %d UPDATED as %s%s\n", s,
511              what&CURL_POLL_IN?"IN":"",
512              what&CURL_POLL_OUT?"OUT":"");
513      }
514      break;
515    }
516    prev = m;
517    m = m->next; /* move to next node */
518  }
519  if(!m) {
520    if(what == CURL_POLL_REMOVE) {
521      /* this happens a bit too often, libcurl fix perhaps? */
522      /* fprintf(stderr,
523         "%s: socket %d asked to be REMOVED but not present!\n",
524                 __func__, s); */
525    }
526    else {
527      m = malloc(sizeof(struct socketmonitor));
528      m->next = ev->list;
529      m->socket.fd = s;
530      m->socket.events = socketcb2poll(what);
531      m->socket.revents = 0;
532      ev->list = m;
533      infof(easy, "socket cb: socket %d ADDED as %s%s\n", s,
534            what&CURL_POLL_IN?"IN":"",
535            what&CURL_POLL_OUT?"OUT":"");
536    }
537  }
538
539  return 0;
540}
541
542
543/*
544 * events_setup()
545 *
546 * Do the multi handle setups that only event-based transfers need.
547 */
548static void events_setup(CURLM *multi, struct events *ev)
549{
550  /* timer callback */
551  curl_multi_setopt(multi, CURLMOPT_TIMERFUNCTION, events_timer);
552  curl_multi_setopt(multi, CURLMOPT_TIMERDATA, ev);
553
554  /* socket callback */
555  curl_multi_setopt(multi, CURLMOPT_SOCKETFUNCTION, events_socket);
556  curl_multi_setopt(multi, CURLMOPT_SOCKETDATA, ev);
557}
558
559
560/* wait_or_timeout()
561 *
562 * waits for activity on any of the given sockets, or the timeout to trigger.
563 */
564
565static CURLcode wait_or_timeout(struct Curl_multi *multi, struct events *ev)
566{
567  bool done = FALSE;
568  CURLMcode mcode;
569  CURLcode rc = CURLE_OK;
570
571  while(!done) {
572    CURLMsg *msg;
573    struct socketmonitor *m;
574    struct pollfd *f;
575    struct pollfd fds[4];
576    int numfds=0;
577    int pollrc;
578    int i;
579    struct timeval before;
580    struct timeval after;
581
582    /* populate the fds[] array */
583    for(m = ev->list, f=&fds[0]; m; m = m->next) {
584      f->fd = m->socket.fd;
585      f->events = m->socket.events;
586      f->revents = 0;
587      /* fprintf(stderr, "poll() %d check socket %d\n", numfds, f->fd); */
588      f++;
589      numfds++;
590    }
591
592    /* get the time stamp to use to figure out how long poll takes */
593    before = curlx_tvnow();
594
595    /* wait for activity or timeout */
596    pollrc = Curl_poll(fds, numfds, (int)ev->ms);
597
598    after = curlx_tvnow();
599
600    ev->msbump = FALSE; /* reset here */
601
602    if(0 == pollrc) {
603      /* timeout! */
604      ev->ms = 0;
605      /* fprintf(stderr, "call curl_multi_socket_action( TIMEOUT )\n"); */
606      mcode = curl_multi_socket_action(multi, CURL_SOCKET_TIMEOUT, 0,
607                                       &ev->running_handles);
608    }
609    else if(pollrc > 0) {
610      /* loop over the monitored sockets to see which ones had activity */
611      for(i = 0; i< numfds; i++) {
612        if(fds[i].revents) {
613          /* socket activity, tell libcurl */
614          int act = poll2cselect(fds[i].revents); /* convert */
615          infof(multi->easyp, "call curl_multi_socket_action( socket %d )\n",
616                fds[i].fd);
617          mcode = curl_multi_socket_action(multi, fds[i].fd, act,
618                                           &ev->running_handles);
619        }
620      }
621
622      if(!ev->msbump)
623        /* If nothing updated the timeout, we decrease it by the spent time.
624         * If it was updated, it has the new timeout time stored already.
625         */
626        ev->ms += curlx_tvdiff(after, before);
627
628    }
629    if(mcode)
630      return CURLE_URL_MALFORMAT; /* TODO: return a proper error! */
631
632    /* we don't really care about the "msgs_in_queue" value returned in the
633       second argument */
634    msg = curl_multi_info_read(multi, &pollrc);
635    if(msg) {
636      rc = msg->data.result;
637      done = TRUE;
638    }
639  }
640
641  return rc;
642}
643
644
645/* easy_events()
646 *
647 * Runs a transfer in a blocking manner using the events-based API
648 */
649static CURLcode easy_events(CURLM *multi)
650{
651  struct events evs= {2, FALSE, 0, NULL, 0};
652
653  /* if running event-based, do some further multi inits */
654  events_setup(multi, &evs);
655
656  return wait_or_timeout(multi, &evs);
657}
658#else /* CURLDEBUG */
659/* when not built with debug, this function doesn't exist */
660#define easy_events(x) CURLE_NOT_BUILT_IN
661#endif
662
663static CURLcode easy_transfer(CURLM *multi)
664{
665  bool done = FALSE;
666  CURLMcode mcode = CURLM_OK;
667  CURLcode code = CURLE_OK;
668  struct timeval before;
669  int without_fds = 0;  /* count number of consecutive returns from
670                           curl_multi_wait() without any filedescriptors */
671
672  while(!done && !mcode) {
673    int still_running;
674    int ret;
675
676    before = curlx_tvnow();
677    mcode = curl_multi_wait(multi, NULL, 0, 1000, &ret);
678
679    if(mcode == CURLM_OK) {
680      if(ret == -1) {
681        /* poll() failed not on EINTR, indicate a network problem */
682        code = CURLE_RECV_ERROR;
683        break;
684      }
685      else if(ret == 0) {
686        struct timeval after = curlx_tvnow();
687        /* If it returns without any filedescriptor instantly, we need to
688           avoid busy-looping during periods where it has nothing particular
689           to wait for */
690        if(curlx_tvdiff(after, before) <= 10) {
691          without_fds++;
692          if(without_fds > 2) {
693            int sleep_ms = without_fds < 10 ? (1 << (without_fds-1)): 1000;
694            Curl_wait_ms(sleep_ms);
695          }
696        }
697        else
698          /* it wasn't "instant", restart counter */
699          without_fds = 0;
700      }
701      else
702        /* got file descriptor, restart counter */
703        without_fds = 0;
704
705      mcode = curl_multi_perform(multi, &still_running);
706    }
707
708    /* only read 'still_running' if curl_multi_perform() return OK */
709    if((mcode == CURLM_OK) && !still_running) {
710      int rc;
711      CURLMsg *msg = curl_multi_info_read(multi, &rc);
712      if(msg) {
713        code = msg->data.result;
714        done = TRUE;
715      }
716    }
717  }
718
719  /* Make sure to return some kind of error if there was a multi problem */
720  if(mcode) {
721    return (mcode == CURLM_OUT_OF_MEMORY) ? CURLE_OUT_OF_MEMORY :
722            /* The other multi errors should never happen, so return
723               something suitably generic */
724            CURLE_BAD_FUNCTION_ARGUMENT;
725  }
726
727  return code;
728}
729
730
731/*
732 * easy_perform() is the external interface that performs a blocking
733 * transfer as previously setup.
734 *
735 * CONCEPT: This function creates a multi handle, adds the easy handle to it,
736 * runs curl_multi_perform() until the transfer is done, then detaches the
737 * easy handle, destroys the multi handle and returns the easy handle's return
738 * code.
739 *
740 * REALITY: it can't just create and destroy the multi handle that easily. It
741 * needs to keep it around since if this easy handle is used again by this
742 * function, the same multi handle must be re-used so that the same pools and
743 * caches can be used.
744 *
745 * DEBUG: if 'events' is set TRUE, this function will use a replacement engine
746 * instead of curl_multi_perform() and use curl_multi_socket_action().
747 */
748static CURLcode easy_perform(struct SessionHandle *data, bool events)
749{
750  CURLM *multi;
751  CURLMcode mcode;
752  CURLcode code = CURLE_OK;
753  SIGPIPE_VARIABLE(pipe_st);
754
755  if(!data)
756    return CURLE_BAD_FUNCTION_ARGUMENT;
757
758  if(data->multi) {
759    failf(data, "easy handled already used in multi handle");
760    return CURLE_FAILED_INIT;
761  }
762
763  if(data->multi_easy)
764    multi = data->multi_easy;
765  else {
766    /* this multi handle will only ever have a single easy handled attached
767       to it, so make it use minimal hashes */
768    multi = Curl_multi_handle(1, 3);
769    if(!multi)
770      return CURLE_OUT_OF_MEMORY;
771    data->multi_easy = multi;
772  }
773
774  /* Copy the MAXCONNECTS option to the multi handle */
775  curl_multi_setopt(multi, CURLMOPT_MAXCONNECTS, data->set.maxconnects);
776
777  mcode = curl_multi_add_handle(multi, data);
778  if(mcode) {
779    curl_multi_cleanup(multi);
780    if(mcode == CURLM_OUT_OF_MEMORY)
781      return CURLE_OUT_OF_MEMORY;
782    else
783      return CURLE_FAILED_INIT;
784  }
785
786  sigpipe_ignore(data, &pipe_st);
787
788  /* assign this after curl_multi_add_handle() since that function checks for
789     it and rejects this handle otherwise */
790  data->multi = multi;
791
792  /* run the transfer */
793  code = events ? easy_events(multi) : easy_transfer(multi);
794
795  /* ignoring the return code isn't nice, but atm we can't really handle
796     a failure here, room for future improvement! */
797  (void)curl_multi_remove_handle(multi, data);
798
799  sigpipe_restore(&pipe_st);
800
801  /* The multi handle is kept alive, owned by the easy handle */
802  return code;
803}
804
805
806/*
807 * curl_easy_perform() is the external interface that performs a blocking
808 * transfer as previously setup.
809 */
810CURLcode curl_easy_perform(CURL *easy)
811{
812  return easy_perform(easy, FALSE);
813}
814
815#ifdef CURLDEBUG
816/*
817 * curl_easy_perform_ev() is the external interface that performs a blocking
818 * transfer using the event-based API internally.
819 */
820CURLcode curl_easy_perform_ev(CURL *easy)
821{
822  return easy_perform(easy, TRUE);
823}
824
825#endif
826
827/*
828 * curl_easy_cleanup() is the external interface to cleaning/freeing the given
829 * easy handle.
830 */
831void curl_easy_cleanup(CURL *curl)
832{
833  struct SessionHandle *data = (struct SessionHandle *)curl;
834  SIGPIPE_VARIABLE(pipe_st);
835
836  if(!data)
837    return;
838
839  sigpipe_ignore(data, &pipe_st);
840  Curl_close(data);
841  sigpipe_restore(&pipe_st);
842}
843
844/*
845 * curl_easy_getinfo() is an external interface that allows an app to retrieve
846 * information from a performed transfer and similar.
847 */
848#undef curl_easy_getinfo
849CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...)
850{
851  va_list arg;
852  void *paramp;
853  CURLcode ret;
854  struct SessionHandle *data = (struct SessionHandle *)curl;
855
856  va_start(arg, info);
857  paramp = va_arg(arg, void *);
858
859  ret = Curl_getinfo(data, info, paramp);
860
861  va_end(arg);
862  return ret;
863}
864
865/*
866 * curl_easy_duphandle() is an external interface to allow duplication of a
867 * given input easy handle. The returned handle will be a new working handle
868 * with all options set exactly as the input source handle.
869 */
870CURL *curl_easy_duphandle(CURL *incurl)
871{
872  struct SessionHandle *data=(struct SessionHandle *)incurl;
873
874  struct SessionHandle *outcurl = calloc(1, sizeof(struct SessionHandle));
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->state.headerbuff = malloc(HEADERSIZE);
884  if(!outcurl->state.headerbuff)
885    goto fail;
886  outcurl->state.headersize = HEADERSIZE;
887
888  /* copy all userdefined values */
889  if(Curl_dupset(outcurl, data) != CURLE_OK)
890    goto fail;
891
892  /* the connection cache is setup on demand */
893  outcurl->state.conn_cache = NULL;
894
895  outcurl->state.lastconnect = NULL;
896
897  outcurl->progress.flags    = data->progress.flags;
898  outcurl->progress.callback = data->progress.callback;
899
900  if(data->cookies) {
901    /* If cookies are enabled in the parent handle, we enable them
902       in the clone as well! */
903    outcurl->cookies = Curl_cookie_init(data,
904                                        data->cookies->filename,
905                                        outcurl->cookies,
906                                        data->set.cookiesession);
907    if(!outcurl->cookies)
908      goto fail;
909  }
910
911  /* duplicate all values in 'change' */
912  if(data->change.cookielist) {
913    outcurl->change.cookielist =
914      Curl_slist_duplicate(data->change.cookielist);
915    if(!outcurl->change.cookielist)
916      goto fail;
917  }
918
919  if(data->change.url) {
920    outcurl->change.url = strdup(data->change.url);
921    if(!outcurl->change.url)
922      goto fail;
923    outcurl->change.url_alloc = TRUE;
924  }
925
926  if(data->change.referer) {
927    outcurl->change.referer = strdup(data->change.referer);
928    if(!outcurl->change.referer)
929      goto fail;
930    outcurl->change.referer_alloc = TRUE;
931  }
932
933  /* Clone the resolver handle, if present, for the new handle */
934  if(Curl_resolver_duphandle(&outcurl->state.resolver,
935                             data->state.resolver) != CURLE_OK)
936    goto fail;
937
938  Curl_convert_setup(outcurl);
939
940  outcurl->magic = CURLEASY_MAGIC_NUMBER;
941
942  /* we reach this point and thus we are OK */
943
944  return outcurl;
945
946  fail:
947
948  if(outcurl) {
949    curl_slist_free_all(outcurl->change.cookielist);
950    outcurl->change.cookielist = NULL;
951    Curl_safefree(outcurl->state.headerbuff);
952    Curl_safefree(outcurl->change.url);
953    Curl_safefree(outcurl->change.referer);
954    Curl_freeset(outcurl);
955    free(outcurl);
956  }
957
958  return NULL;
959}
960
961/*
962 * curl_easy_reset() is an external interface that allows an app to re-
963 * initialize a session handle to the default values.
964 */
965void curl_easy_reset(CURL *curl)
966{
967  struct SessionHandle *data = (struct SessionHandle *)curl;
968
969  Curl_safefree(data->state.pathbuffer);
970
971  data->state.path = NULL;
972
973  Curl_free_request_state(data);
974
975  /* zero out UserDefined data: */
976  Curl_freeset(data);
977  memset(&data->set, 0, sizeof(struct UserDefined));
978  (void)Curl_init_userdefined(&data->set);
979
980  /* zero out Progress data: */
981  memset(&data->progress, 0, sizeof(struct Progress));
982
983  data->progress.flags |= PGRS_HIDE;
984  data->state.current_speed = -1; /* init to negative == impossible */
985}
986
987/*
988 * curl_easy_pause() allows an application to pause or unpause a specific
989 * transfer and direction. This function sets the full new state for the
990 * current connection this easy handle operates on.
991 *
992 * NOTE: if you have the receiving paused and you call this function to remove
993 * the pausing, you may get your write callback called at this point.
994 *
995 * Action is a bitmask consisting of CURLPAUSE_* bits in curl/curl.h
996 */
997CURLcode curl_easy_pause(CURL *curl, int action)
998{
999  struct SessionHandle *data = (struct SessionHandle *)curl;
1000  struct SingleRequest *k = &data->req;
1001  CURLcode result = CURLE_OK;
1002
1003  /* first switch off both pause bits */
1004  int newstate = k->keepon &~ (KEEP_RECV_PAUSE| KEEP_SEND_PAUSE);
1005
1006  /* set the new desired pause bits */
1007  newstate |= ((action & CURLPAUSE_RECV)?KEEP_RECV_PAUSE:0) |
1008    ((action & CURLPAUSE_SEND)?KEEP_SEND_PAUSE:0);
1009
1010  /* put it back in the keepon */
1011  k->keepon = newstate;
1012
1013  if(!(newstate & KEEP_RECV_PAUSE) && data->state.tempwrite) {
1014    /* we have a buffer for sending that we now seem to be able to deliver
1015       since the receive pausing is lifted! */
1016
1017    /* get the pointer, type and length in local copies since the function may
1018       return PAUSE again and then we'll get a new copy allocted and stored in
1019       the tempwrite variables */
1020    char *tempwrite = data->state.tempwrite;
1021    char *freewrite = tempwrite; /* store this pointer to free it later */
1022    size_t tempsize = data->state.tempwritesize;
1023    int temptype = data->state.tempwritetype;
1024    size_t chunklen;
1025
1026    /* clear tempwrite here just to make sure it gets cleared if there's no
1027       further use of it, and make sure we don't clear it after the function
1028       invoke as it may have been set to a new value by then */
1029    data->state.tempwrite = NULL;
1030
1031    /* since the write callback API is define to never exceed
1032       CURL_MAX_WRITE_SIZE bytes in a single call, and since we may in fact
1033       have more data than that in our buffer here, we must loop sending the
1034       data in multiple calls until there's no data left or we get another
1035       pause returned.
1036
1037       A tricky part is that the function we call will "buffer" the data
1038       itself when it pauses on a particular buffer, so we may need to do some
1039       extra trickery if we get a pause return here.
1040    */
1041    do {
1042      chunklen = (tempsize > CURL_MAX_WRITE_SIZE)?CURL_MAX_WRITE_SIZE:tempsize;
1043
1044      result = Curl_client_write(data->easy_conn,
1045                                 temptype, tempwrite, chunklen);
1046      if(result)
1047        /* failures abort the loop at once */
1048        break;
1049
1050      if(data->state.tempwrite && (tempsize - chunklen)) {
1051        /* Ouch, the reading is again paused and the block we send is now
1052           "cached". If this is the final chunk we can leave it like this, but
1053           if we have more chunks that are cached after this, we need to free
1054           the newly cached one and put back a version that is truly the entire
1055           contents that is saved for later
1056        */
1057        char *newptr;
1058
1059        /* note that tempsize is still the size as before the callback was
1060           used, and thus the whole piece of data to keep */
1061        newptr = realloc(data->state.tempwrite, tempsize);
1062
1063        if(!newptr) {
1064          free(data->state.tempwrite); /* free old area */
1065          data->state.tempwrite = NULL;
1066          result = CURLE_OUT_OF_MEMORY;
1067          /* tempwrite will be freed further down */
1068          break;
1069        }
1070        data->state.tempwrite = newptr; /* store new pointer */
1071        memcpy(newptr, tempwrite, tempsize);
1072        data->state.tempwritesize = tempsize; /* store new size */
1073        /* tempwrite will be freed further down */
1074        break; /* go back to pausing until further notice */
1075      }
1076      else {
1077        tempsize -= chunklen;  /* left after the call above */
1078        tempwrite += chunklen; /* advance the pointer */
1079      }
1080
1081    } while((result == CURLE_OK) && tempsize);
1082
1083    free(freewrite); /* this is unconditionally no longer used */
1084  }
1085
1086  /* if there's no error and we're not pausing both directions, we want
1087     to have this handle checked soon */
1088  if(!result &&
1089     ((newstate&(KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) !=
1090      (KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) )
1091    Curl_expire(data, 1); /* get this handle going again */
1092
1093  return result;
1094}
1095
1096
1097static CURLcode easy_connection(struct SessionHandle *data,
1098                                curl_socket_t *sfd,
1099                                struct connectdata **connp)
1100{
1101  if(data == NULL)
1102    return CURLE_BAD_FUNCTION_ARGUMENT;
1103
1104  /* only allow these to be called on handles with CURLOPT_CONNECT_ONLY */
1105  if(!data->set.connect_only) {
1106    failf(data, "CONNECT_ONLY is required!");
1107    return CURLE_UNSUPPORTED_PROTOCOL;
1108  }
1109
1110  *sfd = Curl_getconnectinfo(data, connp);
1111
1112  if(*sfd == CURL_SOCKET_BAD) {
1113    failf(data, "Failed to get recent socket");
1114    return CURLE_UNSUPPORTED_PROTOCOL;
1115  }
1116
1117  return CURLE_OK;
1118}
1119
1120/*
1121 * Receives data from the connected socket. Use after successful
1122 * curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
1123 * Returns CURLE_OK on success, error code on error.
1124 */
1125CURLcode curl_easy_recv(CURL *curl, void *buffer, size_t buflen, size_t *n)
1126{
1127  curl_socket_t sfd;
1128  CURLcode ret;
1129  ssize_t n1;
1130  struct connectdata *c;
1131  struct SessionHandle *data = (struct SessionHandle *)curl;
1132
1133  ret = easy_connection(data, &sfd, &c);
1134  if(ret)
1135    return ret;
1136
1137  *n = 0;
1138  ret = Curl_read(c, sfd, buffer, buflen, &n1);
1139
1140  if(ret != CURLE_OK)
1141    return ret;
1142
1143  *n = (size_t)n1;
1144
1145  return CURLE_OK;
1146}
1147
1148/*
1149 * Sends data over the connected socket. Use after successful
1150 * curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
1151 */
1152CURLcode curl_easy_send(CURL *curl, const void *buffer, size_t buflen,
1153                        size_t *n)
1154{
1155  curl_socket_t sfd;
1156  CURLcode ret;
1157  ssize_t n1;
1158  struct connectdata *c = NULL;
1159  struct SessionHandle *data = (struct SessionHandle *)curl;
1160
1161  ret = easy_connection(data, &sfd, &c);
1162  if(ret)
1163    return ret;
1164
1165  *n = 0;
1166  ret = Curl_write(c, sfd, buffer, buflen, &n1);
1167
1168  if(n1 == -1)
1169    return CURLE_SEND_ERROR;
1170
1171  /* detect EAGAIN */
1172  if((CURLE_OK == ret) && (0 == n1))
1173    return CURLE_AGAIN;
1174
1175  *n = (size_t)n1;
1176
1177  return ret;
1178}
1179