Updated the copyright year since changes have been this year.
[platform/upstream/curl.git] / lib / easy.c
1 /***************************************************************************
2  *                                  _   _ ____  _
3  *  Project                     ___| | | |  _ \| |
4  *                             / __| | | | |_) | |
5  *                            | (__| |_| |  _ <| |___
6  *                             \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
9  *
10  * This software is licensed as described in the file COPYING, which
11  * you should have received as part of this distribution. The terms
12  * are also available at http://curl.haxx.se/docs/copyright.html.
13  *
14  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15  * copies of the Software, and permit persons to whom the Software is
16  * furnished to do so, under the terms of the COPYING file.
17  *
18  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19  * KIND, either express or implied.
20  *
21  * $Id$
22  ***************************************************************************/
23
24 #include "setup.h"
25
26 /* -- WIN32 approved -- */
27 #include <stdio.h>
28 #include <string.h>
29 #include <stdarg.h>
30 #include <stdlib.h>
31 #include <ctype.h>
32 #ifdef HAVE_SYS_TYPES_H
33 #include <sys/types.h>
34 #endif
35 #ifdef HAVE_SYS_STAT_H
36 #include <sys/stat.h>
37 #endif
38
39 #include <errno.h>
40
41 #include "strequal.h"
42
43 #if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
44 #include <time.h>
45 #include <io.h>
46 #else
47 #ifdef HAVE_SYS_SOCKET_H
48 #include <sys/socket.h>
49 #endif
50 #include <netinet/in.h>
51 #include <sys/time.h>
52 #ifdef HAVE_UNISTD_H
53 #include <unistd.h>
54 #endif
55 #include <netdb.h>
56 #ifdef HAVE_ARPA_INET_H
57 #include <arpa/inet.h>
58 #endif
59 #ifdef HAVE_NET_IF_H
60 #include <net/if.h>
61 #endif
62 #include <sys/ioctl.h>
63 #include <signal.h>
64
65 #ifdef HAVE_SYS_PARAM_H
66 #include <sys/param.h>
67 #endif
68
69 #ifdef HAVE_SYS_SELECT_H
70 #include <sys/select.h>
71 #endif
72
73 #endif  /* WIN32 ... */
74
75 #include "urldata.h"
76 #include <curl/curl.h>
77 #include "transfer.h"
78 #include "ssluse.h"
79 #include "url.h"
80 #include "getinfo.h"
81 #include "hostip.h"
82 #include "share.h"
83 #include "memory.h"
84 #include "progress.h"
85 #include "easyif.h"
86
87 #define _MPRINTF_REPLACE /* use our functions only */
88 #include <curl/mprintf.h>
89
90 /* The last #include file should be: */
91 #include "memdebug.h"
92
93 #if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
94 /* win32_cleanup() is for win32 socket cleanup functionality, the opposite
95    of win32_init() */
96 static void win32_cleanup(void)
97 {
98   WSACleanup();
99 }
100
101 /* win32_init() performs win32 socket initialization to properly setup the
102    stack to allow networking */
103 static CURLcode win32_init(void)
104 {
105   WORD wVersionRequested;
106   WSADATA wsaData;
107   int err;
108
109 #ifdef ENABLE_IPV6
110   wVersionRequested = MAKEWORD(2, 0);
111 #else
112   wVersionRequested = MAKEWORD(1, 1);
113 #endif
114
115   err = WSAStartup(wVersionRequested, &wsaData);
116
117   if (err != 0)
118     /* Tell the user that we couldn't find a useable */
119     /* winsock.dll.     */
120     return CURLE_FAILED_INIT;
121
122   /* Confirm that the Windows Sockets DLL supports what we need.*/
123   /* Note that if the DLL supports versions greater */
124   /* than wVersionRequested, it will still return */
125   /* wVersionRequested in wVersion. wHighVersion contains the */
126   /* highest supported version. */
127
128   if ( LOBYTE( wsaData.wVersion ) != LOBYTE(wVersionRequested) ||
129        HIBYTE( wsaData.wVersion ) != HIBYTE(wVersionRequested) ) {
130     /* Tell the user that we couldn't find a useable */
131
132     /* winsock.dll. */
133     WSACleanup();
134     return CURLE_FAILED_INIT;
135   }
136   /* The Windows Sockets DLL is acceptable. Proceed. */
137   return CURLE_OK;
138 }
139
140 #else
141 /* These functions exist merely to prevent compiler warnings */
142 static CURLcode win32_init(void) { return CURLE_OK; }
143 static void win32_cleanup(void) { }
144 #endif
145
146 #ifdef USE_LIBIDN
147 /*
148  * Initialise use of IDNA library.
149  * It falls back to ASCII if $CHARSET isn't defined. This doesn't work for
150  * idna_to_ascii_lz().
151  */
152 static void idna_init (void)
153 {
154 #ifdef WIN32
155   char buf[60];
156   UINT cp = GetACP();
157
158   if (!getenv("CHARSET") && cp > 0) {
159     snprintf(buf, sizeof(buf), "CHARSET=cp%u", cp);
160     putenv(buf);
161   }
162 #else
163   /* to do? */
164 #endif
165 }
166 #endif  /* USE_LIBIDN */
167
168 /* true globals -- for curl_global_init() and curl_global_cleanup() */
169 static unsigned int  initialized;
170 static long          init_flags;
171
172 /*
173  * If a memory-using function (like curl_getenv) is used before
174  * curl_global_init() is called, we need to have these pointers set already.
175  */
176
177 #ifdef _WIN32_WCE
178 #define strdup _strdup
179 #endif
180
181 curl_malloc_callback Curl_cmalloc = (curl_malloc_callback)malloc;
182 curl_free_callback Curl_cfree = (curl_free_callback)free;
183 curl_realloc_callback Curl_crealloc = (curl_realloc_callback)realloc;
184 curl_strdup_callback Curl_cstrdup = (curl_strdup_callback)strdup;
185 curl_calloc_callback Curl_ccalloc = (curl_calloc_callback)calloc;
186
187 /**
188  * curl_global_init() globally initializes cURL given a bitwise set of the
189  * different features of what to initialize.
190  */
191 CURLcode curl_global_init(long flags)
192 {
193   if (initialized)
194     return CURLE_OK;
195
196   /* Setup the default memory functions here (again) */
197   Curl_cmalloc = (curl_malloc_callback)malloc;
198   Curl_cfree = (curl_free_callback)free;
199   Curl_crealloc = (curl_realloc_callback)realloc;
200   Curl_cstrdup = (curl_strdup_callback)strdup;
201   Curl_ccalloc = (curl_calloc_callback)calloc;
202
203   if (flags & CURL_GLOBAL_SSL)
204     if (!Curl_SSL_init())
205       return CURLE_FAILED_INIT;
206
207   if (flags & CURL_GLOBAL_WIN32)
208     if (win32_init() != CURLE_OK)
209       return CURLE_FAILED_INIT;
210
211 #ifdef _AMIGASF
212   if(!amiga_init())
213     return CURLE_FAILED_INIT;
214 #endif
215
216 #ifdef USE_LIBIDN
217   idna_init();
218 #endif
219
220   initialized = 1;
221   init_flags  = flags;
222
223   return CURLE_OK;
224 }
225
226 /*
227  * curl_global_init_mem() globally initializes cURL and also registers the
228  * user provided callback routines.
229  */
230 CURLcode curl_global_init_mem(long flags, curl_malloc_callback m,
231                               curl_free_callback f, curl_realloc_callback r,
232                               curl_strdup_callback s, curl_calloc_callback c)
233 {
234   CURLcode code = CURLE_OK;
235
236   /* Invalid input, return immediately */
237   if (!m || !f || !r || !s || !c)
238     return CURLE_FAILED_INIT;
239
240   /* Already initialized, don't do it again */
241   if ( initialized )
242     return CURLE_OK;
243
244   /* Call the actual init function first */
245   code = curl_global_init(flags);
246   if (code == CURLE_OK) {
247     Curl_cmalloc = m;
248     Curl_cfree = f;
249     Curl_cstrdup = s;
250     Curl_crealloc = r;
251     Curl_ccalloc = c;
252   }
253
254   return code;
255 }
256
257 /**
258  * curl_global_cleanup() globally cleanups cURL, uses the value of
259  * "init_flags" to determine what needs to be cleaned up and what doesn't.
260  */
261 void curl_global_cleanup(void)
262 {
263   if (!initialized)
264     return;
265
266   Curl_global_host_cache_dtor();
267
268   if (init_flags & CURL_GLOBAL_SSL)
269     Curl_SSL_cleanup();
270
271   if (init_flags & CURL_GLOBAL_WIN32)
272     win32_cleanup();
273
274 #ifdef _AMIGASF
275   amiga_cleanup();
276 #endif
277
278   initialized = 0;
279   init_flags  = 0;
280 }
281
282 /*
283  * curl_easy_init() is the external interface to alloc, setup and init an
284  * easy handle that is returned. If anything goes wrong, NULL is returned.
285  */
286 CURL *curl_easy_init(void)
287 {
288   CURLcode res;
289   struct SessionHandle *data;
290
291   /* Make sure we inited the global SSL stuff */
292   if (!initialized) {
293     res = curl_global_init(CURL_GLOBAL_DEFAULT);
294     if(res)
295       /* something in the global init failed, return nothing */
296       return NULL;
297   }
298
299   /* We use curl_open() with undefined URL so far */
300   res = Curl_open(&data);
301   if(res != CURLE_OK)
302     return NULL;
303
304   return data;
305 }
306
307 /*
308  * curl_easy_setopt() is the external interface for setting options on an
309  * easy handle.
310  */
311 typedef int (*func_T)(void);
312 CURLcode curl_easy_setopt(CURL *curl, CURLoption tag, ...)
313 {
314   va_list arg;
315   func_T param_func = (func_T)0;
316   long param_long = 0;
317   void *param_obj = NULL;
318   curl_off_t param_offset = 0;
319   struct SessionHandle *data = curl;
320   CURLcode ret=CURLE_FAILED_INIT;
321
322   if(!curl)
323     return CURLE_BAD_FUNCTION_ARGUMENT;
324
325   va_start(arg, tag);
326
327   /* PORTING NOTE:
328      Object pointers can't necessarily be casted to function pointers and
329      therefore we need to know what type it is and read the correct type
330      at once. This should also correct problems with different sizes of
331      the types.
332   */
333
334   if(tag < CURLOPTTYPE_OBJECTPOINT) {
335     /* This is a LONG type */
336     param_long = va_arg(arg, long);
337     ret = Curl_setopt(data, tag, param_long);
338   }
339   else if(tag < CURLOPTTYPE_FUNCTIONPOINT) {
340     /* This is a object pointer type */
341     param_obj = va_arg(arg, void *);
342     ret = Curl_setopt(data, tag, param_obj);
343   }
344   else if(tag < CURLOPTTYPE_OFF_T) {
345     /* This is a function pointer type */
346     param_func = va_arg(arg, func_T );
347     ret = Curl_setopt(data, tag, param_func);
348   }
349   else {
350     /* This is a curl_off_t type */
351     param_offset = va_arg(arg, curl_off_t);
352     ret = Curl_setopt(data, tag, param_offset);
353   }
354
355   va_end(arg);
356   return ret;
357 }
358
359 #ifdef CURL_MULTIEASY
360 /***************************************************************************
361  * This function is still only for testing purposes. It makes a great way
362  * to run the full test suite on the multi interface instead of the easy one.
363  ***************************************************************************
364  *
365  * The *new* curl_easy_perform() is the external interface that performs a
366  * transfer previously setup.
367  *
368  * Wrapper-function that: creates a multi handle, adds the easy handle to it,
369  * runs curl_multi_perform() until the transfer is done, then detaches the
370  * easy handle, destroys the multi handle and returns the easy handle's return
371  * code. This will make everything internally use and assume multi interface.
372  */
373 CURLcode curl_easy_perform(CURL *easy)
374 {
375   CURLM *multi;
376   CURLMcode mcode;
377   CURLcode code = CURLE_OK;
378   int still_running;
379   struct timeval timeout;
380   int rc;
381   CURLMsg *msg;
382   fd_set fdread;
383   fd_set fdwrite;
384   fd_set fdexcep;
385   int maxfd;
386
387   if(!easy)
388     return CURLE_BAD_FUNCTION_ARGUMENT;
389
390   multi = curl_multi_init();
391   if(!multi)
392     return CURLE_OUT_OF_MEMORY;
393
394   mcode = curl_multi_add_handle(multi, easy);
395   if(mcode) {
396     curl_multi_cleanup(multi);
397     return CURLE_FAILED_INIT;
398   }
399
400   /* we start some action by calling perform right away */
401
402   do {
403     while(CURLM_CALL_MULTI_PERFORM ==
404           curl_multi_perform(multi, &still_running));
405
406     if(!still_running)
407       break;
408
409     FD_ZERO(&fdread);
410     FD_ZERO(&fdwrite);
411     FD_ZERO(&fdexcep);
412
413     /* timeout once per second */
414     timeout.tv_sec = 1;
415     timeout.tv_usec = 0;
416
417     /* get file descriptors from the transfers */
418     curl_multi_fdset(multi, &fdread, &fdwrite, &fdexcep, &maxfd);
419
420     rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
421
422     if(rc == -1)
423       /* select error */
424       break;
425
426     /* timeout or data to send/receive => loop! */
427   } while(still_running);
428
429   msg = curl_multi_info_read(multi, &rc);
430   if(msg)
431     code = msg->data.result;
432
433   mcode = curl_multi_remove_handle(multi, easy);
434   /* what to do if it fails? */
435
436   mcode = curl_multi_cleanup(multi);
437   /* what to do if it fails? */
438
439   return code;
440 }
441 #else
442 /*
443  * curl_easy_perform() is the external interface that performs a transfer
444  * previously setup.
445  */
446 CURLcode curl_easy_perform(CURL *curl)
447 {
448   struct SessionHandle *data = (struct SessionHandle *)curl;
449
450   if(!data)
451     return CURLE_BAD_FUNCTION_ARGUMENT;
452
453   if ( ! (data->share && data->share->hostcache) ) {
454
455     if (Curl_global_host_cache_use(data) &&
456         data->hostcache != Curl_global_host_cache_get()) {
457       if (data->hostcache)
458         Curl_hash_destroy(data->hostcache);
459       data->hostcache = Curl_global_host_cache_get();
460     }
461
462     if (!data->hostcache) {
463       data->hostcache = Curl_mk_dnscache();
464
465       if(!data->hostcache)
466         /* While we possibly could survive and do good without a host cache,
467            the fact that creating it failed indicates that things are truly
468            screwed up and we should bail out! */
469         return CURLE_OUT_OF_MEMORY;
470     }
471
472   }
473
474   return Curl_perform(data);
475 }
476 #endif
477
478 /*
479  * curl_easy_cleanup() is the external interface to cleaning/freeing the given
480  * easy handle.
481  */
482 void curl_easy_cleanup(CURL *curl)
483 {
484   struct SessionHandle *data = (struct SessionHandle *)curl;
485
486   if(!data)
487     return;
488
489   Curl_close(data);
490 }
491
492 /*
493  * Store a pointed to the multi handle within the easy handle's data struct.
494  */
495 void Curl_easy_addmulti(struct SessionHandle *data,
496                         void *multi)
497 {
498   data->multi = multi;
499 }
500
501 /*
502  * curl_easy_getinfo() is an external interface that allows an app to retrieve
503  * information from a performed transfer and similar.
504  */
505 CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...)
506 {
507   va_list arg;
508   void *paramp;
509   struct SessionHandle *data = (struct SessionHandle *)curl;
510
511   va_start(arg, info);
512   paramp = va_arg(arg, void *);
513
514   return Curl_getinfo(data, info, paramp);
515 }
516
517 /*
518  * curl_easy_duphandle() is an external interface to allow duplication of a
519  * given input easy handle. The returned handle will be a new working handle
520  * with all options set exactly as the input source handle.
521  */
522 CURL *curl_easy_duphandle(CURL *incurl)
523 {
524   bool fail = TRUE;
525   struct SessionHandle *data=(struct SessionHandle *)incurl;
526
527   struct SessionHandle *outcurl = (struct SessionHandle *)
528     calloc(sizeof(struct SessionHandle), 1);
529
530   if(NULL == outcurl)
531     return NULL; /* failure */
532
533   do {
534
535     /*
536      * We setup a few buffers we need. We should probably make them
537      * get setup on-demand in the code, as that would probably decrease
538      * the likeliness of us forgetting to init a buffer here in the future.
539      */
540     outcurl->state.headerbuff=(char*)malloc(HEADERSIZE);
541     if(!outcurl->state.headerbuff) {
542       break;
543     }
544     outcurl->state.headersize=HEADERSIZE;
545
546     /* copy all userdefined values */
547     outcurl->set = data->set;
548     outcurl->state.numconnects = data->state.numconnects;
549     outcurl->state.connects = (struct connectdata **)
550       malloc(sizeof(struct connectdata *) * outcurl->state.numconnects);
551
552     if(!outcurl->state.connects) {
553       break;
554     }
555
556     memset(outcurl->state.connects, 0,
557            sizeof(struct connectdata *)*outcurl->state.numconnects);
558
559     outcurl->progress.flags    = data->progress.flags;
560     outcurl->progress.callback = data->progress.callback;
561
562 #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
563     if(data->cookies) {
564       /* If cookies are enabled in the parent handle, we enable them
565          in the clone as well! */
566       outcurl->cookies = Curl_cookie_init(data,
567                                             data->cookies->filename,
568                                             outcurl->cookies,
569                                             data->set.cookiesession);
570       if(!outcurl->cookies) {
571         break;
572       }
573     }
574 #endif   /* CURL_DISABLE_HTTP */
575
576     /* duplicate all values in 'change' */
577     if(data->change.url) {
578       outcurl->change.url = strdup(data->change.url);
579       if(!outcurl->change.url)
580         break;
581       outcurl->change.url_alloc = TRUE;
582     }
583     if(data->change.proxy) {
584       outcurl->change.proxy = strdup(data->change.proxy);
585       if(!outcurl->change.proxy)
586         break;
587       outcurl->change.proxy_alloc = TRUE;
588     }
589     if(data->change.referer) {
590       outcurl->change.referer = strdup(data->change.referer);
591       if(!outcurl->change.referer)
592         break;
593       outcurl->change.referer_alloc = TRUE;
594     }
595
596 #ifdef USE_ARES
597     /* If we use ares, we setup a new ares channel for the new handle */
598     if(ARES_SUCCESS != ares_init(&outcurl->state.areschannel))
599       break;
600 #endif
601
602     fail = FALSE; /* we reach this point and thus we are OK */
603
604   } while(0);
605
606   if(fail) {
607     if(outcurl) {
608       if(outcurl->state.connects)
609         free(outcurl->state.connects);
610       if(outcurl->state.headerbuff)
611         free(outcurl->state.headerbuff);
612       if(outcurl->change.proxy)
613         free(outcurl->change.proxy);
614       if(outcurl->change.url)
615         free(outcurl->change.url);
616       if(outcurl->change.referer)
617         free(outcurl->change.referer);
618       free(outcurl); /* free the memory again */
619       outcurl = NULL;
620     }
621   }
622
623   return outcurl;
624 }
625
626 /*
627  * curl_easy_reset() is an external interface that allows an app to re-
628  * initialize a session handle to the default values.
629  */
630 void curl_easy_reset(CURL *curl)
631 {
632   struct SessionHandle *data = (struct SessionHandle *)curl;
633
634   /* zero out UserDefined data: */
635   memset(&data->set, 0, sizeof(struct UserDefined));
636
637   /* zero out Progress data: */
638   memset(&data->progress, 0, sizeof(struct Progress));
639
640   /* The remainder of these calls have been taken from Curl_open() */
641
642   data->set.out = stdout; /* default output to stdout */
643   data->set.in  = stdin;  /* default input from stdin */
644   data->set.err  = stderr;  /* default stderr to stderr */
645
646   /* use fwrite as default function to store output */
647   data->set.fwrite = (curl_write_callback)fwrite;
648
649   /* use fread as default function to read input */
650   data->set.fread = (curl_read_callback)fread;
651
652   data->set.infilesize = -1; /* we don't know any size */
653   data->set.postfieldsize = -1;
654
655   data->state.current_speed = -1; /* init to negative == impossible */
656
657   data->set.httpreq = HTTPREQ_GET; /* Default HTTP request */
658   data->set.ftp_use_epsv = TRUE;   /* FTP defaults to EPSV operations */
659   data->set.ftp_use_eprt = TRUE;   /* FTP defaults to EPRT operations */
660
661   data->set.dns_cache_timeout = 60; /* Timeout every 60 seconds by default */
662
663   /* make libcurl quiet by default: */
664   data->set.hide_progress = TRUE;  /* CURLOPT_NOPROGRESS changes these */
665   data->progress.flags |= PGRS_HIDE;
666
667   /* Set the default size of the SSL session ID cache */
668   data->set.ssl.numsessions = 5;
669
670   data->set.proxyport = 1080;
671   data->set.proxytype = CURLPROXY_HTTP; /* defaults to HTTP proxy */
672   data->set.httpauth = CURLAUTH_BASIC;  /* defaults to basic */
673   data->set.proxyauth = CURLAUTH_BASIC; /* defaults to basic */
674
675   /*
676    * libcurl 7.10 introduced SSL verification *by default*! This needs to be
677    * switched off unless wanted.
678    */
679   data->set.ssl.verifypeer = TRUE;
680   data->set.ssl.verifyhost = 2;
681 #ifdef CURL_CA_BUNDLE
682   /* This is our prefered CA cert bundle since install time */
683   data->set.ssl.CAfile = (char *)CURL_CA_BUNDLE;
684 #endif
685 }