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