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