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