Fixed ftp support with uClibc due to differing inet_ntoa_r() behaviour.
[platform/upstream/curl.git] / lib / url.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 /* -- WIN32 approved -- */
25
26 #include "setup.h"
27
28 #include <stdio.h>
29 #include <string.h>
30 #include <stdarg.h>
31 #include <stdlib.h>
32 #include <ctype.h>
33 #ifdef HAVE_SYS_TYPES_H
34 #include <sys/types.h>
35 #endif
36 #ifdef HAVE_SYS_STAT_H
37 #include <sys/stat.h>
38 #endif
39 #include <errno.h>
40
41 #if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
42 #include <time.h>
43 #include <io.h>
44 #else
45 #ifdef HAVE_SYS_SOCKET_H
46 #include <sys/socket.h>
47 #endif
48 #include <netinet/in.h>
49 #include <sys/time.h>
50 #ifdef HAVE_UNISTD_H
51 #include <unistd.h>
52 #endif
53 #include <netdb.h>
54 #ifdef HAVE_ARPA_INET_H
55 #include <arpa/inet.h>
56 #endif
57 #ifdef HAVE_NET_IF_H
58 #include <net/if.h>
59 #endif
60 #include <sys/ioctl.h>
61 #include <signal.h>
62
63 #ifdef HAVE_SYS_PARAM_H
64 #include <sys/param.h>
65 #endif
66
67 #ifdef VMS
68 #include <in.h>
69 #include <inet.h>
70 #endif
71
72 #ifdef HAVE_SETJMP_H
73 #include <setjmp.h>
74 #endif
75
76 #ifndef HAVE_SOCKET
77 #error "We can't compile without socket() support!"
78 #endif
79
80
81 #endif
82
83 #ifdef USE_LIBIDN
84 #include <idna.h>
85 #include <tld.h>
86 #include <stringprep.h>
87 #ifdef HAVE_IDN_FREE_H
88 #include <idn-free.h>
89 #else
90 void idn_free (void *ptr); /* prototype from idn-free.h, not provided by
91                               libidn 0.4.5's make install! */
92 #endif
93 #ifndef HAVE_IDN_FREE
94 /* if idn_free() was not found in this version of libidn, use plain free()
95    instead */
96 #define idn_free(x) (free)(x)
97 #endif
98 #endif
99
100 #include "urldata.h"
101 #include "netrc.h"
102
103 #include "formdata.h"
104 #include "base64.h"
105 #include "ssluse.h"
106 #include "hostip.h"
107 #include "transfer.h"
108 #include "sendf.h"
109 #include "progress.h"
110 #include "cookie.h"
111 #include "strequal.h"
112 #include "strerror.h"
113 #include "escape.h"
114 #include "strtok.h"
115 #include "share.h"
116 #include "content_encoding.h"
117 #include "http_digest.h"
118 #include "http_negotiate.h"
119 #include "select.h"
120 #include "multiif.h"
121
122 /* And now for the protocols */
123 #include "ftp.h"
124 #include "dict.h"
125 #include "telnet.h"
126 #include "http.h"
127 #include "file.h"
128 #include "ldap.h"
129 #include "url.h"
130 #include "connect.h"
131 #include "inet_ntop.h"
132 #include "http_ntlm.h"
133 #include <ca-bundle.h>
134
135 #if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL)
136 #include "inet_ntoa_r.h"
137 #endif
138
139 #define _MPRINTF_REPLACE /* use our functions only */
140 #include <curl/mprintf.h>
141
142 #ifdef HAVE_KRB4
143 #include "krb4.h"
144 #endif
145 #include "memory.h"
146
147 /* The last #include file should be: */
148 #include "memdebug.h"
149
150 /* Local static prototypes */
151 static long ConnectionKillOne(struct SessionHandle *data);
152 static bool ConnectionExists(struct SessionHandle *data,
153                              struct connectdata *needle,
154                              struct connectdata **usethis);
155 static long ConnectionStore(struct SessionHandle *data,
156                             struct connectdata *conn);
157 static bool safe_strequal(char* str1, char* str2);
158
159 #ifndef USE_ARES
160 /* not for Win32, unless it is cygwin
161    not for ares builds */
162 #if !defined(WIN32) || defined(__CYGWIN32__)
163
164 #ifndef RETSIGTYPE
165 #define RETSIGTYPE void
166 #endif
167 #ifdef HAVE_SIGSETJMP
168 extern sigjmp_buf curl_jmpenv;
169 #endif
170 static
171 RETSIGTYPE alarmfunc(int sig)
172 {
173   /* this is for "-ansi -Wall -pedantic" to stop complaining!   (rabe) */
174   (void)sig;
175 #ifdef HAVE_SIGSETJMP
176   siglongjmp(curl_jmpenv, 1);
177 #endif
178   return;
179 }
180 #endif
181 #endif /* USE_ARES */
182
183 void Curl_safefree(void *ptr)
184 {
185   if(ptr)
186     free(ptr);
187 }
188
189 /*
190  * This is the internal function curl_easy_cleanup() calls. This should
191  * cleanup and free all resources associated with this sessionhandle.
192  *
193  * NOTE: if we ever add something that attempts to write to a socket or
194  * similar here, we must ignore SIGPIPE first. It is currently only done
195  * when curl_easy_perform() is invoked.
196  */
197
198 CURLcode Curl_close(struct SessionHandle *data)
199 {
200   if(data->multi) {
201     /* this handle is still part of a multi handle, take care of this first */
202     Curl_multi_rmeasy(data->multi, data);
203   }
204   /* Loop through all open connections and kill them one by one */
205   while(-1 != ConnectionKillOne(data))
206     ; /* empty loop */
207
208   if ( ! (data->share && data->share->hostcache) ) {
209     if ( !Curl_global_host_cache_use(data)) {
210       Curl_hash_destroy(data->hostcache);
211     }
212   }
213
214 #ifdef USE_SSLEAY
215   /* Close down all open SSL info and sessions */
216   Curl_SSL_Close_All(data);
217 #endif
218
219   Curl_safefree(data->state.first_host);
220   Curl_safefree(data->state.scratch);
221
222   if(data->change.proxy_alloc)
223     free(data->change.proxy);
224
225   if(data->change.referer_alloc)
226     free(data->change.referer);
227
228   if(data->change.url_alloc)
229     free(data->change.url);
230
231   Curl_safefree(data->state.headerbuff);
232
233 #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
234   if(data->change.cookielist) /* clean up list if any */
235     curl_slist_free_all(data->change.cookielist);
236
237   Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
238   if(data->set.cookiejar) {
239     /* we have a "destination" for all the cookies to get dumped to */
240     if(Curl_cookie_output(data->cookies, data->set.cookiejar))
241       infof(data, "WARNING: failed to save cookies in %s\n",
242             data->set.cookiejar);
243   }
244
245   if( !data->share || (data->cookies != data->share->cookies) ) {
246     Curl_cookie_cleanup(data->cookies);
247   }
248   Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
249 #endif
250
251 #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH)
252   Curl_digest_cleanup(data);
253 #endif
254
255   /* free the connection cache */
256   free(data->state.connects);
257
258   Curl_safefree(data->info.contenttype);
259
260 #ifdef USE_ARES
261   /* this destroys the channel and we cannot use it anymore after this */
262   ares_destroy(data->state.areschannel);
263 #endif
264
265   /* No longer a dirty share, if it exists */
266   if (data->share)
267     data->share->dirty--;
268
269   free(data);
270   return CURLE_OK;
271 }
272
273 /**
274  * Curl_open()
275  *
276  * @param curl is a pointer to a sessionhandle pointer that gets set by this
277  * function.
278  * @return CURLcode
279  */
280
281 CURLcode Curl_open(struct SessionHandle **curl)
282 {
283   CURLcode res = CURLE_OK;
284   struct SessionHandle *data;
285   /* Very simple start-up: alloc the struct, init it with zeroes and return */
286   data = (struct SessionHandle *)calloc(1, sizeof(struct SessionHandle));
287   if(!data)
288     /* this is a very serious error */
289     return CURLE_OUT_OF_MEMORY;
290
291 #ifdef USE_ARES
292   if(ARES_SUCCESS != ares_init(&data->state.areschannel)) {
293     free(data);
294     return CURLE_FAILED_INIT;
295   }
296   /* make sure that all other returns from this function should destroy the
297      ares channel before returning error! */
298 #endif
299
300   /* We do some initial setup here, all those fields that can't be just 0 */
301
302   data->state.headerbuff=(char*)malloc(HEADERSIZE);
303   if(!data->state.headerbuff)
304     res = CURLE_OUT_OF_MEMORY;
305   else {
306     data->state.headersize=HEADERSIZE;
307
308     data->set.out = stdout; /* default output to stdout */
309     data->set.in  = stdin;  /* default input from stdin */
310     data->set.err  = stderr;  /* default stderr to stderr */
311
312     /* use fwrite as default function to store output */
313     data->set.fwrite = (curl_write_callback)fwrite;
314
315     /* use fread as default function to read input */
316     data->set.fread = (curl_read_callback)fread;
317
318     data->set.infilesize = -1; /* we don't know any size */
319     data->set.postfieldsize = -1;
320
321     data->state.current_speed = -1; /* init to negative == impossible */
322
323     data->set.httpreq = HTTPREQ_GET; /* Default HTTP request */
324     data->set.ftp_use_epsv = TRUE;   /* FTP defaults to EPSV operations */
325     data->set.ftp_use_eprt = TRUE;   /* FTP defaults to EPRT operations */
326     data->set.ftp_use_lprt = TRUE;   /* FTP defaults to EPRT operations */
327
328     data->set.dns_cache_timeout = 60; /* Timeout every 60 seconds by default */
329
330     /* make libcurl quiet by default: */
331     data->set.hide_progress = TRUE;  /* CURLOPT_NOPROGRESS changes these */
332     data->progress.flags |= PGRS_HIDE;
333
334     /* Set the default size of the SSL session ID cache */
335     data->set.ssl.numsessions = 5;
336
337     data->set.proxyport = 1080;
338     data->set.proxytype = CURLPROXY_HTTP; /* defaults to HTTP proxy */
339     data->set.httpauth = CURLAUTH_BASIC;  /* defaults to basic */
340     data->set.proxyauth = CURLAUTH_BASIC; /* defaults to basic */
341
342     /* create an array with connection data struct pointers */
343     data->state.numconnects = 5; /* hard-coded right now */
344     data->state.connects = (struct connectdata **)
345       malloc(sizeof(struct connectdata *) * data->state.numconnects);
346
347     if(!data->state.connects)
348       res = CURLE_OUT_OF_MEMORY;
349     else
350       memset(data->state.connects, 0,
351              sizeof(struct connectdata *)*data->state.numconnects);
352
353     /*
354      * libcurl 7.10 introduced SSL verification *by default*! This needs to be
355      * switched off unless wanted.
356      */
357     data->set.ssl.verifypeer = TRUE;
358     data->set.ssl.verifyhost = 2;
359 #ifdef CURL_CA_BUNDLE
360     /* This is our prefered CA cert bundle since install time */
361     data->set.ssl.CAfile = (char *)CURL_CA_BUNDLE;
362 #endif
363   }
364
365   if(res) {
366 #ifdef USE_ARES
367     ares_destroy(data->state.areschannel);
368 #endif
369     if(data->state.headerbuff)
370       free(data->state.headerbuff);
371     free(data);
372     data = NULL;
373   }
374
375   *curl = data;
376   return CURLE_OK;
377 }
378
379 CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
380 {
381   va_list param;
382   char *argptr;
383   CURLcode result = CURLE_OK;
384
385   va_start(param, option);
386
387   switch(option) {
388   case CURLOPT_DNS_CACHE_TIMEOUT:
389     data->set.dns_cache_timeout = va_arg(param, int);
390     break;
391   case CURLOPT_DNS_USE_GLOBAL_CACHE:
392     {
393       int use_cache = va_arg(param, int);
394       if (use_cache) {
395         Curl_global_host_cache_init();
396       }
397
398       data->set.global_dns_cache = use_cache;
399     }
400     break;
401   case CURLOPT_SSL_CIPHER_LIST:
402     /* set a list of cipher we want to use in the SSL connection */
403     data->set.ssl.cipher_list = va_arg(param, char *);
404     break;
405
406   case CURLOPT_RANDOM_FILE:
407     /*
408      * This is the path name to a file that contains random data to seed
409      * the random SSL stuff with. The file is only used for reading.
410      */
411     data->set.ssl.random_file = va_arg(param, char *);
412     break;
413   case CURLOPT_EGDSOCKET:
414     /*
415      * The Entropy Gathering Daemon socket pathname
416      */
417     data->set.ssl.egdsocket = va_arg(param, char *);
418     break;
419   case CURLOPT_MAXCONNECTS:
420     /*
421      * Set the absolute number of maximum simultaneous alive connection that
422      * libcurl is allowed to have.
423      */
424     {
425       long newconnects= va_arg(param, long);
426       struct connectdata **newptr;
427       long i;
428
429       if(newconnects < data->state.numconnects) {
430         /* Since this number is *decreased* from the existing number, we must
431            close the possibly open connections that live on the indexes that
432            are being removed! */
433         for(i=newconnects; i< data->state.numconnects; i++)
434           Curl_disconnect(data->state.connects[i]);
435       }
436       if(newconnects) {
437         newptr= (struct connectdata **)
438           realloc(data->state.connects,
439                   sizeof(struct connectdata *) * newconnects);
440         if(!newptr)
441           /* we closed a few connections in vain, but so what? */
442           return CURLE_OUT_OF_MEMORY;
443
444         /* nullify the newly added pointers */
445         for(i=data->state.numconnects; i<newconnects; i++) {
446           newptr[i] = NULL;
447         }
448
449         data->state.connects = newptr;
450         data->state.numconnects = newconnects;
451       }
452       else {
453         /* zero makes NO cache at all */
454         if(data->state.connects)
455           free(data->state.connects);
456         data->state.connects=NULL;
457         data->state.numconnects=0;
458       }
459     }
460     break;
461   case CURLOPT_FORBID_REUSE:
462     /*
463      * When this transfer is done, it must not be left to be reused by a
464      * subsequent transfer but shall be closed immediately.
465      */
466     data->set.reuse_forbid = va_arg(param, long)?TRUE:FALSE;
467     break;
468   case CURLOPT_FRESH_CONNECT:
469     /*
470      * This transfer shall not use a previously cached connection but
471      * should be made with a fresh new connect!
472      */
473     data->set.reuse_fresh = va_arg(param, long)?TRUE:FALSE;
474     break;
475   case CURLOPT_VERBOSE:
476     /*
477      * Verbose means infof() calls that give a lot of information about
478      * the connection and transfer procedures as well as internal choices.
479      */
480     data->set.verbose = va_arg(param, long)?TRUE:FALSE;
481     break;
482   case CURLOPT_HEADER:
483     /*
484      * Set to include the header in the general data output stream.
485      */
486     data->set.include_header = va_arg(param, long)?TRUE:FALSE;
487     break;
488   case CURLOPT_NOPROGRESS:
489     /*
490      * Shut off the internal supported progress meter
491      */
492     data->set.hide_progress = va_arg(param, long)?TRUE:FALSE;
493     if(data->set.hide_progress)
494       data->progress.flags |= PGRS_HIDE;
495     else
496       data->progress.flags &= ~PGRS_HIDE;
497     break;
498   case CURLOPT_NOBODY:
499     /*
500      * Do not include the body part in the output data stream.
501      */
502     data->set.opt_no_body = va_arg(param, long)?TRUE:FALSE;
503     if(data->set.opt_no_body)
504       /* in HTTP lingo, this means using the HEAD request */
505       data->set.httpreq = HTTPREQ_HEAD;
506     break;
507   case CURLOPT_FAILONERROR:
508     /*
509      * Don't output the >=300 error code HTML-page, but instead only
510      * return error.
511      */
512     data->set.http_fail_on_error = va_arg(param, long)?TRUE:FALSE;
513     break;
514   case CURLOPT_UPLOAD:
515   case CURLOPT_PUT:
516     /*
517      * We want to sent data to the remote host. If this is HTTP, that equals
518      * using the PUT request.
519      */
520     data->set.upload = va_arg(param, long)?TRUE:FALSE;
521     if(data->set.upload)
522       /* If this is HTTP, PUT is what's needed to "upload" */
523       data->set.httpreq = HTTPREQ_PUT;
524     break;
525   case CURLOPT_FILETIME:
526     /*
527      * Try to get the file time of the remote document. The time will
528      * later (possibly) become available using curl_easy_getinfo().
529      */
530     data->set.get_filetime = va_arg(param, long)?TRUE:FALSE;
531     break;
532   case CURLOPT_FTP_CREATE_MISSING_DIRS:
533     /*
534      * An FTP option that modifies an upload to create missing directories on
535      * the server.
536      */
537     data->set.ftp_create_missing_dirs = va_arg( param , long )?TRUE:FALSE;
538     break;
539   case CURLOPT_FTP_RESPONSE_TIMEOUT:
540     /*
541      * An FTP option that specifies how quickly an FTP response must be
542      * obtained before it is considered failure.
543      */
544     data->set.ftp_response_timeout = va_arg( param , long );
545     break;
546   case CURLOPT_FTPLISTONLY:
547     /*
548      * An FTP option that changes the command to one that asks for a list
549      * only, no file info details.
550      */
551     data->set.ftp_list_only = va_arg(param, long)?TRUE:FALSE;
552     break;
553   case CURLOPT_FTPAPPEND:
554     /*
555      * We want to upload and append to an existing (FTP) file.
556      */
557     data->set.ftp_append = va_arg(param, long)?TRUE:FALSE;
558     break;
559   case CURLOPT_NETRC:
560     /*
561      * Parse the $HOME/.netrc file
562      */
563     data->set.use_netrc = (enum CURL_NETRC_OPTION)va_arg(param, long);
564     break;
565   case CURLOPT_NETRC_FILE:
566     /*
567      * Use this file instead of the $HOME/.netrc file
568      */
569     data->set.netrc_file = va_arg(param, char *);
570     break;
571   case CURLOPT_TRANSFERTEXT:
572     /*
573      * This option was previously named 'FTPASCII'. Renamed to work with
574      * more protocols than merely FTP.
575      *
576      * Transfer using ASCII (instead of BINARY).
577      */
578     data->set.ftp_ascii = va_arg(param, long)?TRUE:FALSE;
579     break;
580   case CURLOPT_TIMECONDITION:
581     /*
582      * Set HTTP time condition. This must be one of the defines in the
583      * curl/curl.h header file.
584      */
585     data->set.timecondition = (curl_TimeCond)va_arg(param, long);
586     break;
587   case CURLOPT_TIMEVALUE:
588     /*
589      * This is the value to compare with the remote document with the
590      * method set with CURLOPT_TIMECONDITION
591      */
592     data->set.timevalue = (time_t)va_arg(param, long);
593     break;
594   case CURLOPT_SSLVERSION:
595     /*
596      * Set explicit SSL version to try to connect with, as some SSL
597      * implementations are lame.
598      */
599     data->set.ssl.version = va_arg(param, long);
600     break;
601
602 #ifndef CURL_DISABLE_HTTP
603   case CURLOPT_AUTOREFERER:
604     /*
605      * Switch on automatic referer that gets set if curl follows locations.
606      */
607     data->set.http_auto_referer = va_arg(param, long)?1:0;
608     break;
609
610   case CURLOPT_ENCODING:
611     /*
612      * String to use at the value of Accept-Encoding header.
613      *
614      * If the encoding is set to "" we use an Accept-Encoding header that
615      * encompasses all the encodings we support.
616      * If the encoding is set to NULL we don't send an Accept-Encoding header
617      * and ignore an received Content-Encoding header.
618      *
619      */
620     data->set.encoding = va_arg(param, char *);
621     if(data->set.encoding && !*data->set.encoding)
622       data->set.encoding = (char*)ALL_CONTENT_ENCODINGS;
623     break;
624
625   case CURLOPT_FOLLOWLOCATION:
626     /*
627      * Follow Location: header hints on a HTTP-server.
628      */
629     data->set.http_follow_location = va_arg(param, long)?TRUE:FALSE;
630     break;
631
632   case CURLOPT_UNRESTRICTED_AUTH:
633     /*
634      * Send authentication (user+password) when following locations, even when
635      * hostname changed.
636      */
637     data->set.http_disable_hostname_check_before_authentication =
638       va_arg(param, long)?TRUE:FALSE;
639     break;
640
641   case CURLOPT_MAXREDIRS:
642     /*
643      * The maximum amount of hops you allow curl to follow Location:
644      * headers. This should mostly be used to detect never-ending loops.
645      */
646     data->set.maxredirs = va_arg(param, long);
647     break;
648
649   case CURLOPT_POST:
650     /* Does this option serve a purpose anymore? Yes it does, when
651        CURLOPT_POSTFIELDS isn't used and the POST data is read off the
652        callback! */
653     if(va_arg(param, long))
654       data->set.httpreq = HTTPREQ_POST;
655     else
656       data->set.httpreq = HTTPREQ_GET;
657     break;
658
659   case CURLOPT_POSTFIELDS:
660     /*
661      * A string with POST data. Makes curl HTTP POST. Even if it is NULL.
662      */
663     data->set.postfields = va_arg(param, char *);
664     data->set.httpreq = HTTPREQ_POST;
665     break;
666
667   case CURLOPT_POSTFIELDSIZE:
668     /*
669      * The size of the POSTFIELD data to prevent libcurl to do strlen() to
670      * figure it out. Enables binary posts.
671      */
672     data->set.postfieldsize = va_arg(param, long);
673     break;
674
675   case CURLOPT_POSTFIELDSIZE_LARGE:
676     /*
677      * The size of the POSTFIELD data to prevent libcurl to do strlen() to
678      * figure it out. Enables binary posts.
679      */
680     data->set.postfieldsize = va_arg(param, curl_off_t);
681     break;
682
683   case CURLOPT_HTTPPOST:
684     /*
685      * Set to make us do HTTP POST
686      */
687     data->set.httppost = va_arg(param, struct curl_httppost *);
688     data->set.httpreq = HTTPREQ_POST_FORM;
689     break;
690
691   case CURLOPT_REFERER:
692     /*
693      * String to set in the HTTP Referer: field.
694      */
695     if(data->change.referer_alloc) {
696       free(data->change.referer);
697       data->change.referer_alloc = FALSE;
698     }
699     data->set.set_referer = va_arg(param, char *);
700     data->change.referer = data->set.set_referer;
701     break;
702
703   case CURLOPT_USERAGENT:
704     /*
705      * String to use in the HTTP User-Agent field
706      */
707     data->set.useragent = va_arg(param, char *);
708     break;
709
710   case CURLOPT_HTTPHEADER:
711     /*
712      * Set a list with HTTP headers to use (or replace internals with)
713      */
714     data->set.headers = va_arg(param, struct curl_slist *);
715     break;
716
717   case CURLOPT_HTTP200ALIASES:
718     /*
719      * Set a list of aliases for HTTP 200 in response header
720      */
721     data->set.http200aliases = va_arg(param, struct curl_slist *);
722     break;
723
724 #if !defined(CURL_DISABLE_COOKIES)
725   case CURLOPT_COOKIE:
726     /*
727      * Cookie string to send to the remote server in the request.
728      */
729     data->set.cookie = va_arg(param, char *);
730     break;
731
732   case CURLOPT_COOKIEFILE:
733     /*
734      * Set cookie file to read and parse. Can be used multiple times.
735      */
736     argptr = (char *)va_arg(param, void *);
737     if(argptr) {
738       struct curl_slist *cl;
739       /* append the cookie file name to the list of file names, and deal with
740          them later */
741       cl = curl_slist_append(data->change.cookielist, argptr);
742
743       if(!cl)
744         return CURLE_OUT_OF_MEMORY;
745
746       data->change.cookielist = cl;
747     }
748     break;
749
750   case CURLOPT_COOKIEJAR:
751     /*
752      * Set cookie file name to dump all cookies to when we're done.
753      */
754     data->set.cookiejar = (char *)va_arg(param, void *);
755
756     /*
757      * Activate the cookie parser. This may or may not already
758      * have been made.
759      */
760     data->cookies = Curl_cookie_init(data, NULL, data->cookies,
761                                      data->set.cookiesession);
762     break;
763
764   case CURLOPT_COOKIESESSION:
765     /*
766      * Set this option to TRUE to start a new "cookie session". It will
767      * prevent the forthcoming read-cookies-from-file actions to accept
768      * cookies that are marked as being session cookies, as they belong to a
769      * previous session.
770      *
771      * In the original Netscape cookie spec, "session cookies" are cookies
772      * with no expire date set. RFC2109 describes the same action if no
773      * 'Max-Age' is set and RFC2965 includes the RFC2109 description and adds
774      * a 'Discard' action that can enforce the discard even for cookies that
775      * have a Max-Age.
776      *
777      * We run mostly with the original cookie spec, as hardly anyone implements
778      * anything else.
779      */
780     data->set.cookiesession = (bool)va_arg(param, long);
781     break;
782 #endif /* CURL_DISABLE_COOKIES */
783
784   case CURLOPT_HTTPGET:
785     /*
786      * Set to force us do HTTP GET
787      */
788     if(va_arg(param, long)) {
789       data->set.httpreq = HTTPREQ_GET;
790       data->set.upload = FALSE; /* switch off upload */
791     }
792     break;
793
794   case CURLOPT_HTTP_VERSION:
795     /*
796      * This sets a requested HTTP version to be used. The value is one of
797      * the listed enums in curl/curl.h.
798      */
799     data->set.httpversion = va_arg(param, long);
800     break;
801
802   case CURLOPT_HTTPPROXYTUNNEL:
803     /*
804      * Tunnel operations through the proxy instead of normal proxy use
805      */
806     data->set.tunnel_thru_httpproxy = va_arg(param, long)?TRUE:FALSE;
807     break;
808
809   case CURLOPT_CUSTOMREQUEST:
810     /*
811      * Set a custom string to use as request
812      */
813     data->set.customrequest = va_arg(param, char *);
814
815     /* we don't set
816        data->set.httpreq = HTTPREQ_CUSTOM;
817        here, we continue as if we were using the already set type
818        and this just changes the actual request keyword */
819     break;
820
821   case CURLOPT_PROXYPORT:
822     /*
823      * Explicitly set HTTP proxy port number.
824      */
825     data->set.proxyport = va_arg(param, long);
826     break;
827
828   case CURLOPT_HTTPAUTH:
829     /*
830      * Set HTTP Authentication type BITMASK.
831      */
832   {
833     long auth = va_arg(param, long);
834     /* switch off bits we can't support */
835 #if ! defined(USE_SSLEAY) && !defined(USE_WINDOWS_SSPI)
836     auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */
837 #endif
838 #ifndef HAVE_GSSAPI
839     auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI */
840 #endif
841     if(!auth)
842       return CURLE_FAILED_INIT; /* no supported types left! */
843
844     data->set.httpauth = auth;
845   }
846   break;
847
848   case CURLOPT_PROXYAUTH:
849     /*
850      * Set HTTP Authentication type BITMASK.
851      */
852   {
853     long auth = va_arg(param, long);
854     /* switch off bits we can't support */
855 #ifndef USE_SSLEAY
856     auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */
857 #endif
858 #ifndef HAVE_GSSAPI
859     auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI */
860 #endif
861     if(!auth)
862       return CURLE_FAILED_INIT; /* no supported types left! */
863
864     data->set.proxyauth = auth;
865   }
866   break;
867 #endif   /* CURL_DISABLE_HTTP */
868
869   case CURLOPT_PROXY:
870     /*
871      * Set proxy server:port to use as HTTP proxy.
872      *
873      * If the proxy is set to "" we explicitly say that we don't want to use a
874      * proxy (even though there might be environment variables saying so).
875      *
876      * Setting it to NULL, means no proxy but allows the environment variables
877      * to decide for us.
878      */
879     if(data->change.proxy_alloc) {
880       /*
881        * The already set string is allocated, free that first
882        */
883       data->change.proxy_alloc=FALSE;;
884       free(data->change.proxy);
885     }
886     data->set.set_proxy = va_arg(param, char *);
887     data->change.proxy = data->set.set_proxy;
888     break;
889
890   case CURLOPT_WRITEHEADER:
891     /*
892      * Custom pointer to pass the header write callback function
893      */
894     data->set.writeheader = (void *)va_arg(param, void *);
895     break;
896   case CURLOPT_ERRORBUFFER:
897     /*
898      * Error buffer provided by the caller to get the human readable
899      * error string in.
900      */
901     data->set.errorbuffer = va_arg(param, char *);
902     break;
903   case CURLOPT_FILE:
904     /*
905      * FILE pointer to write to or include in the data write callback
906      */
907     data->set.out = va_arg(param, FILE *);
908     break;
909   case CURLOPT_FTPPORT:
910     /*
911      * Use FTP PORT, this also specifies which IP address to use
912      */
913     data->set.ftpport = va_arg(param, char *);
914     data->set.ftp_use_port = data->set.ftpport?1:0;
915     break;
916
917   case CURLOPT_FTP_USE_EPRT:
918     data->set.ftp_use_eprt = va_arg(param, long)?TRUE:FALSE;
919     data->set.ftp_use_lprt = data->set.ftp_use_eprt;
920     break;
921
922   case CURLOPT_FTP_USE_EPSV:
923     data->set.ftp_use_epsv = va_arg(param, long)?TRUE:FALSE;
924     break;
925
926   case CURLOPT_INFILE:
927     /*
928      * FILE pointer to read the file to be uploaded from. Or possibly
929      * used as argument to the read callback.
930      */
931     data->set.in = va_arg(param, FILE *);
932     break;
933   case CURLOPT_INFILESIZE:
934     /*
935      * If known, this should inform curl about the file size of the
936      * to-be-uploaded file.
937      */
938     data->set.infilesize = va_arg(param, long);
939     break;
940   case CURLOPT_INFILESIZE_LARGE:
941     /*
942      * If known, this should inform curl about the file size of the
943      * to-be-uploaded file.
944      */
945     data->set.infilesize = va_arg(param, curl_off_t);
946     break;
947   case CURLOPT_LOW_SPEED_LIMIT:
948     /*
949      * The low speed limit that if transfers are below this for
950      * CURLOPT_LOW_SPEED_TIME, the transfer is aborted.
951      */
952     data->set.low_speed_limit=va_arg(param, long);
953     break;
954   case CURLOPT_LOW_SPEED_TIME:
955     /*
956      * The low speed time that if transfers are below the set
957      * CURLOPT_LOW_SPEED_LIMIT during this time, the transfer is aborted.
958      */
959     data->set.low_speed_time=va_arg(param, long);
960     break;
961   case CURLOPT_URL:
962     /*
963      * The URL to fetch.
964      */
965     if(data->change.url_alloc) {
966       /* the already set URL is allocated, free it first! */
967       free(data->change.url);
968       data->change.url_alloc=FALSE;
969     }
970     data->set.set_url = va_arg(param, char *);
971     data->change.url = data->set.set_url;
972     data->change.url_changed = TRUE;
973     break;
974   case CURLOPT_PORT:
975     /*
976      * The port number to use when getting the URL
977      */
978     data->set.use_port = va_arg(param, long);
979     break;
980   case CURLOPT_TIMEOUT:
981     /*
982      * The maximum time you allow curl to use for a single transfer
983      * operation.
984      */
985     data->set.timeout = va_arg(param, long);
986     break;
987   case CURLOPT_CONNECTTIMEOUT:
988     /*
989      * The maximum time you allow curl to use to connect.
990      */
991     data->set.connecttimeout = va_arg(param, long);
992     break;
993
994   case CURLOPT_USERPWD:
995     /*
996      * user:password to use in the operation
997      */
998     data->set.userpwd = va_arg(param, char *);
999     break;
1000   case CURLOPT_POSTQUOTE:
1001     /*
1002      * List of RAW FTP commands to use after a transfer
1003      */
1004     data->set.postquote = va_arg(param, struct curl_slist *);
1005     break;
1006   case CURLOPT_PREQUOTE:
1007     /*
1008      * List of RAW FTP commands to use prior to RETR (Wesley Laxton)
1009      */
1010     data->set.prequote = va_arg(param, struct curl_slist *);
1011     break;
1012   case CURLOPT_QUOTE:
1013     /*
1014      * List of RAW FTP commands to use before a transfer
1015      */
1016     data->set.quote = va_arg(param, struct curl_slist *);
1017     break;
1018   case CURLOPT_PROGRESSFUNCTION:
1019     /*
1020      * Progress callback function
1021      */
1022     data->set.fprogress = va_arg(param, curl_progress_callback);
1023     if(data->set.fprogress)
1024       data->progress.callback = TRUE; /* no longer internal */
1025     else
1026       data->progress.callback = FALSE; /* NULL enforces internal */
1027
1028     break;
1029   case CURLOPT_PROGRESSDATA:
1030     /*
1031      * Custom client data to pass to the progress callback
1032      */
1033     data->set.progress_client = va_arg(param, void *);
1034     break;
1035   case CURLOPT_PROXYUSERPWD:
1036     /*
1037      * user:password needed to use the proxy
1038      */
1039     data->set.proxyuserpwd = va_arg(param, char *);
1040     break;
1041   case CURLOPT_RANGE:
1042     /*
1043      * What range of the file you want to transfer
1044      */
1045     data->set.set_range = va_arg(param, char *);
1046     break;
1047   case CURLOPT_RESUME_FROM:
1048     /*
1049      * Resume transfer at the give file position
1050      */
1051     data->set.set_resume_from = va_arg(param, long);
1052     break;
1053   case CURLOPT_RESUME_FROM_LARGE:
1054     /*
1055      * Resume transfer at the give file position
1056      */
1057     data->set.set_resume_from = va_arg(param, curl_off_t);
1058     break;
1059   case CURLOPT_DEBUGFUNCTION:
1060     /*
1061      * stderr write callback.
1062      */
1063     data->set.fdebug = va_arg(param, curl_debug_callback);
1064     /*
1065      * if the callback provided is NULL, it'll use the default callback
1066      */
1067     break;
1068   case CURLOPT_DEBUGDATA:
1069     /*
1070      * Set to a void * that should receive all error writes. This
1071      * defaults to CURLOPT_STDERR for normal operations.
1072      */
1073     data->set.debugdata = va_arg(param, void *);
1074     break;
1075   case CURLOPT_STDERR:
1076     /*
1077      * Set to a FILE * that should receive all error writes. This
1078      * defaults to stderr for normal operations.
1079      */
1080     data->set.err = va_arg(param, FILE *);
1081     if(!data->set.err)
1082       data->set.err = stderr;
1083     break;
1084   case CURLOPT_HEADERFUNCTION:
1085     /*
1086      * Set header write callback
1087      */
1088     data->set.fwrite_header = va_arg(param, curl_write_callback);
1089     break;
1090   case CURLOPT_WRITEFUNCTION:
1091     /*
1092      * Set data write callback
1093      */
1094     data->set.fwrite = va_arg(param, curl_write_callback);
1095     if(!data->set.fwrite)
1096       /* When set to NULL, reset to our internal default function */
1097       data->set.fwrite = (curl_write_callback)fwrite;
1098     break;
1099   case CURLOPT_READFUNCTION:
1100     /*
1101      * Read data callback
1102      */
1103     data->set.fread = va_arg(param, curl_read_callback);
1104     if(!data->set.fread)
1105       /* When set to NULL, reset to our internal default function */
1106       data->set.fread = (curl_read_callback)fread;
1107     break;
1108   case CURLOPT_IOCTLFUNCTION:
1109     /*
1110      * I/O control callback. Might be NULL.
1111      */
1112     data->set.ioctl = va_arg(param, curl_ioctl_callback);
1113     break;
1114   case CURLOPT_IOCTLDATA:
1115     /*
1116      * I/O control data pointer. Might be NULL.
1117      */
1118     data->set.ioctl_client = va_arg(param, void *);
1119     break;
1120   case CURLOPT_SSLCERT:
1121     /*
1122      * String that holds file name of the SSL certificate to use
1123      */
1124     data->set.cert = va_arg(param, char *);
1125     break;
1126   case CURLOPT_SSLCERTTYPE:
1127     /*
1128      * String that holds file type of the SSL certificate to use
1129      */
1130     data->set.cert_type = va_arg(param, char *);
1131     break;
1132   case CURLOPT_SSLKEY:
1133     /*
1134      * String that holds file name of the SSL certificate to use
1135      */
1136     data->set.key = va_arg(param, char *);
1137     break;
1138   case CURLOPT_SSLKEYTYPE:
1139     /*
1140      * String that holds file type of the SSL certificate to use
1141      */
1142     data->set.key_type = va_arg(param, char *);
1143     break;
1144   case CURLOPT_SSLKEYPASSWD:
1145     /*
1146      * String that holds the SSL private key password.
1147      */
1148     data->set.key_passwd = va_arg(param, char *);
1149     break;
1150   case CURLOPT_SSLENGINE:
1151     /*
1152      * String that holds the SSL crypto engine.
1153      */
1154     argptr = va_arg(param, char *);
1155     if (argptr && argptr[0])
1156        result = Curl_SSL_set_engine(data, argptr);
1157     break;
1158
1159   case CURLOPT_SSLENGINE_DEFAULT:
1160     /*
1161      * flag to set engine as default.
1162      */
1163     result = Curl_SSL_set_engine_default(data);
1164     break;
1165   case CURLOPT_CRLF:
1166     /*
1167      * Kludgy option to enable CRLF convertions. Subject for removal.
1168      */
1169     data->set.crlf = va_arg(param, long)?TRUE:FALSE;
1170     break;
1171   case CURLOPT_INTERFACE:
1172     /*
1173      * Set what interface to bind to when performing an operation and thus
1174      * what from-IP your connection will use.
1175      */
1176     data->set.device = va_arg(param, char *);
1177     break;
1178   case CURLOPT_KRB4LEVEL:
1179     /*
1180      * A string that defines the krb4 security level.
1181      */
1182     data->set.krb4_level = va_arg(param, char *);
1183     data->set.krb4=data->set.krb4_level?TRUE:FALSE;
1184     break;
1185   case CURLOPT_SSL_VERIFYPEER:
1186     /*
1187      * Enable peer SSL verifying.
1188      */
1189     data->set.ssl.verifypeer = va_arg(param, long);
1190     break;
1191   case CURLOPT_SSL_VERIFYHOST:
1192     /*
1193      * Enable verification of the CN contained in the peer certificate
1194      */
1195     data->set.ssl.verifyhost = va_arg(param, long);
1196     break;
1197   case CURLOPT_SSL_CTX_FUNCTION:
1198     /*
1199      * Set a SSL_CTX callback
1200      */
1201        data->set.ssl.fsslctx = va_arg(param, curl_ssl_ctx_callback);
1202     break;
1203   case CURLOPT_SSL_CTX_DATA:
1204     /*
1205      * Set a SSL_CTX callback parameter pointer
1206      */
1207     data->set.ssl.fsslctxp = va_arg(param, void *);
1208     break;
1209   case CURLOPT_CAINFO:
1210     /*
1211      * Set CA info for SSL connection. Specify file name of the CA certificate
1212      */
1213     data->set.ssl.CAfile = va_arg(param, char *);
1214     break;
1215   case CURLOPT_CAPATH:
1216     /*
1217      * Set CA path info for SSL connection. Specify directory name of the CA
1218      * certificates which have been prepared using openssl c_rehash utility.
1219      */
1220     /* This does not work on windows. */
1221     data->set.ssl.CApath = va_arg(param, char *);
1222     break;
1223   case CURLOPT_TELNETOPTIONS:
1224     /*
1225      * Set a linked list of telnet options
1226      */
1227     data->set.telnet_options = va_arg(param, struct curl_slist *);
1228     break;
1229
1230   case CURLOPT_BUFFERSIZE:
1231     /*
1232      * The application kindly asks for a differently sized receive buffer.
1233      * If it seems reasonable, we'll use it.
1234      */
1235     data->set.buffer_size = va_arg(param, long);
1236
1237     if((data->set.buffer_size> (BUFSIZE -1 )) ||
1238        (data->set.buffer_size < 1))
1239       data->set.buffer_size = 0; /* huge internal default */
1240
1241     break;
1242
1243   case CURLOPT_NOSIGNAL:
1244     /*
1245      * The application asks not to set any signal() or alarm() handlers,
1246      * even when using a timeout.
1247      */
1248     data->set.no_signal = va_arg(param, long) ? TRUE : FALSE;
1249     break;
1250
1251   case CURLOPT_SHARE:
1252     {
1253       struct Curl_share *set;
1254       set = va_arg(param, struct Curl_share *);
1255
1256       /* disconnect from old share, if any */
1257       if(data->share) {
1258         Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE);
1259
1260         if(data->share->hostcache == data->hostcache)
1261           data->hostcache = NULL;
1262
1263         if(data->share->cookies == data->cookies)
1264           data->cookies = NULL;
1265
1266         data->share->dirty--;
1267
1268         Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
1269         data->share = NULL;
1270       }
1271
1272       /* use new share if it set */
1273       data->share = set;
1274       if(data->share) {
1275
1276         Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE);
1277
1278         data->share->dirty++;
1279
1280         if(data->share->hostcache) {
1281           /* use shared host cache, first free own one if any */
1282           if(data->hostcache)
1283             Curl_hash_destroy(data->hostcache);
1284
1285           data->hostcache = data->share->hostcache;
1286         }
1287 #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
1288         if(data->share->cookies) {
1289           /* use shared cookie list, first free own one if any */
1290           if (data->cookies)
1291             Curl_cookie_cleanup(data->cookies);
1292           data->cookies = data->share->cookies;
1293         }
1294 #endif   /* CURL_DISABLE_HTTP */
1295         Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
1296
1297       }
1298 #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
1299       /* check cookie list is set */
1300       if(!data->cookies)
1301         data->cookies = Curl_cookie_init(data, NULL, NULL, TRUE );
1302 #endif   /* CURL_DISABLE_HTTP */
1303       /* check for host cache not needed,
1304        * it will be done by curl_easy_perform */
1305     }
1306     break;
1307
1308   case CURLOPT_PROXYTYPE:
1309     /*
1310      * Set proxy type. HTTP/SOCKS4/SOCKS5
1311      */
1312     data->set.proxytype = (curl_proxytype)va_arg(param, long);
1313     break;
1314
1315   case CURLOPT_PRIVATE:
1316     /*
1317      * Set private data pointer.
1318      */
1319     data->set.private_data = va_arg(param, char *);
1320     break;
1321
1322   case CURLOPT_MAXFILESIZE:
1323     /*
1324      * Set the maximum size of a file to download.
1325      */
1326     data->set.max_filesize = va_arg(param, long);
1327     break;
1328
1329   case CURLOPT_FTP_SSL:
1330     /*
1331      * Make FTP transfers attempt to use SSL/TLS.
1332      */
1333     data->set.ftp_ssl = (curl_ftpssl)va_arg(param, long);
1334     break;
1335
1336   case CURLOPT_FTPSSLAUTH:
1337     /*
1338      * Set a specific auth for FTP-SSL transfers.
1339      */
1340     data->set.ftpsslauth = (curl_ftpauth)va_arg(param, long);
1341     break;
1342
1343   case CURLOPT_IPRESOLVE:
1344     data->set.ip_version = va_arg(param, long);
1345     break;
1346
1347   case CURLOPT_MAXFILESIZE_LARGE:
1348     /*
1349      * Set the maximum size of a file to download.
1350      */
1351     data->set.max_filesize = va_arg(param, curl_off_t);
1352     break;
1353
1354   case CURLOPT_TCP_NODELAY:
1355     /*
1356      * Enable or disable TCP_NODELAY, which will disable/enable the Nagle
1357      * algorithm
1358      */
1359     data->set.tcp_nodelay = (bool)va_arg(param, long);
1360     break;
1361
1362   /*********** 3rd party transfer options ***********/
1363   case CURLOPT_SOURCE_URL:
1364     /*
1365      * SOURCE URL
1366      */
1367     data->set.source_url = va_arg(param, char *);
1368     data->set.printhost = (data->set.source_url != NULL);
1369     break;
1370
1371   case CURLOPT_SOURCE_USERPWD:
1372     /*
1373      * Use SOURCE USER[:PASSWORD]
1374      */
1375     data->set.source_userpwd = va_arg(param, char *);
1376     break;
1377
1378   case CURLOPT_SOURCE_QUOTE:
1379     /*
1380      * List of RAW FTP commands to use after a connect
1381      */
1382     data->set.source_quote = va_arg(param, struct curl_slist *);
1383     break;
1384
1385   case CURLOPT_SOURCE_PREQUOTE:
1386     /*
1387      * List of RAW FTP commands to use before a transfer on the source host
1388      */
1389     data->set.source_prequote = va_arg(param, struct curl_slist *);
1390     break;
1391
1392   case CURLOPT_SOURCE_POSTQUOTE:
1393     /*
1394      * List of RAW FTP commands to use after a transfer on the source host
1395      */
1396     data->set.source_postquote = va_arg(param, struct curl_slist *);
1397     break;
1398
1399   case CURLOPT_FTP_ACCOUNT:
1400     data->set.ftp_account = va_arg(param, char *);
1401     break;
1402
1403   default:
1404     /* unknown tag and its companion, just ignore: */
1405     result = CURLE_FAILED_INIT; /* correct this */
1406     break;
1407   }
1408
1409   return result;
1410 }
1411
1412 CURLcode Curl_disconnect(struct connectdata *conn)
1413 {
1414   struct SessionHandle *data;
1415   if(!conn)
1416     return CURLE_OK; /* this is closed and fine already */
1417
1418   data = conn->data;
1419
1420 #if defined(CURLDEBUG) && defined(AGGRESIVE_TEST)
1421   /* scan for DNS cache entries still marked as in use */
1422   Curl_hash_apply(data->hostcache,
1423                   NULL, Curl_scan_cache_used);
1424 #endif
1425
1426   Curl_hostcache_prune(data); /* kill old DNS cache entries */
1427
1428   /*
1429    * The range string is usually freed in curl_done(), but we might
1430    * get here *instead* if we fail prematurely. Thus we need to be able
1431    * to free this resource here as well.
1432    */
1433   if(conn->bits.rangestringalloc) {
1434     free(conn->range);
1435     conn->bits.rangestringalloc = FALSE;
1436   }
1437
1438   if((conn->ntlm.state != NTLMSTATE_NONE) ||
1439      (conn->proxyntlm.state != NTLMSTATE_NONE)) {
1440     /* Authentication data is a mix of connection-related and sessionhandle-
1441        related stuff. NTLM is connection-related so when we close the shop
1442        we shall forget. */
1443     data->state.authhost.done = FALSE;
1444     data->state.authhost.picked =
1445       data->state.authhost.want;
1446
1447     data->state.authproxy.done = FALSE;
1448     data->state.authproxy.picked =
1449       data->state.authhost.want;
1450
1451     data->state.authproblem = FALSE;
1452
1453 #if defined(USE_SSLEAY) || defined(USE_WINDOWS_SSPI)
1454     Curl_ntlm_cleanup(conn);
1455 #endif
1456   }
1457
1458   if(conn->curl_disconnect)
1459     /* This is set if protocol-specific cleanups should be made */
1460     conn->curl_disconnect(conn);
1461
1462   if(-1 != conn->connectindex) {
1463     /* unlink ourselves! */
1464     infof(data, "Closing connection #%ld\n", conn->connectindex);
1465     data->state.connects[conn->connectindex] = NULL;
1466   }
1467
1468   Curl_safefree(conn->proto.generic);
1469   Curl_safefree(conn->newurl);
1470   Curl_safefree(conn->pathbuffer); /* the URL path buffer */
1471
1472   Curl_safefree(conn->host.rawalloc); /* host name buffer */
1473   Curl_safefree(conn->proxy.rawalloc); /* proxy name buffer */
1474 #ifdef USE_LIBIDN
1475   if(conn->host.encalloc)
1476     idn_free(conn->host.encalloc); /* encoded host name buffer, must be freed
1477                                       with idn_free() since this was allocated
1478                                       by libidn */
1479   if(conn->proxy.encalloc)
1480     idn_free(conn->proxy.encalloc); /* encoded proxy name buffer, must be
1481                                        freed with idn_free() since this was
1482                                        allocated by libidn */
1483 #endif
1484   Curl_SSL_Close(conn);
1485
1486   /* close possibly still open sockets */
1487   if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET])
1488     sclose(conn->sock[SECONDARYSOCKET]);
1489   if(CURL_SOCKET_BAD != conn->sock[FIRSTSOCKET])
1490     sclose(conn->sock[FIRSTSOCKET]);
1491
1492   Curl_safefree(conn->user);
1493   Curl_safefree(conn->passwd);
1494   Curl_safefree(conn->proxyuser);
1495   Curl_safefree(conn->proxypasswd);
1496   Curl_safefree(conn->allocptr.proxyuserpwd);
1497   Curl_safefree(conn->allocptr.uagent);
1498   Curl_safefree(conn->allocptr.userpwd);
1499   Curl_safefree(conn->allocptr.accept_encoding);
1500   Curl_safefree(conn->allocptr.rangeline);
1501   Curl_safefree(conn->allocptr.ref);
1502   Curl_safefree(conn->allocptr.host);
1503   Curl_safefree(conn->allocptr.cookiehost);
1504   Curl_safefree(conn->ip_addr_str);
1505
1506 #if defined(USE_ARES) || defined(USE_THREADING_GETHOSTBYNAME) || \
1507     defined(USE_THREADING_GETADDRINFO)
1508   /* possible left-overs from the async name resolve */
1509   Curl_safefree(conn->async.hostname);
1510   Curl_safefree(conn->async.os_specific);
1511 #endif
1512
1513   Curl_free_ssl_config(&conn->ssl_config);
1514
1515   free(conn); /* free all the connection oriented data */
1516
1517   return CURLE_OK;
1518 }
1519
1520 /*
1521  * This function should return TRUE if the socket is to be assumed to
1522  * be dead. Most commonly this happens when the server has closed the
1523  * connection due to inactivity.
1524  */
1525 static bool SocketIsDead(curl_socket_t sock)
1526 {
1527   int sval;
1528   bool ret_val = TRUE;
1529
1530   sval = Curl_select(sock, CURL_SOCKET_BAD, 0);
1531   if(sval == 0)
1532     /* timeout */
1533     ret_val = FALSE;
1534
1535   return ret_val;
1536 }
1537
1538 /*
1539  * Given one filled in connection struct (named needle), this function should
1540  * detect if there already is one that have all the significant details
1541  * exactly the same and thus should be used instead.
1542  */
1543 static bool
1544 ConnectionExists(struct SessionHandle *data,
1545                  struct connectdata *needle,
1546                  struct connectdata **usethis)
1547 {
1548   long i;
1549   struct connectdata *check;
1550
1551   for(i=0; i< data->state.numconnects; i++) {
1552     bool match = FALSE;
1553     /*
1554      * Note that if we use a HTTP proxy, we check connections to that
1555      * proxy and not to the actual remote server.
1556      */
1557     check = data->state.connects[i];
1558     if(!check)
1559       /* NULL pointer means not filled-in entry */
1560       continue;
1561
1562     if((needle->protocol&PROT_SSL) != (check->protocol&PROT_SSL))
1563       /* don't do mixed SSL and non-SSL connections */
1564       continue;
1565
1566     if(!needle->bits.httpproxy || needle->protocol&PROT_SSL) {
1567       /* The requested connection does not use a HTTP proxy or it
1568          uses SSL. */
1569
1570       if(!(needle->protocol&PROT_SSL) && check->bits.httpproxy)
1571         /* we don't do SSL but the cached connection has a proxy,
1572            then don't match this */
1573         continue;
1574
1575       if(strequal(needle->protostr, check->protostr) &&
1576          strequal(needle->host.name, check->host.name) &&
1577          (needle->remote_port == check->remote_port) ) {
1578         if(needle->protocol & PROT_SSL) {
1579           /* This is SSL, verify that we're using the same
1580              ssl options as well */
1581           if(!Curl_ssl_config_matches(&needle->ssl_config,
1582                                       &check->ssl_config)) {
1583             continue;
1584           }
1585         }
1586         if((needle->protocol & PROT_FTP) ||
1587            ((needle->protocol & PROT_HTTP) &&
1588             (needle->data->state.authhost.want==CURLAUTH_NTLM))) {
1589           /* This is FTP or HTTP+NTLM, verify that we're using the same name
1590              and password as well */
1591           if(!strequal(needle->user, check->user) ||
1592              !strequal(needle->passwd, check->passwd)) {
1593             /* one of them was different */
1594             continue;
1595           }
1596         }
1597         match = TRUE;
1598       }
1599     }
1600     else { /* The requested needle connection is using a proxy,
1601               is the checked one using the same? */
1602       if(check->bits.httpproxy &&
1603          strequal(needle->proxy.name, check->proxy.name) &&
1604          needle->port == check->port) {
1605         /* This is the same proxy connection, use it! */
1606         match = TRUE;
1607       }
1608     }
1609
1610     if(match) {
1611       bool dead = SocketIsDead(check->sock[FIRSTSOCKET]);
1612       if(dead) {
1613         /*
1614          */
1615         infof(data, "Connection %d seems to be dead!\n", i);
1616         Curl_disconnect(check); /* disconnect resources */
1617         data->state.connects[i]=NULL; /* nothing here */
1618
1619         /* There's no need to continue searching, because we only store
1620            one connection for each unique set of identifiers */
1621         return FALSE;
1622       }
1623
1624       *usethis = check;
1625       return TRUE; /* yes, we found one to use! */
1626     }
1627   }
1628   return FALSE; /* no matching connecting exists */
1629 }
1630
1631 /*
1632  * This function frees/closes a connection in the connection cache. This
1633  * should take the previously set policy into account when deciding which
1634  * of the connections to kill.
1635  */
1636 static long
1637 ConnectionKillOne(struct SessionHandle *data)
1638 {
1639   long i;
1640   struct connectdata *conn;
1641   long highscore=-1;
1642   long connindex=-1;
1643   long score;
1644   struct timeval now;
1645
1646   now = Curl_tvnow();
1647
1648   for(i=0; i< data->state.numconnects; i++) {
1649     conn = data->state.connects[i];
1650
1651     if(!conn)
1652       continue;
1653
1654     /*
1655      * By using the set policy, we score each connection.
1656      */
1657     switch(data->set.closepolicy) {
1658     case CURLCLOSEPOLICY_LEAST_RECENTLY_USED:
1659     default:
1660       /*
1661        * Set higher score for the age passed since the connection
1662        * was used.
1663        */
1664       score = Curl_tvdiff(now, conn->now);
1665       break;
1666     case CURLCLOSEPOLICY_OLDEST:
1667       /*
1668        * Set higher score for the age passed since the connection
1669        * was created.
1670        */
1671       score = Curl_tvdiff(now, conn->created);
1672       break;
1673     }
1674
1675     if(score > highscore) {
1676       highscore = score;
1677       connindex = i;
1678     }
1679   }
1680   if(connindex >= 0) {
1681
1682     /* the winner gets the honour of being disconnected */
1683     (void) Curl_disconnect(data->state.connects[connindex]);
1684
1685     /* clean the array entry */
1686     data->state.connects[connindex] = NULL;
1687   }
1688
1689   return connindex; /* return the available index or -1 */
1690 }
1691
1692 /*
1693  * The given input connection struct pointer is to be stored. If the "cache"
1694  * is already full, we must clean out the most suitable using the previously
1695  * set policy.
1696  *
1697  * The given connection should be unique. That must've been checked prior to
1698  * this call.
1699  */
1700 static long
1701 ConnectionStore(struct SessionHandle *data,
1702                 struct connectdata *conn)
1703 {
1704   long i;
1705   for(i=0; i< data->state.numconnects; i++) {
1706     if(!data->state.connects[i])
1707       break;
1708   }
1709   if(i == data->state.numconnects) {
1710     /* there was no room available, kill one */
1711     i = ConnectionKillOne(data);
1712     infof(data, "Connection (#%d) was killed to make room\n", i);
1713   }
1714
1715   if(-1 != i) {
1716     /* only do this if a true index was returned, if -1 was returned there
1717        is no room in the cache for an unknown reason and we cannot store
1718        this there. */
1719     data->state.connects[i] = conn; /* fill in this */
1720     conn->connectindex = i; /* make the child know where the pointer to this
1721                                particular data is stored */
1722   }
1723   return i;
1724 }
1725
1726 /*
1727  * This function logs in to a SOCKS5 proxy and sends the specifies the final
1728  * desitination server.
1729  */
1730 static int handleSock5Proxy(const char *proxy_name,
1731                             const char *proxy_password,
1732                             struct connectdata *conn)
1733 {
1734   /*
1735     According to the RFC1928, section "6.  Replies". This is what a SOCK5
1736     replies:
1737
1738         +----+-----+-------+------+----------+----------+
1739         |VER | REP |  RSV  | ATYP | BND.ADDR | BND.PORT |
1740         +----+-----+-------+------+----------+----------+
1741         | 1  |  1  | X'00' |  1   | Variable |    2     |
1742         +----+-----+-------+------+----------+----------+
1743
1744     Where:
1745
1746     o  VER    protocol version: X'05'
1747     o  REP    Reply field:
1748     o  X'00' succeeded
1749   */
1750
1751   unsigned char socksreq[600]; /* room for large user/pw (255 max each) */
1752   ssize_t actualread;
1753   ssize_t written;
1754   int result;
1755   CURLcode code;
1756   int sock = conn->sock[FIRSTSOCKET];
1757
1758   Curl_nonblock(sock, FALSE);
1759
1760   socksreq[0] = 5; /* version */
1761   socksreq[1] = (char)(proxy_name ? 2 : 1); /* number of methods (below) */
1762   socksreq[2] = 0; /* no authentication */
1763   socksreq[3] = 2; /* username/password */
1764
1765   code = Curl_write(conn, sock, (char *)socksreq, (2 + (int)socksreq[1]),
1766                       &written);
1767   if ((code != CURLE_OK) || (written != (2 + (int)socksreq[1]))) {
1768     failf(conn->data, "Unable to send initial SOCKS5 request.");
1769     return 1;
1770   }
1771
1772   result=Curl_read(conn, sock, (char *)socksreq, 2, &actualread);
1773   if ((result != CURLE_OK) || (actualread != 2)) {
1774     failf(conn->data, "Unable to receive initial SOCKS5 response.");
1775     return 1;
1776   }
1777
1778   if (socksreq[0] != 5) {
1779     failf(conn->data, "Received invalid version in initial SOCKS5 response.");
1780     return 1;
1781   }
1782   if (socksreq[1] == 0) {
1783     /* Nothing to do, no authentication needed */
1784     ;
1785   }
1786   else if (socksreq[1] == 2) {
1787     /* Needs user name and password */
1788     int userlen, pwlen, len;
1789
1790     userlen = (int)strlen(proxy_name);
1791     pwlen = proxy_password?(int)strlen(proxy_password):0;
1792
1793     /*   username/password request looks like
1794      * +----+------+----------+------+----------+
1795      * |VER | ULEN |  UNAME   | PLEN |  PASSWD  |
1796      * +----+------+----------+------+----------+
1797      * | 1  |  1   | 1 to 255 |  1   | 1 to 255 |
1798      * +----+------+----------+------+----------+
1799      */
1800     len = 0;
1801     socksreq[len++] = 1;    /* username/pw subnegotiation version */
1802     socksreq[len++] = (char) userlen;
1803     memcpy(socksreq + len, proxy_name, (int) userlen);
1804     len += userlen;
1805     socksreq[len++] = (char) pwlen;
1806     memcpy(socksreq + len, proxy_password, (int) pwlen);
1807     len += pwlen;
1808
1809     code = Curl_write(conn, sock, (char *)socksreq, len, &written);
1810     if ((code != CURLE_OK) || (len != written)) {
1811       failf(conn->data, "Failed to send SOCKS5 sub-negotiation request.");
1812       return 1;
1813     }
1814
1815     result=Curl_read(conn, sock, (char *)socksreq, 2, &actualread);
1816     if ((result != CURLE_OK) || (actualread != 2)) {
1817       failf(conn->data, "Unable to receive SOCKS5 sub-negotiation response.");
1818       return 1;
1819     }
1820
1821     /* ignore the first (VER) byte */
1822     if (socksreq[1] != 0) { /* status */
1823       failf(conn->data, "User was rejected by the SOCKS5 server (%d %d).",
1824             socksreq[0], socksreq[1]);
1825       return 1;
1826     }
1827
1828     /* Everything is good so far, user was authenticated! */
1829   }
1830   else {
1831     /* error */
1832     if (socksreq[1] == 1) {
1833       failf(conn->data,
1834             "SOCKS5 GSSAPI per-message authentication is not supported.");
1835       return 1;
1836     }
1837     else if (socksreq[1] == 255) {
1838       if (!proxy_name || !*proxy_name) {
1839         failf(conn->data,
1840               "No authentication method was acceptable. (It is quite likely"
1841               " that the SOCKS5 server wanted a username/password, since none"
1842               " was supplied to the server on this connection.)");
1843       }
1844       else {
1845         failf(conn->data, "No authentication method was acceptable.");
1846       }
1847       return 1;
1848     }
1849     else {
1850       failf(conn->data,
1851             "Undocumented SOCKS5 mode attempted to be used by server.");
1852       return 1;
1853     }
1854   }
1855
1856   /* Authentication is complete, now specify destination to the proxy */
1857   socksreq[0] = 5; /* version (SOCKS5) */
1858   socksreq[1] = 1; /* connect */
1859   socksreq[2] = 0; /* must be zero */
1860   socksreq[3] = 1; /* IPv4 = 1 */
1861
1862   {
1863     struct Curl_dns_entry *dns;
1864     Curl_addrinfo *hp=NULL;
1865     int rc = Curl_resolv(conn, conn->host.name, (int)conn->remote_port, &dns);
1866
1867     if(rc == CURLRESOLV_ERROR)
1868       return 1;
1869
1870     if(rc == CURLRESOLV_PENDING)
1871       /* this requires that we're in "wait for resolve" state */
1872       rc = Curl_wait_for_resolv(conn, &dns);
1873
1874     /*
1875      * We cannot use 'hostent' as a struct that Curl_resolv() returns.  It
1876      * returns a Curl_addrinfo pointer that may not always look the same.
1877      */
1878     if(dns)
1879       hp=dns->addr;
1880     if (hp) {
1881       char buf[64];
1882       unsigned short ip[4];
1883       Curl_printable_address(hp, buf, sizeof(buf));
1884
1885       if(4 == sscanf( buf, "%hu.%hu.%hu.%hu",
1886                       &ip[0], &ip[1], &ip[2], &ip[3])) {
1887         socksreq[4] = (unsigned char)ip[0];
1888         socksreq[5] = (unsigned char)ip[1];
1889         socksreq[6] = (unsigned char)ip[2];
1890         socksreq[7] = (unsigned char)ip[3];
1891       }
1892       else
1893         hp = NULL; /* fail! */
1894
1895       Curl_resolv_unlock(conn->data, dns); /* not used anymore from now on */
1896     }
1897     if(!hp) {
1898       failf(conn->data, "Failed to resolve \"%s\" for SOCKS5 connect.",
1899             conn->host.name);
1900       return 1;
1901     }
1902   }
1903
1904   *((unsigned short*)&socksreq[8]) = htons(conn->remote_port);
1905
1906   {
1907     const int packetsize = 10;
1908
1909     code = Curl_write(conn, sock, (char *)socksreq, packetsize, &written);
1910     if ((code != CURLE_OK) || (written != packetsize)) {
1911       failf(conn->data, "Failed to send SOCKS5 connect request.");
1912       return 1;
1913     }
1914
1915     result = Curl_read(conn, sock, (char *)socksreq, packetsize, &actualread);
1916     if ((result != CURLE_OK) || (actualread != packetsize)) {
1917       failf(conn->data, "Failed to receive SOCKS5 connect request ack.");
1918       return 1;
1919     }
1920
1921     if (socksreq[0] != 5) { /* version */
1922       failf(conn->data,
1923             "SOCKS5 reply has wrong version, version should be 5.");
1924       return 1;
1925     }
1926     if (socksreq[1] != 0) { /* Anything besides 0 is an error */
1927         failf(conn->data,
1928               "Can't complete SOCKS5 connection to %d.%d.%d.%d:%d. (%d)",
1929               (unsigned char)socksreq[4], (unsigned char)socksreq[5],
1930               (unsigned char)socksreq[6], (unsigned char)socksreq[7],
1931               (unsigned int)ntohs(*(unsigned short*)(&socksreq[8])),
1932               socksreq[1]);
1933         return 1;
1934     }
1935   }
1936
1937   Curl_nonblock(sock, TRUE);
1938   return 0; /* Proxy was successful! */
1939 }
1940
1941 static CURLcode ConnectPlease(struct connectdata *conn,
1942                               struct Curl_dns_entry *hostaddr,
1943                               bool *connected)
1944 {
1945   CURLcode result;
1946   Curl_addrinfo *addr;
1947   struct SessionHandle *data = conn->data;
1948   char *hostname = data->change.proxy?conn->proxy.name:conn->host.name;
1949
1950   infof(data, "About to connect() to %s port %d\n",
1951         hostname, conn->port);
1952
1953   /*************************************************************
1954    * Connect to server/proxy
1955    *************************************************************/
1956   result= Curl_connecthost(conn,
1957                            hostaddr,
1958                            &conn->sock[FIRSTSOCKET],
1959                            &addr,
1960                            connected);
1961   if(CURLE_OK == result) {
1962     /* All is cool, then we store the current information */
1963     conn->dns_entry = hostaddr;
1964     conn->ip_addr = addr;
1965
1966     Curl_store_ip_addr(conn);
1967
1968     if (conn->data->set.proxytype == CURLPROXY_SOCKS5) {
1969       return handleSock5Proxy(conn->proxyuser,
1970                               conn->proxypasswd,
1971                               conn) ?
1972         CURLE_COULDNT_CONNECT : CURLE_OK;
1973     }
1974     else if (conn->data->set.proxytype == CURLPROXY_HTTP) {
1975       /* do nothing here. handled later. */
1976     }
1977     else {
1978       failf(conn->data, "unknown proxytype option given");
1979       return CURLE_COULDNT_CONNECT;
1980     }
1981   }
1982
1983   return result;
1984 }
1985
1986 /*
1987  * verboseconnect() displays verbose information after a connect
1988  */
1989 static void verboseconnect(struct connectdata *conn)
1990 {
1991   infof(conn->data, "Connected to %s (%s) port %d\n",
1992         conn->bits.httpproxy ? conn->proxy.dispname : conn->host.dispname,
1993         conn->ip_addr_str, conn->port);
1994 }
1995
1996 CURLcode Curl_protocol_fdset(struct connectdata *conn,
1997                              fd_set *read_fd_set,
1998                              fd_set *write_fd_set,
1999                              int *max_fdp)
2000 {
2001   CURLcode res = CURLE_OK;
2002   if(conn->curl_proto_fdset)
2003     res = conn->curl_proto_fdset(conn, read_fd_set, write_fd_set, max_fdp);
2004   return res;
2005 }
2006
2007 CURLcode Curl_doing_fdset(struct connectdata *conn,
2008                           fd_set *read_fd_set,
2009                           fd_set *write_fd_set,
2010                           int *max_fdp)
2011 {
2012   CURLcode res = CURLE_OK;
2013   if(conn && conn->curl_doing_fdset)
2014     res = conn->curl_doing_fdset(conn, read_fd_set, write_fd_set, max_fdp);
2015   return res;
2016 }
2017
2018 /*
2019  * We are doing protocol-specific connecting and this is being called over and
2020  * over from the multi interface until the connection phase is done on
2021  * protocol layer.
2022  */
2023
2024 CURLcode Curl_protocol_connecting(struct connectdata *conn, bool *done)
2025 {
2026   CURLcode result=CURLE_OK;
2027
2028   if(conn && conn->curl_connecting) {
2029     *done = FALSE;
2030     result = conn->curl_connecting(conn, done);
2031   }
2032   else
2033     *done = TRUE;
2034
2035   return result;
2036 }
2037
2038 /*
2039  * We are DOING this is being called over and over from the multi interface
2040  * until the DOING phase is done on protocol layer.
2041  */
2042
2043 CURLcode Curl_protocol_doing(struct connectdata *conn, bool *done)
2044 {
2045   CURLcode result=CURLE_OK;
2046
2047   if(conn && conn->curl_doing) {
2048     *done = FALSE;
2049     result = conn->curl_doing(conn, done);
2050   }
2051   else
2052     *done = TRUE;
2053
2054   return result;
2055 }
2056
2057 /*
2058  * We have discovered that the TCP connection has been successful, we can now
2059  * proceed with some action.
2060  *
2061  */
2062 CURLcode Curl_protocol_connect(struct connectdata *conn, bool *protocol_done)
2063 {
2064   struct SessionHandle *data = conn->data;
2065   CURLcode result=CURLE_OK;
2066
2067   *protocol_done = FALSE;
2068
2069   if(conn->bits.tcpconnect && conn->bits.protoconnstart) {
2070     /* We already are connected, get back. This may happen when the connect
2071        worked fine in the first call, like when we connect to a local server
2072        or proxy. Note that we don't know if the protocol is actually done.
2073
2074        Unless this protocol doesn't have any protocol-connect callback, as
2075        then we know we're done. */
2076     if(!conn->curl_connecting)
2077       *protocol_done = TRUE;
2078
2079     return CURLE_OK;
2080   }
2081
2082   if(!conn->bits.tcpconnect) {
2083
2084     Curl_pgrsTime(data, TIMER_CONNECT); /* connect done */
2085
2086     if(data->set.verbose)
2087       verboseconnect(conn);
2088   }
2089
2090   if(!conn->bits.protoconnstart) {
2091     if(conn->curl_connect) {
2092       /* is there a protocol-specific connect() procedure? */
2093
2094       /* Set start time here for timeout purposes in the connect procedure, it
2095          is later set again for the progress meter purpose */
2096       conn->now = Curl_tvnow();
2097
2098       /* Call the protocol-specific connect function */
2099       result = conn->curl_connect(conn, protocol_done);
2100     }
2101     else
2102       *protocol_done = TRUE;
2103
2104     /* it has started, possibly even completed but that knowledge isn't stored
2105        in this bit! */
2106     conn->bits.protoconnstart = TRUE;
2107   }
2108
2109   return result; /* pass back status */
2110 }
2111
2112 /*
2113  * Helpers for IDNA convertions.
2114  */
2115 #ifdef USE_LIBIDN
2116 static bool is_ASCII_name (const char *hostname)
2117 {
2118   const unsigned char *ch = (const unsigned char*)hostname;
2119
2120   while (*ch) {
2121     if (*ch++ & 0x80)
2122       return FALSE;
2123   }
2124   return TRUE;
2125 }
2126
2127 /*
2128  * Check if characters in hostname is allowed in Top Level Domain.
2129  */
2130 static bool tld_check_name (struct SessionHandle *data,
2131                             const char *ace_hostname)
2132 {
2133   size_t err_pos;
2134   char *uc_name = NULL;
2135   int rc;
2136
2137   /* Convert (and downcase) ACE-name back into locale's character set */
2138   rc = idna_to_unicode_lzlz(ace_hostname, &uc_name, 0);
2139   if (rc != IDNA_SUCCESS)
2140     return (FALSE);
2141
2142   rc = tld_check_lz(uc_name, &err_pos, NULL);
2143   if (rc == TLD_INVALID)
2144      infof(data, "WARNING: %s; pos %u = `%c'/0x%02X\n",
2145 #ifdef HAVE_TLD_STRERROR
2146            tld_strerror(rc),
2147 #else
2148            "<no msg>",
2149 #endif
2150            err_pos, uc_name[err_pos],
2151            uc_name[err_pos] & 255);
2152   else if (rc != TLD_SUCCESS)
2153        infof(data, "WARNING: TLD check for %s failed; %s\n",
2154              uc_name,
2155 #ifdef HAVE_TLD_STRERROR
2156              tld_strerror(rc)
2157 #else
2158              "<no msg>"
2159 #endif
2160          );
2161   if (uc_name)
2162      idn_free(uc_name);
2163   return (rc == TLD_SUCCESS);
2164 }
2165 #endif
2166
2167 static void fix_hostname(struct connectdata *conn, struct hostname *host)
2168 {
2169   /* set the name we use to display the host name */
2170   host->dispname = host->name;
2171
2172 #ifdef USE_LIBIDN
2173   /*************************************************************
2174    * Check name for non-ASCII and convert hostname to ACE form.
2175    *************************************************************/
2176   if (!is_ASCII_name(host->name) &&
2177       stringprep_check_version(LIBIDN_REQUIRED_VERSION)) {
2178     char *ace_hostname = NULL;
2179     struct SessionHandle *data = conn->data;
2180     int rc = idna_to_ascii_lz(host->name, &ace_hostname, 0);
2181     infof (data, "Input domain encoded as `%s'\n",
2182            stringprep_locale_charset ());
2183     if (rc != IDNA_SUCCESS)
2184       infof(data, "Failed to convert %s to ACE; %s\n",
2185             host->name, Curl_idn_strerror(conn,rc));
2186     else {
2187       tld_check_name(data, ace_hostname);
2188
2189       host->encalloc = ace_hostname;
2190       /* change the name pointer to point to the encoded hostname */
2191       host->name = host->encalloc;
2192     }
2193   }
2194 #else
2195   (void)conn; /* never used */
2196 #endif
2197 }
2198
2199
2200 /**
2201  * CreateConnection() sets up a new connectdata struct, or re-uses an already
2202  * existing one, and resolves host name.
2203  *
2204  * if this function returns CURLE_OK and *async is set to TRUE, the resolve
2205  * response will be coming asynchronously. If *async is FALSE, the name is
2206  * already resolved.
2207  *
2208  * @param data The sessionhandle pointer
2209  * @param in_connect is set to the next connection data pointer
2210  * @param addr is set to the new dns entry for this connection
2211  * @param async is set TRUE/FALSE depending on the nature of this lookup
2212  * @return CURLcode
2213  * @see SetupConnection()
2214  */
2215
2216 static CURLcode CreateConnection(struct SessionHandle *data,
2217                                  struct connectdata **in_connect,
2218                                  struct Curl_dns_entry **addr,
2219                                  bool *async)
2220 {
2221   char *tmp;
2222   char *at;
2223   CURLcode result=CURLE_OK;
2224   struct connectdata *conn;
2225   struct connectdata *conn_temp;
2226   size_t urllen;
2227   struct Curl_dns_entry *hostaddr;
2228 #if defined(HAVE_ALARM) && !defined(USE_ARES)
2229   unsigned int prev_alarm=0;
2230 #endif
2231   char endbracket;
2232   char user[MAX_CURL_USER_LENGTH];
2233   char passwd[MAX_CURL_PASSWORD_LENGTH];
2234   int rc;
2235   bool reuse;
2236
2237 #ifndef USE_ARES
2238 #ifdef SIGALRM
2239 #ifdef HAVE_SIGACTION
2240   struct sigaction keep_sigact;   /* store the old struct here */
2241   bool keep_copysig=FALSE;        /* did copy it? */
2242 #else
2243 #ifdef HAVE_SIGNAL
2244   void *keep_sigact;              /* store the old handler here */
2245 #endif /* HAVE_SIGNAL */
2246 #endif /* HAVE_SIGACTION */
2247 #endif /* SIGALRM */
2248 #endif /* USE_ARES */
2249
2250   *addr = NULL; /* nothing yet */
2251   *async = FALSE;
2252
2253   /*************************************************************
2254    * Check input data
2255    *************************************************************/
2256
2257   if(!data->change.url)
2258     return CURLE_URL_MALFORMAT;
2259
2260   /* First, split up the current URL in parts so that we can use the
2261      parts for checking against the already present connections. In order
2262      to not have to modify everything at once, we allocate a temporary
2263      connection data struct and fill in for comparison purposes. */
2264
2265   conn = (struct connectdata *)calloc(sizeof(struct connectdata), 1);
2266   if(!conn) {
2267     *in_connect = NULL; /* clear the pointer */
2268     return CURLE_OUT_OF_MEMORY;
2269   }
2270   /* We must set the return variable as soon as possible, so that our
2271      parent can cleanup any possible allocs we may have done before
2272      any failure */
2273   *in_connect = conn;
2274
2275   /* and we setup a few fields in case we end up actually using this struct */
2276   conn->data = data;           /* remember our daddy */
2277   conn->sock[FIRSTSOCKET] = CURL_SOCKET_BAD;     /* no file descriptor */
2278   conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */
2279   conn->connectindex = -1;    /* no index */
2280   conn->bits.httpproxy = (data->change.proxy && *data->change.proxy &&
2281                           (data->set.proxytype == CURLPROXY_HTTP))?
2282     TRUE:FALSE; /* http proxy or not */
2283
2284   /* Default protocol-independent behavior doesn't support persistant
2285      connections, so we set this to force-close. Protocols that support
2286      this need to set this to FALSE in their "curl_do" functions. */
2287   conn->bits.close = TRUE;
2288
2289   /* maxdownload must be -1 on init, as 0 is a valid value! */
2290   conn->maxdownload = -1;  /* might have been used previously! */
2291
2292   /* Store creation time to help future close decision making */
2293   conn->created = Curl_tvnow();
2294
2295   conn->bits.use_range = data->set.set_range?TRUE:FALSE; /* range status */
2296   conn->range = data->set.set_range;              /* clone the range setting */
2297   conn->resume_from = data->set.set_resume_from;   /* inherite resume_from */
2298
2299   conn->bits.user_passwd = data->set.userpwd?1:0;
2300   conn->bits.proxy_user_passwd = data->set.proxyuserpwd?1:0;
2301   conn->bits.no_body = data->set.opt_no_body;
2302   conn->bits.tunnel_proxy = data->set.tunnel_thru_httpproxy;
2303   conn->bits.ftp_use_epsv = data->set.ftp_use_epsv;
2304   conn->bits.ftp_use_eprt = data->set.ftp_use_eprt;
2305   conn->bits.ftp_use_lprt = data->set.ftp_use_lprt;
2306
2307   /* This initing continues below, see the comment "Continue connectdata
2308    * initialization here" */
2309
2310   /***********************************************************
2311    * We need to allocate memory to store the path in. We get the size of the
2312    * full URL to be sure, and we need to make it at least 256 bytes since
2313    * other parts of the code will rely on this fact
2314    ***********************************************************/
2315 #define LEAST_PATH_ALLOC 256
2316   urllen=strlen(data->change.url);
2317   if(urllen < LEAST_PATH_ALLOC)
2318     urllen=LEAST_PATH_ALLOC;
2319
2320   conn->pathbuffer=(char *)malloc(urllen);
2321   if(NULL == conn->pathbuffer)
2322     return CURLE_OUT_OF_MEMORY; /* really bad error */
2323   conn->path = conn->pathbuffer;
2324
2325   conn->host.rawalloc=(char *)malloc(urllen);
2326   if(NULL == conn->host.rawalloc)
2327     return CURLE_OUT_OF_MEMORY;
2328   conn->host.name = conn->host.rawalloc;
2329   conn->host.name[0] = 0;
2330
2331   /*************************************************************
2332    * Parse the URL.
2333    *
2334    * We need to parse the url even when using the proxy, because we will need
2335    * the hostname and port in case we are trying to SSL connect through the
2336    * proxy -- and we don't know if we will need to use SSL until we parse the
2337    * url ...
2338    ************************************************************/
2339   if((2 == sscanf(data->change.url, "%15[^:]:%[^\n]",
2340                   conn->protostr,
2341                   conn->path)) && strequal(conn->protostr, "file")) {
2342     if(conn->path[0] == '/' && conn->path[1] == '/') {
2343       /* Allow omitted hostname (e.g. file:/<path>).  This is not strictly
2344        * speaking a valid file: URL by RFC 1738, but treating file:/<path> as
2345        * file://localhost/<path> is similar to how other schemes treat missing
2346        * hostnames.  See RFC 1808. */
2347
2348       /* This cannot be done with strcpy() in a portable manner, since the
2349          memory areas overlap! */
2350       memmove(conn->path, conn->path + 2, strlen(conn->path + 2)+1);
2351     }
2352     /*
2353      * we deal with file://<host>/<path> differently since it supports no
2354      * hostname other than "localhost" and "127.0.0.1", which is unique among
2355      * the URL protocols specified in RFC 1738
2356      */
2357     if(conn->path[0] != '/') {
2358       /* the URL included a host name, we ignore host names in file:// URLs
2359          as the standards don't define what to do with them */
2360       char *ptr=strchr(conn->path, '/');
2361       if(ptr) {
2362         /* there was a slash present
2363
2364            RFC1738 (section 3.1, page 5) says:
2365
2366            The rest of the locator consists of data specific to the scheme,
2367            and is known as the "url-path". It supplies the details of how the
2368            specified resource can be accessed. Note that the "/" between the
2369            host (or port) and the url-path is NOT part of the url-path.
2370
2371            As most agents use file://localhost/foo to get '/foo' although the
2372            slash preceeding foo is a separator and not a slash for the path,
2373            a URL as file://localhost//foo must be valid as well, to refer to
2374            the same file with an absolute path.
2375         */
2376
2377         if(ptr[1] && ('/' == ptr[1]))
2378           /* if there was two slashes, we skip the first one as that is then
2379              used truly as a separator */
2380           ptr++;
2381
2382         /* This cannot be made with strcpy, as the memory chunks overlap! */
2383         memmove(conn->path, ptr, strlen(ptr)+1);
2384       }
2385     }
2386
2387     strcpy(conn->protostr, "file"); /* store protocol string lowercase */
2388   }
2389   else {
2390     /* Set default path */
2391     strcpy(conn->path, "/");
2392
2393     if (2 > sscanf(data->change.url,
2394                    "%15[^\n:]://%[^\n/]%[^\n]",
2395                    conn->protostr,
2396                    conn->host.name, conn->path)) {
2397
2398       /*
2399        * The URL was badly formatted, let's try the browser-style _without_
2400        * protocol specified like 'http://'.
2401        */
2402       if((1 > sscanf(data->change.url, "%[^\n/]%[^\n]",
2403                      conn->host.name, conn->path)) ) {
2404         /*
2405          * We couldn't even get this format.
2406          */
2407         failf(data, "<url> malformed");
2408         return CURLE_URL_MALFORMAT;
2409       }
2410
2411       /*
2412        * Since there was no protocol part specified, we guess what protocol it
2413        * is based on the first letters of the server name.
2414        */
2415
2416       /* Note: if you add a new protocol, please update the list in
2417        * lib/version.c too! */
2418
2419       if(checkprefix("GOPHER.", conn->host.name))
2420         strcpy(conn->protostr, "gopher");
2421 #ifdef USE_SSLEAY
2422       else if(checkprefix("FTPS", conn->host.name))
2423         strcpy(conn->protostr, "ftps");
2424 #endif /* USE_SSLEAY */
2425       else if(checkprefix("FTP.", conn->host.name))
2426         strcpy(conn->protostr, "ftp");
2427       else if(checkprefix("TELNET.", conn->host.name))
2428         strcpy(conn->protostr, "telnet");
2429       else if (checkprefix("DICT.", conn->host.name))
2430         strcpy(conn->protostr, "DICT");
2431       else if (checkprefix("LDAP.", conn->host.name))
2432         strcpy(conn->protostr, "LDAP");
2433       else {
2434         strcpy(conn->protostr, "http");
2435       }
2436
2437       conn->protocol |= PROT_MISSING; /* not given in URL */
2438     }
2439   }
2440
2441   /* We search for '?' in the host name (but only on the right side of a
2442    * @-letter to allow ?-letters in username and password) to handle things
2443    * like http://example.com?param= (notice the missing '/').
2444    */
2445   at = strchr(conn->host.name, '@');
2446   if(at)
2447     tmp = strchr(at+1, '?');
2448   else
2449     tmp = strchr(conn->host.name, '?');
2450
2451   if(tmp) {
2452     /* The right part of the ?-letter needs to be moved to prefix
2453        the current path buffer! */
2454     size_t len = strlen(tmp);
2455     /* move the existing path plus the zero byte */
2456     memmove(conn->path+len+1, conn->path, strlen(conn->path)+1);
2457     conn->path[0]='/'; /* prepend the missing slash */
2458     memcpy(conn->path+1, tmp, len); /* now copy the prefix part */
2459     *tmp=0; /* now cut off the hostname at the ? */
2460   }
2461
2462   /* If the URL is malformatted (missing a '/' after hostname before path) we
2463    * insert a slash here. The only letter except '/' we accept to start a path
2464    * is '?'.
2465    */
2466   if(conn->path[0] == '?') {
2467     /* We need this function to deal with overlapping memory areas. We know
2468        that the memory area 'path' points to is 'urllen' bytes big and that
2469        is bigger than the path. Use +1 to move the zero byte too. */
2470     memmove(&conn->path[1], conn->path, strlen(conn->path)+1);
2471     conn->path[0] = '/';
2472   }
2473
2474   /*
2475    * So if the URL was A://B/C,
2476    *   conn->protostr is A
2477    *   conn->host.name is B
2478    *   conn->path is /C
2479    */
2480
2481   /*************************************************************
2482    * Take care of proxy authentication stuff
2483    *************************************************************/
2484   if(conn->bits.proxy_user_passwd) {
2485     char proxyuser[MAX_CURL_USER_LENGTH]="";
2486     char proxypasswd[MAX_CURL_PASSWORD_LENGTH]="";
2487
2488     sscanf(data->set.proxyuserpwd,
2489            "%" MAX_CURL_USER_LENGTH_TXT "[^:]:"
2490            "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^\n]",
2491            proxyuser, proxypasswd);
2492
2493     conn->proxyuser = strdup(proxyuser);
2494     if(!conn->proxyuser)
2495       return CURLE_OUT_OF_MEMORY;
2496
2497     conn->proxypasswd = strdup(proxypasswd);
2498     if(!conn->proxypasswd)
2499       return CURLE_OUT_OF_MEMORY;
2500   }
2501
2502 #ifndef CURL_DISABLE_HTTP
2503   /*************************************************************
2504    * Detect what (if any) proxy to use
2505    *************************************************************/
2506   if(!data->change.proxy) {
2507     /* If proxy was not specified, we check for default proxy environment
2508      * variables, to enable i.e Lynx compliance:
2509      *
2510      * http_proxy=http://some.server.dom:port/
2511      * https_proxy=http://some.server.dom:port/
2512      * ftp_proxy=http://some.server.dom:port/
2513      * gopher_proxy=http://some.server.dom:port/
2514      * no_proxy=domain1.dom,host.domain2.dom
2515      *   (a comma-separated list of hosts which should
2516      *   not be proxied, or an asterisk to override
2517      *   all proxy variables)
2518      * all_proxy=http://some.server.dom:port/
2519      *   (seems to exist for the CERN www lib. Probably
2520      *   the first to check for.)
2521      *
2522      * For compatibility, the all-uppercase versions of these variables are
2523      * checked if the lowercase versions don't exist.
2524      */
2525     char *no_proxy=NULL;
2526     char *no_proxy_tok_buf;
2527     char *proxy=NULL;
2528     char proxy_env[128];
2529
2530     no_proxy=curl_getenv("no_proxy");
2531     if(!no_proxy)
2532       no_proxy=curl_getenv("NO_PROXY");
2533
2534     if(!no_proxy || !strequal("*", no_proxy)) {
2535       /* NO_PROXY wasn't specified or it wasn't just an asterisk */
2536       char *nope;
2537
2538       nope=no_proxy?strtok_r(no_proxy, ", ", &no_proxy_tok_buf):NULL;
2539       while(nope) {
2540         size_t namelen;
2541         char *endptr = strchr(conn->host.name, ':');
2542         if(endptr)
2543           namelen=endptr-conn->host.name;
2544         else
2545           namelen=strlen(conn->host.name);
2546
2547         if(strlen(nope) <= namelen) {
2548           char *checkn=
2549             conn->host.name + namelen - strlen(nope);
2550           if(checkprefix(nope, checkn)) {
2551             /* no proxy for this host! */
2552             break;
2553           }
2554         }
2555         nope=strtok_r(NULL, ", ", &no_proxy_tok_buf);
2556       }
2557       if(!nope) {
2558         /* It was not listed as without proxy */
2559         char *protop = conn->protostr;
2560         char *envp = proxy_env;
2561         char *prox;
2562
2563         /* Now, build <protocol>_proxy and check for such a one to use */
2564         while(*protop)
2565           *envp++ = tolower((int)*protop++);
2566
2567         /* append _proxy */
2568         strcpy(envp, "_proxy");
2569
2570         /* read the protocol proxy: */
2571         prox=curl_getenv(proxy_env);
2572
2573         /*
2574          * We don't try the uppercase version of HTTP_PROXY because of
2575          * security reasons:
2576          *
2577          * When curl is used in a webserver application
2578          * environment (cgi or php), this environment variable can
2579          * be controlled by the web server user by setting the
2580          * http header 'Proxy:' to some value.
2581          *
2582          * This can cause 'internal' http/ftp requests to be
2583          * arbitrarily redirected by any external attacker.
2584          */
2585         if(!prox && !strequal("http_proxy", proxy_env)) {
2586           /* There was no lowercase variable, try the uppercase version: */
2587           for(envp = proxy_env; *envp; envp++)
2588             *envp = toupper((int)*envp);
2589           prox=curl_getenv(proxy_env);
2590         }
2591
2592         if(prox && *prox) { /* don't count "" strings */
2593           proxy = prox; /* use this */
2594         }
2595         else {
2596           proxy = curl_getenv("all_proxy"); /* default proxy to use */
2597           if(!proxy)
2598             proxy=curl_getenv("ALL_PROXY");
2599         }
2600
2601         if(proxy && *proxy) {
2602           /* we have a proxy here to set */
2603           char *ptr;
2604           char proxyuser[MAX_CURL_USER_LENGTH];
2605           char proxypasswd[MAX_CURL_PASSWORD_LENGTH];
2606
2607           char *fineptr;
2608
2609           /* skip the possible protocol piece */
2610           ptr=strstr(proxy, "://");
2611           if(ptr)
2612             ptr += 3;
2613           else
2614             ptr = proxy;
2615
2616           fineptr = ptr;
2617
2618           /* check for an @-letter */
2619           ptr = strchr(ptr, '@');
2620           if(ptr && (2 == sscanf(fineptr,
2621                                  "%" MAX_CURL_USER_LENGTH_TXT"[^:]:"
2622                                  "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^@]",
2623                                  proxyuser, proxypasswd))) {
2624             CURLcode res = CURLE_OK;
2625
2626             /* found user and password, rip them out */
2627             Curl_safefree(conn->proxyuser);
2628             conn->proxyuser = strdup(proxyuser);
2629
2630             if(!conn->proxyuser)
2631               res = CURLE_OUT_OF_MEMORY;
2632             else {
2633               Curl_safefree(conn->proxypasswd);
2634               conn->proxypasswd = strdup(proxypasswd);
2635
2636               if(!conn->proxypasswd)
2637                 res = CURLE_OUT_OF_MEMORY;
2638             }
2639
2640             if(CURLE_OK == res) {
2641               conn->bits.proxy_user_passwd = TRUE; /* enable it */
2642               ptr = strdup(ptr+1); /* the right side of the @-letter */
2643
2644               if(ptr) {
2645                 free(proxy); /* free the former proxy string */
2646                 proxy = ptr; /* now use this instead */
2647               }
2648               else
2649                 res = CURLE_OUT_OF_MEMORY;
2650             }
2651
2652             if(res) {
2653               free(proxy); /* free the allocated proxy string */
2654               return res;
2655             }
2656           }
2657
2658           data->change.proxy = proxy;
2659           data->change.proxy_alloc=TRUE; /* this needs to be freed later */
2660           conn->bits.httpproxy = TRUE;
2661         }
2662       } /* if (!nope) - it wasn't specified non-proxy */
2663     } /* NO_PROXY wasn't specified or '*' */
2664     if(no_proxy)
2665       free(no_proxy);
2666   } /* if not using proxy */
2667 #endif /* CURL_DISABLE_HTTP */
2668
2669   /*************************************************************
2670    * No protocol part in URL was used, add it!
2671    *************************************************************/
2672   if(conn->protocol&PROT_MISSING) {
2673     /* We're guessing prefixes here and if we're told to use a proxy or if
2674        we're gonna follow a Location: later or... then we need the protocol
2675        part added so that we have a valid URL. */
2676     char *reurl;
2677
2678     reurl = aprintf("%s://%s", conn->protostr, data->change.url);
2679
2680     if(!reurl)
2681       return CURLE_OUT_OF_MEMORY;
2682
2683     data->change.url = reurl;
2684     data->change.url_alloc = TRUE; /* free this later */
2685     conn->protocol &= ~PROT_MISSING; /* switch that one off again */
2686   }
2687
2688 #ifndef CURL_DISABLE_HTTP
2689   /************************************************************
2690    * RESUME on a HTTP page is a tricky business. First, let's just check that
2691    * 'range' isn't used, then set the range parameter and leave the resume as
2692    * it is to inform about this situation for later use. We will then
2693    * "attempt" to resume, and if we're talking to a HTTP/1.1 (or later)
2694    * server, we will get the document resumed. If we talk to a HTTP/1.0
2695    * server, we just fail since we can't rewind the file writing from within
2696    * this function.
2697    ***********************************************************/
2698   if(conn->resume_from) {
2699     if(!conn->bits.use_range) {
2700       /* if it already was in use, we just skip this */
2701       conn->range = aprintf("%" FORMAT_OFF_T "-", conn->resume_from);
2702       if(!conn->range)
2703         return CURLE_OUT_OF_MEMORY;
2704       conn->bits.rangestringalloc = TRUE; /* mark as allocated */
2705       conn->bits.use_range = 1; /* switch on range usage */
2706     }
2707   }
2708 #endif
2709   /*************************************************************
2710    * Setup internals depending on protocol
2711    *************************************************************/
2712
2713   if (strequal(conn->protostr, "HTTP")) {
2714 #ifndef CURL_DISABLE_HTTP
2715     conn->port = (data->set.use_port && data->state.allow_port)?
2716       data->set.use_port:PORT_HTTP;
2717     conn->remote_port = PORT_HTTP;
2718     conn->protocol |= PROT_HTTP;
2719     conn->curl_do = Curl_http;
2720     conn->curl_do_more = NULL;
2721     conn->curl_done = Curl_http_done;
2722     conn->curl_connect = Curl_http_connect;
2723 #else
2724     failf(data, LIBCURL_NAME
2725           " was built with HTTP disabled, http: not supported!");
2726     return CURLE_UNSUPPORTED_PROTOCOL;
2727 #endif
2728   }
2729   else if (strequal(conn->protostr, "HTTPS")) {
2730 #if defined(USE_SSLEAY) && !defined(CURL_DISABLE_HTTP)
2731
2732     conn->port = (data->set.use_port && data->state.allow_port)?
2733       data->set.use_port:PORT_HTTPS;
2734     conn->remote_port = PORT_HTTPS;
2735     conn->protocol |= PROT_HTTP|PROT_HTTPS|PROT_SSL;
2736
2737     conn->curl_do = Curl_http;
2738     conn->curl_do_more = NULL;
2739     conn->curl_done = Curl_http_done;
2740     conn->curl_connect = Curl_http_connect;
2741
2742 #else /* USE_SSLEAY */
2743     failf(data, LIBCURL_NAME
2744           " was built with SSL disabled, https: not supported!");
2745     return CURLE_UNSUPPORTED_PROTOCOL;
2746 #endif /* !USE_SSLEAY */
2747   }
2748   else if (strequal(conn->protostr, "GOPHER")) {
2749 #ifndef CURL_DISABLE_GOPHER
2750     conn->port = (data->set.use_port && data->state.allow_port)?
2751       data->set.use_port:PORT_GOPHER;
2752     conn->remote_port = PORT_GOPHER;
2753     /* Skip /<item-type>/ in path if present */
2754     if (isdigit((int)conn->path[1])) {
2755       conn->path = strchr(&conn->path[1], '/');
2756       if (conn->path == NULL)
2757         conn->path = conn->pathbuffer;
2758     }
2759     conn->protocol |= PROT_GOPHER;
2760     conn->curl_do = Curl_http;
2761     conn->curl_do_more = NULL;
2762     conn->curl_done = Curl_http_done;
2763 #else
2764     failf(data, LIBCURL_NAME
2765           " was built with GOPHER disabled, gopher: not supported!");
2766 #endif
2767   }
2768   else if(strequal(conn->protostr, "FTP") ||
2769           strequal(conn->protostr, "FTPS")) {
2770
2771 #ifndef CURL_DISABLE_FTP
2772     char *type;
2773     int port = PORT_FTP;
2774
2775     if(strequal(conn->protostr, "FTPS")) {
2776 #ifdef USE_SSLEAY
2777       conn->protocol |= PROT_FTPS|PROT_SSL;
2778       conn->ssl[SECONDARYSOCKET].use = TRUE; /* send data securely */
2779       port = PORT_FTPS;
2780 #else
2781       failf(data, LIBCURL_NAME
2782             " was built with SSL disabled, ftps: not supported!");
2783       return CURLE_UNSUPPORTED_PROTOCOL;
2784 #endif /* !USE_SSLEAY */
2785     }
2786
2787     conn->port = (data->set.use_port && data->state.allow_port)?
2788       data->set.use_port:port;
2789     conn->remote_port = port;
2790     conn->protocol |= PROT_FTP;
2791
2792     if(data->change.proxy &&
2793        *data->change.proxy &&
2794        !data->set.tunnel_thru_httpproxy) {
2795       /* Unless we have asked to tunnel ftp operations through the proxy, we
2796          switch and use HTTP operations only */
2797       if(conn->protocol & PROT_FTPS) {
2798         /* FTPS is a hacked protocol and does not work through your
2799            ordinary http proxy! */
2800         failf(data, "ftps does not work through http proxy!");
2801         return CURLE_UNSUPPORTED_PROTOCOL;
2802       }
2803 #ifndef CURL_DISABLE_HTTP
2804       conn->curl_do = Curl_http;
2805       conn->curl_done = Curl_http_done;
2806 #else
2807       failf(data, "FTP over http proxy requires HTTP support built-in!");
2808       return CURLE_UNSUPPORTED_PROTOCOL;
2809 #endif
2810     }
2811     else {
2812       conn->curl_do = Curl_ftp;
2813       conn->curl_do_more = Curl_ftp_nextconnect;
2814       conn->curl_done = Curl_ftp_done;
2815       conn->curl_connect = Curl_ftp_connect;
2816       conn->curl_connecting = Curl_ftp_multi_statemach;
2817       conn->curl_doing = Curl_ftp_doing;
2818       conn->curl_proto_fdset = Curl_ftp_fdset;
2819       conn->curl_doing_fdset = Curl_ftp_fdset;
2820       conn->curl_disconnect = Curl_ftp_disconnect;
2821     }
2822
2823     conn->path++; /* don't include the initial slash */
2824
2825     /* FTP URLs support an extension like ";type=<typecode>" that
2826      * we'll try to get now! */
2827     type=strstr(conn->path, ";type=");
2828     if(!type) {
2829       type=strstr(conn->host.rawalloc, ";type=");
2830     }
2831     if(type) {
2832       char command;
2833       *type=0;                     /* it was in the middle of the hostname */
2834       command = toupper((int)type[6]);
2835       switch(command) {
2836       case 'A': /* ASCII mode */
2837         data->set.ftp_ascii = 1;
2838         break;
2839       case 'D': /* directory mode */
2840         data->set.ftp_list_only = 1;
2841         break;
2842       case 'I': /* binary mode */
2843       default:
2844         /* switch off ASCII */
2845         data->set.ftp_ascii = 0;
2846         break;
2847       }
2848     }
2849 #else /* CURL_DISABLE_FTP */
2850     failf(data, LIBCURL_NAME
2851           " was built with FTP disabled, ftp/ftps: not supported!");
2852     return CURLE_UNSUPPORTED_PROTOCOL;
2853 #endif
2854   }
2855   else if(strequal(conn->protostr, "TELNET")) {
2856 #ifndef CURL_DISABLE_TELNET
2857     /* telnet testing factory */
2858     conn->protocol |= PROT_TELNET;
2859
2860     conn->port = (data->set.use_port && data->state.allow_port)?
2861       data->set.use_port: PORT_TELNET;
2862     conn->remote_port = PORT_TELNET;
2863     conn->curl_do = Curl_telnet;
2864     conn->curl_done = Curl_telnet_done;
2865 #else
2866     failf(data, LIBCURL_NAME
2867           " was built with TELNET disabled!");
2868 #endif
2869   }
2870   else if (strequal(conn->protostr, "DICT")) {
2871 #ifndef CURL_DISABLE_DICT
2872     conn->protocol |= PROT_DICT;
2873     conn->port = (data->set.use_port && data->state.allow_port)?
2874       data->set.use_port:PORT_DICT;
2875     conn->remote_port = PORT_DICT;
2876     conn->curl_do = Curl_dict;
2877     conn->curl_done = NULL; /* no DICT-specific done */
2878 #else
2879     failf(data, LIBCURL_NAME
2880           " was built with DICT disabled!");
2881 #endif
2882   }
2883   else if (strequal(conn->protostr, "LDAP")) {
2884 #ifndef CURL_DISABLE_LDAP
2885     conn->protocol |= PROT_LDAP;
2886     conn->port = (data->set.use_port && data->state.allow_port)?
2887       data->set.use_port:PORT_LDAP;
2888     conn->remote_port = PORT_LDAP;
2889     conn->curl_do = Curl_ldap;
2890     conn->curl_done = NULL; /* no LDAP-specific done */
2891 #else
2892     failf(data, LIBCURL_NAME
2893           " was built with LDAP disabled!");
2894 #endif
2895   }
2896   else if (strequal(conn->protostr, "FILE")) {
2897 #ifndef CURL_DISABLE_FILE
2898     conn->protocol |= PROT_FILE;
2899
2900     conn->curl_do = Curl_file;
2901     conn->curl_done = Curl_file_done;
2902
2903     /* anyway, this is supposed to be the connect function so we better
2904        at least check that the file is present here! */
2905     result = Curl_file_connect(conn);
2906
2907     /* Setup a "faked" transfer that'll do nothing */
2908     if(CURLE_OK == result) {
2909       conn->bits.tcpconnect = TRUE; /* we are "connected */
2910       result = Curl_Transfer(conn, -1, -1, FALSE, NULL, /* no download */
2911                              -1, NULL); /* no upload */
2912     }
2913
2914     return result;
2915 #else
2916     failf(data, LIBCURL_NAME
2917           " was built with FILE disabled!");
2918 #endif
2919   }
2920   else {
2921     /* We fell through all checks and thus we don't support the specified
2922        protocol */
2923     failf(data, "Unsupported protocol: %s", conn->protostr);
2924     return CURLE_UNSUPPORTED_PROTOCOL;
2925   }
2926
2927   if(data->change.proxy && *data->change.proxy) {
2928     /* If this is supposed to use a proxy, we need to figure out the proxy
2929        host name name, so that we can re-use an existing connection
2930        that may exist registered to the same proxy host. */
2931
2932     char *prox_portno;
2933     char *endofprot;
2934
2935     /* We need to make a duplicate of the proxy so that we can modify the
2936        string safely. */
2937     char *proxydup=strdup(data->change.proxy);
2938
2939     /* We use 'proxyptr' to point to the proxy name from now on... */
2940     char *proxyptr=proxydup;
2941
2942     if(NULL == proxydup) {
2943       failf(data, "memory shortage");
2944       return CURLE_OUT_OF_MEMORY;
2945     }
2946
2947     /* Daniel Dec 10, 1998:
2948        We do the proxy host string parsing here. We want the host name and the
2949        port name. Accept a protocol:// prefix, even though it should just be
2950        ignored. */
2951
2952     /* 1. skip the protocol part if present */
2953     endofprot=strstr(proxyptr, "://");
2954     if(endofprot) {
2955       proxyptr = endofprot+3;
2956     }
2957
2958     /* allow user to specify proxy.server.com:1080 if desired */
2959     prox_portno = strchr (proxyptr, ':');
2960     if (prox_portno) {
2961       *prox_portno = 0x0; /* cut off number from host name */
2962       prox_portno ++;
2963       /* now set the local port number */
2964       conn->port = atoi(prox_portno);
2965     }
2966     else if(data->set.proxyport) {
2967       /* None given in the proxy string, then get the default one if it is
2968          given */
2969       conn->port = data->set.proxyport;
2970     }
2971
2972     /* now, clone the cleaned proxy host name */
2973     conn->proxy.rawalloc = strdup(proxyptr);
2974     conn->proxy.name = conn->proxy.rawalloc;
2975
2976     free(proxydup); /* free the duplicate pointer and not the modified */
2977     if(!conn->proxy.rawalloc)
2978       return CURLE_OUT_OF_MEMORY;
2979   }
2980
2981   /*************************************************************
2982    * If the protcol is using SSL and HTTP proxy is used, we set
2983    * the tunnel_proxy bit.
2984    *************************************************************/
2985   if((conn->protocol&PROT_SSL) && conn->bits.httpproxy)
2986     conn->bits.tunnel_proxy = TRUE;
2987
2988   /*************************************************************
2989    * Take care of user and password authentication stuff
2990    *************************************************************/
2991
2992   /*
2993    * Inputs: data->set.userpwd   (CURLOPT_USERPWD)
2994    *         data->set.fpasswd   (CURLOPT_PASSWDFUNCTION)
2995    *         data->set.use_netrc (CURLOPT_NETRC)
2996    *         conn->host.name
2997    *         netrc file
2998    *         hard-coded defaults
2999    *
3000    * Outputs: (almost :- all currently undefined)
3001    *          conn->bits.user_passwd  - non-zero if non-default passwords exist
3002    *          conn->user              - non-zero length if defined
3003    *          conn->passwd            -   ditto
3004    *          conn->host.name          - remove user name and password
3005    */
3006
3007   /* At this point, we're hoping all the other special cases have
3008    * been taken care of, so conn->host.name is at most
3009    *    [user[:password]]@]hostname
3010    *
3011    * We need somewhere to put the embedded details, so do that first.
3012    */
3013
3014   user[0] =0;   /* to make everything well-defined */
3015   passwd[0]=0;
3016
3017   if (conn->protocol & (PROT_FTP|PROT_HTTP)) {
3018     /* This is a FTP or HTTP URL, we will now try to extract the possible
3019      * user+password pair in a string like:
3020      * ftp://user:password@ftp.my.site:8021/README */
3021     char *ptr=strchr(conn->host.name, '@');
3022     char *userpass = conn->host.name;
3023     if(ptr != NULL) {
3024       /* there's a user+password given here, to the left of the @ */
3025
3026       conn->host.name = ++ptr;
3027
3028       /* So the hostname is sane.  Only bother interpreting the
3029        * results if we could care.  It could still be wasted
3030        * work because it might be overtaken by the programmatically
3031        * set user/passwd, but doing that first adds more cases here :-(
3032        */
3033
3034       if (data->set.use_netrc != CURL_NETRC_REQUIRED) {
3035         /* We could use the one in the URL */
3036
3037         conn->bits.user_passwd = 1; /* enable user+password */
3038
3039         if(*userpass != ':') {
3040           /* the name is given, get user+password */
3041           sscanf(userpass, "%127[^:@]:%127[^@]",
3042                  user, passwd);
3043         }
3044         else
3045           /* no name given, get the password only */
3046           sscanf(userpass, ":%127[^@]", passwd);
3047
3048         if(user[0]) {
3049           char *newname=curl_unescape(user, 0);
3050           if(!newname)
3051             return CURLE_OUT_OF_MEMORY;
3052           if(strlen(newname) < sizeof(user))
3053             strcpy(user, newname);
3054
3055           /* if the new name is longer than accepted, then just use
3056              the unconverted name, it'll be wrong but what the heck */
3057           free(newname);
3058         }
3059         if (passwd[0]) {
3060           /* we have a password found in the URL, decode it! */
3061           char *newpasswd=curl_unescape(passwd, 0);
3062           if(!newpasswd)
3063             return CURLE_OUT_OF_MEMORY;
3064           if(strlen(newpasswd) < sizeof(passwd))
3065             strcpy(passwd, newpasswd);
3066
3067           free(newpasswd);
3068         }
3069       }
3070     }
3071   }
3072
3073   /*************************************************************
3074    * Figure out the remote port number
3075    *
3076    * No matter if we use a proxy or not, we have to figure out the remote
3077    * port number of various reasons.
3078    *
3079    * To be able to detect port number flawlessly, we must not confuse them
3080    * IPv6-specified addresses in the [0::1] style. (RFC2732)
3081    *
3082    * The conn->host.name is currently [user:passwd@]host[:port] where host
3083    * could be a hostname, IPv4 address or IPv6 address.
3084    *************************************************************/
3085   if((1 == sscanf(conn->host.name, "[%*39[0-9a-fA-F:.]%c", &endbracket)) &&
3086      (']' == endbracket)) {
3087     /* this is a RFC2732-style specified IP-address */
3088     conn->bits.ipv6_ip = TRUE;
3089
3090     conn->host.name++; /* pass the starting bracket */
3091     tmp = strchr(conn->host.name, ']');
3092     *tmp = 0; /* zero terminate */
3093     tmp++; /* pass the ending bracket */
3094     if(':' != *tmp)
3095       tmp = NULL; /* no port number available */
3096   }
3097   else
3098     tmp = strrchr(conn->host.name, ':');
3099
3100   if (tmp) {
3101     char *rest;
3102     unsigned long port;
3103
3104     port=strtoul(tmp+1, &rest, 10);  /* Port number must be decimal */
3105
3106     if (rest != (tmp+1) && *rest == '\0') {
3107       /* The colon really did have only digits after it,
3108        * so it is either a port number or a mistake */
3109
3110       if (port > 0xffff) {   /* Single unix standard says port numbers are
3111                               * 16 bits long */
3112         failf(data, "Port number too large: %lu", port);
3113         return CURLE_URL_MALFORMAT;
3114       }
3115
3116       *tmp = '\0'; /* cut off the name there */
3117       conn->remote_port = (unsigned short)port;
3118     }
3119   }
3120
3121   /* Programmatically set password:
3122    *   - always applies, if available
3123    *   - takes precedence over the values we just set above
3124    * so scribble it over the top.
3125    * User-supplied passwords are assumed not to need unescaping.
3126    *
3127    * user_password is set in "inherite initial knowledge' above,
3128    * so it doesn't have to be set in this block
3129    */
3130   if (data->set.userpwd != NULL) {
3131     /* the name is given, get user+password */
3132     sscanf(data->set.userpwd,
3133            "%" MAX_CURL_USER_LENGTH_TXT "[^:]:"
3134            "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^\n]",
3135            user, passwd);
3136   }
3137
3138   if (data->set.use_netrc != CURL_NETRC_IGNORED) {
3139     if(Curl_parsenetrc(conn->host.name,
3140                        user, passwd,
3141                        data->set.netrc_file)) {
3142       infof(data, "Couldn't find host %s in the " DOT_CHAR "netrc file, using defaults\n",
3143             conn->host.name);
3144     }
3145     else
3146       conn->bits.user_passwd = 1; /* enable user+password */
3147   }
3148
3149   /* If our protocol needs a password and we have none, use the defaults */
3150   if ( (conn->protocol & PROT_FTP) &&
3151        !conn->bits.user_passwd) {
3152
3153     conn->user = strdup(CURL_DEFAULT_USER);
3154     conn->passwd = strdup(CURL_DEFAULT_PASSWORD);
3155     /* This is the default password, so DON'T set conn->bits.user_passwd */
3156   }
3157   else {
3158     /* store user + password, zero-length if not set */
3159     conn->user = strdup(user);
3160     conn->passwd = strdup(passwd);
3161   }
3162   if(!conn->user || !conn->passwd)
3163     return CURLE_OUT_OF_MEMORY;
3164
3165   /*************************************************************
3166    * Check the current list of connections to see if we can
3167    * re-use an already existing one or if we have to create a
3168    * new one.
3169    *************************************************************/
3170
3171   /* get a cloned copy of the SSL config situation stored in the
3172      connection struct */
3173   if(!Curl_clone_ssl_config(&data->set.ssl, &conn->ssl_config))
3174     return CURLE_OUT_OF_MEMORY;
3175
3176   /* reuse_fresh is TRUE if we are told to use a new connection by force, but
3177      we only acknowledge this option if this is not a re-used connection
3178      already (which happens due to follow-location or during a HTTP
3179      authentication phase). */
3180   if(data->set.reuse_fresh && !data->state.this_is_a_follow)
3181     reuse = FALSE;
3182   else
3183     reuse = ConnectionExists(data, conn, &conn_temp);
3184
3185   if(reuse) {
3186     /*
3187      * We already have a connection for this, we got the former connection
3188      * in the conn_temp variable and thus we need to cleanup the one we
3189      * just allocated before we can move along and use the previously
3190      * existing one.
3191      */
3192     struct connectdata *old_conn = conn;
3193
3194     if(old_conn->proxy.rawalloc)
3195       free(old_conn->proxy.rawalloc);
3196
3197     /* free the SSL config struct from this connection struct as this was
3198        allocated in vain and is targeted for destruction */
3199     Curl_free_ssl_config(&conn->ssl_config);
3200
3201     conn = conn_temp;        /* use this connection from now on */
3202
3203     /* get the user+password information from the old_conn struct since it may
3204      * be new for this request even when we re-use an existing connection */
3205     conn->bits.user_passwd = old_conn->bits.user_passwd;
3206     if (conn->bits.user_passwd) {
3207       /* use the new user namd and password though */
3208       Curl_safefree(conn->user);
3209       Curl_safefree(conn->passwd);
3210       conn->user = old_conn->user;
3211       conn->passwd = old_conn->passwd;
3212       old_conn->user = NULL;
3213       old_conn->passwd = NULL;
3214     }
3215
3216     conn->bits.proxy_user_passwd = old_conn->bits.proxy_user_passwd;
3217     if (conn->bits.proxy_user_passwd) {
3218       /* use the new proxy user name and proxy password though */
3219       Curl_safefree(conn->proxyuser);
3220       Curl_safefree(conn->proxypasswd);
3221       conn->proxyuser = old_conn->proxyuser;
3222       conn->proxypasswd = old_conn->proxypasswd;
3223       old_conn->proxyuser = NULL;
3224       old_conn->proxypasswd = NULL;
3225     }
3226
3227     /* host can change, when doing keepalive with a proxy ! */
3228     if (conn->bits.httpproxy) {
3229       free(conn->host.rawalloc);
3230       conn->host=old_conn->host;
3231     }
3232
3233     /* get the newly set value, not the old one */
3234     conn->bits.no_body = old_conn->bits.no_body;
3235
3236     if (!conn->bits.httpproxy)
3237       free(old_conn->host.rawalloc); /* free the newly allocated name buffer */
3238
3239     free(conn->pathbuffer); /* free the newly allocated path pointer */
3240     conn->pathbuffer = old_conn->pathbuffer; /* use the old one */
3241     conn->path = old_conn->path;
3242
3243     /* re-use init */
3244     conn->bits.reuse = TRUE; /* yes, we're re-using here */
3245     conn->bits.chunk = FALSE; /* always assume not chunked unless told
3246                                  otherwise */
3247     conn->maxdownload = -1;  /* might have been used previously! */
3248
3249     Curl_safefree(old_conn->user);
3250     Curl_safefree(old_conn->passwd);
3251     Curl_safefree(old_conn->proxyuser);
3252     Curl_safefree(old_conn->proxypasswd);
3253
3254     if(old_conn->bits.rangestringalloc)
3255       free(old_conn->range);
3256
3257     free(old_conn);          /* we don't need this anymore */
3258
3259     /*
3260      * If we're doing a resumed transfer, we need to setup our stuff
3261      * properly.
3262      */
3263     conn->resume_from = data->set.set_resume_from;
3264     if (conn->resume_from) {
3265       if (conn->bits.rangestringalloc == TRUE)
3266         free(conn->range);
3267       conn->range = aprintf("%" FORMAT_OFF_T "-", conn->resume_from);
3268       if(!conn->range)
3269         return CURLE_OUT_OF_MEMORY;
3270
3271       /* tell ourselves to fetch this range */
3272       conn->bits.use_range = TRUE;        /* enable range download */
3273       conn->bits.rangestringalloc = TRUE; /* mark range string allocated */
3274     }
3275     else if (data->set.set_range) {
3276       /* There is a range, but is not a resume, useful for random ftp access */
3277       conn->range = strdup(data->set.set_range);
3278       if(!conn->range)
3279         return CURLE_OUT_OF_MEMORY;
3280       conn->bits.rangestringalloc = TRUE; /* mark range string allocated */
3281       conn->bits.use_range = TRUE;        /* enable range download */
3282     }
3283     else
3284       conn->bits.use_range = FALSE; /* disable range download */
3285
3286     *in_connect = conn;      /* return this instead! */
3287
3288     infof(data, "Re-using existing connection! (#%ld) with host %s\n",
3289           conn->connectindex,
3290           conn->bits.httpproxy?conn->proxy.dispname:conn->host.dispname);
3291   }
3292   else {
3293     /*
3294      * This is a brand new connection, so let's store it in the connection
3295      * cache of ours!
3296      */
3297     ConnectionStore(data, conn);
3298   }
3299
3300   /* Continue connectdata initialization here.
3301    *
3302    * Inherit the proper values from the urldata struct AFTER we have arranged
3303    * the persistant conncetion stuff */
3304   conn->fread = data->set.fread;
3305   conn->fread_in = data->set.in;
3306
3307   conn->bits.upload_chunky =
3308     ((conn->protocol&PROT_HTTP) &&
3309      data->set.upload &&
3310      (data->set.infilesize == -1) &&
3311      (data->set.httpversion != CURL_HTTP_VERSION_1_0))?
3312     /* HTTP, upload, unknown file size and not HTTP 1.0 */
3313     TRUE:
3314   /* else, no chunky upload */
3315   FALSE;
3316
3317 #ifndef USE_ARES
3318   /*************************************************************
3319    * Set timeout if that is being used, and we're not using an asynchronous
3320    * name resolve.
3321    *************************************************************/
3322   if((data->set.timeout || data->set.connecttimeout) && !data->set.no_signal) {
3323     /*************************************************************
3324      * Set signal handler to catch SIGALRM
3325      * Store the old value to be able to set it back later!
3326      *************************************************************/
3327
3328 #ifdef SIGALRM
3329 #ifdef HAVE_SIGACTION
3330     struct sigaction sigact;
3331     sigaction(SIGALRM, NULL, &sigact);
3332     keep_sigact = sigact;
3333     keep_copysig = TRUE; /* yes, we have a copy */
3334     sigact.sa_handler = alarmfunc;
3335 #ifdef SA_RESTART
3336     /* HPUX doesn't have SA_RESTART but defaults to that behaviour! */
3337     sigact.sa_flags &= ~SA_RESTART;
3338 #endif
3339     /* now set the new struct */
3340     sigaction(SIGALRM, &sigact, NULL);
3341 #else /* HAVE_SIGACTION */
3342     /* no sigaction(), revert to the much lamer signal() */
3343 #ifdef HAVE_SIGNAL
3344     keep_sigact = signal(SIGALRM, alarmfunc);
3345 #endif
3346 #endif /* HAVE_SIGACTION */
3347
3348     /* We set the timeout on the name resolving phase first, separately from
3349      * the download/upload part to allow a maximum time on everything. This is
3350      * a signal-based timeout, why it won't work and shouldn't be used in
3351      * multi-threaded environments. */
3352
3353 #ifdef HAVE_ALARM
3354     /* alarm() makes a signal get sent when the timeout fires off, and that
3355        will abort system calls */
3356     prev_alarm = alarm(data->set.connecttimeout?
3357                        data->set.connecttimeout:
3358                        data->set.timeout);
3359     /* We can expect the conn->created time to be "now", as that was just
3360        recently set in the beginning of this function and nothing slow
3361        has been done since then until now. */
3362 #endif
3363 #endif /* SIGALRM */
3364   }
3365 #endif /* USE_ARES */
3366
3367   /*************************************************************
3368    * Resolve the name of the server or proxy
3369    *************************************************************/
3370   if(conn->bits.reuse) {
3371     /* re-used connection, no resolving is necessary */
3372     hostaddr = NULL;
3373     /* we'll need to clear conn->dns_entry later in Curl_disconnect() */
3374
3375     if (conn->bits.httpproxy)
3376       fix_hostname(conn, &conn->host);
3377   }
3378   else {
3379     /* this is a fresh connect */
3380
3381     /* set a pointer to the hostname we display */
3382     fix_hostname(conn, &conn->host);
3383
3384     if(!data->change.proxy || !*data->change.proxy) {
3385       /* If not connecting via a proxy, extract the port from the URL, if it is
3386        * there, thus overriding any defaults that might have been set above. */
3387       conn->port =  conn->remote_port; /* it is the same port */
3388
3389       /* Resolve target host right on */
3390       rc = Curl_resolv(conn, conn->host.name, (int)conn->port, &hostaddr);
3391       if(rc == CURLRESOLV_PENDING)
3392         *async = TRUE;
3393
3394       else if(!hostaddr) {
3395         failf(data, "Couldn't resolve host '%s'", conn->host.dispname);
3396         result =  CURLE_COULDNT_RESOLVE_HOST;
3397         /* don't return yet, we need to clean up the timeout first */
3398       }
3399     }
3400     else {
3401       /* This is a proxy that hasn't been resolved yet. */
3402
3403       /* IDN-fix the proxy name */
3404       fix_hostname(conn, &conn->proxy);
3405
3406       /* resolve proxy */
3407       rc = Curl_resolv(conn, conn->proxy.name, (int)conn->port, &hostaddr);
3408
3409       if(rc == CURLRESOLV_PENDING)
3410         *async = TRUE;
3411
3412       else if(!hostaddr) {
3413         failf(data, "Couldn't resolve proxy '%s'", conn->proxy.dispname);
3414         result = CURLE_COULDNT_RESOLVE_PROXY;
3415         /* don't return yet, we need to clean up the timeout first */
3416       }
3417     }
3418   }
3419   *addr = hostaddr;
3420
3421 #if defined(HAVE_ALARM) && defined(SIGALRM) && !defined(USE_ARES)
3422   if((data->set.timeout || data->set.connecttimeout) && !data->set.no_signal) {
3423 #ifdef HAVE_SIGACTION
3424     if(keep_copysig) {
3425       /* we got a struct as it looked before, now put that one back nice
3426          and clean */
3427       sigaction(SIGALRM, &keep_sigact, NULL); /* put it back */
3428     }
3429 #else
3430 #ifdef HAVE_SIGNAL
3431     /* restore the previous SIGALRM handler */
3432     signal(SIGALRM, keep_sigact);
3433 #endif
3434 #endif /* HAVE_SIGACTION */
3435
3436     /* switch back the alarm() to either zero or to what it was before minus
3437        the time we spent until now! */
3438     if(prev_alarm) {
3439       /* there was an alarm() set before us, now put it back */
3440       unsigned long elapsed_ms = Curl_tvdiff(Curl_tvnow(), conn->created);
3441       unsigned long alarm_set;
3442
3443       /* the alarm period is counted in even number of seconds */
3444       alarm_set = prev_alarm - elapsed_ms/1000;
3445
3446       if(!alarm_set ||
3447          ((alarm_set >= 0x80000000) && (prev_alarm < 0x80000000)) ) {
3448         /* if the alarm time-left reached zero or turned "negative" (counted
3449            with unsigned values), we should fire off a SIGALRM here, but we
3450            won't, and zero would be to switch it off so we never set it to
3451            less than 1! */
3452         alarm(1);
3453         result = CURLE_OPERATION_TIMEOUTED;
3454         failf(data, "Previous alarm fired off!");
3455       }
3456       else
3457         alarm((unsigned int)alarm_set);
3458     }
3459     else
3460       alarm(0); /* just shut it off */
3461   }
3462 #endif
3463
3464   return result;
3465 }
3466
3467 /* SetupConnection() should be called after the name resolve initiated in
3468  * CreateConnection() is all done.
3469  */
3470
3471 static CURLcode SetupConnection(struct connectdata *conn,
3472                                 struct Curl_dns_entry *hostaddr,
3473                                 bool *protocol_done)
3474 {
3475   struct SessionHandle *data = conn->data;
3476   CURLcode result=CURLE_OK;
3477
3478   Curl_pgrsTime(data, TIMER_NAMELOOKUP);
3479
3480   if(conn->protocol & PROT_FILE) {
3481     /* There's nothing in this function to setup if we're only doing
3482        a file:// transfer */
3483     *protocol_done = TRUE;
3484     return result;
3485   }
3486   *protocol_done = FALSE; /* default to not done */
3487
3488   /*************************************************************
3489    * Send user-agent to HTTP proxies even if the target protocol
3490    * isn't HTTP.
3491    *************************************************************/
3492   if((conn->protocol&PROT_HTTP) ||
3493      (data->change.proxy && *data->change.proxy)) {
3494     if(data->set.useragent) {
3495       Curl_safefree(conn->allocptr.uagent);
3496       conn->allocptr.uagent =
3497         aprintf("User-Agent: %s\015\012", data->set.useragent);
3498       if(!conn->allocptr.uagent)
3499         return CURLE_OUT_OF_MEMORY;
3500     }
3501   }
3502
3503   conn->bytecount = 0;
3504   conn->headerbytecount = 0;
3505
3506   if(CURL_SOCKET_BAD == conn->sock[FIRSTSOCKET]) {
3507     bool connected = FALSE;
3508
3509     /* Connect only if not already connected! */
3510     result = ConnectPlease(conn, hostaddr, &connected);
3511
3512     if(connected) {
3513       result = Curl_protocol_connect(conn, protocol_done);
3514       if(CURLE_OK == result)
3515         conn->bits.tcpconnect = TRUE;
3516     }
3517     else
3518       conn->bits.tcpconnect = FALSE;
3519
3520
3521     if(CURLE_OK != result)
3522       return result;
3523   }
3524   else {
3525     Curl_pgrsTime(data, TIMER_CONNECT); /* we're connected already */
3526     conn->bits.tcpconnect = TRUE;
3527     *protocol_done = TRUE;
3528     if(data->set.verbose)
3529       verboseconnect(conn);
3530   }
3531
3532   conn->now = Curl_tvnow(); /* time this *after* the connect is done, we
3533                                set this here perhaps a second time */
3534
3535 #ifdef __EMX__
3536   /* 20000330 mgs
3537    * the check is quite a hack...
3538    * we're calling _fsetmode to fix the problem with fwrite converting newline
3539    * characters (you get mangled text files, and corrupted binary files when
3540    * you download to stdout and redirect it to a file). */
3541
3542   if ((data->set.out)->_handle == NULL) {
3543     _fsetmode(stdout, "b");
3544   }
3545 #endif
3546
3547   return CURLE_OK;
3548 }
3549
3550 CURLcode Curl_connect(struct SessionHandle *data,
3551                       struct connectdata **in_connect,
3552                       bool *asyncp,
3553                       bool *protocol_done)
3554 {
3555   CURLcode code;
3556   struct Curl_dns_entry *dns;
3557
3558   *asyncp = FALSE; /* assume synchronous resolves by default */
3559
3560   /* call the stuff that needs to be called */
3561   code = CreateConnection(data, in_connect, &dns, asyncp);
3562
3563   if(CURLE_OK == code) {
3564     /* no error */
3565     if(dns || !*asyncp)
3566       /* If an address is available it means that we already have the name
3567          resolved, OR it isn't async.
3568          If so => continue connecting from here */
3569       code = SetupConnection(*in_connect, dns, protocol_done);
3570     /* else
3571          response will be received and treated async wise */
3572   }
3573
3574   if(CURLE_OK != code) {
3575     /* We're not allowed to return failure with memory left allocated
3576        in the connectdata struct, free those here */
3577     if(*in_connect) {
3578       Curl_disconnect(*in_connect); /* close the connection */
3579       *in_connect = NULL;           /* return a NULL */
3580     }
3581   }
3582
3583   return code;
3584 }
3585
3586 /* Call this function after Curl_connect() has returned async=TRUE and
3587    then a successful name resolve has been received.
3588
3589    Note: this function disconnects and frees the conn data in case of
3590    resolve failure */
3591 CURLcode Curl_async_resolved(struct connectdata *conn,
3592                              bool *protocol_done)
3593 {
3594 #if defined(USE_ARES) || defined(USE_THREADING_GETHOSTBYNAME) || \
3595     defined(USE_THREADING_GETADDRINFO)
3596   CURLcode code = SetupConnection(conn, conn->async.dns, protocol_done);
3597
3598   if(code)
3599     /* We're not allowed to return failure with memory left allocated
3600        in the connectdata struct, free those here */
3601     Curl_disconnect(conn); /* close the connection */
3602
3603   return code;
3604 #else
3605   (void)conn;
3606   (void)protocol_done;
3607   return CURLE_OK;
3608 #endif
3609 }
3610
3611
3612 CURLcode Curl_done(struct connectdata **connp,
3613                    CURLcode status) /* an error if this is called after an
3614                                        error was detected */
3615 {
3616   CURLcode result;
3617   struct connectdata *conn = *connp;
3618   struct SessionHandle *data=conn->data;
3619
3620   /* cleanups done even if the connection is re-used */
3621   if(conn->bits.rangestringalloc) {
3622     free(conn->range);
3623     conn->bits.rangestringalloc = FALSE;
3624   }
3625
3626   if(conn->dns_entry) {
3627     Curl_resolv_unlock(data, conn->dns_entry); /* done with this */
3628     conn->dns_entry = NULL;
3629   }
3630
3631   /* Cleanup possible redirect junk */
3632   if(conn->newurl) {
3633     free(conn->newurl);
3634     conn->newurl = NULL;
3635   }
3636
3637   /* this calls the protocol-specific function pointer previously set */
3638   if(conn->curl_done)
3639     result = conn->curl_done(conn, status);
3640   else
3641     result = CURLE_OK;
3642
3643   Curl_pgrsDone(conn); /* done with the operation */
3644
3645   /* if data->set.reuse_forbid is TRUE, it means the libcurl client has
3646      forced us to close this no matter what we think.
3647
3648      if conn->bits.close is TRUE, it means that the connection should be
3649      closed in spite of all our efforts to be nice, due to protocol
3650      restrictions in our or the server's end */
3651   if(data->set.reuse_forbid || conn->bits.close) {
3652     CURLcode res2;
3653     res2 = Curl_disconnect(conn); /* close the connection */
3654
3655     *connp = NULL; /* to make the caller of this function better detect that
3656                       this was actually killed here */
3657
3658     /* If we had an error already, make sure we return that one. But
3659        if we got a new error, return that. */
3660     if(!result && res2)
3661       result = res2;
3662   }
3663   else
3664     infof(data, "Connection #%ld to host %s left intact\n",
3665           conn->connectindex,
3666           conn->bits.httpproxy?conn->proxy.dispname:conn->host.dispname);
3667
3668   return result;
3669 }
3670
3671 CURLcode Curl_do(struct connectdata **connp, bool *done)
3672 {
3673   CURLcode result=CURLE_OK;
3674   struct connectdata *conn = *connp;
3675   struct SessionHandle *data=conn->data;
3676
3677   conn->bits.do_more = FALSE; /* by default there's no curl_do_more() to use */
3678
3679   if(conn->curl_do) {
3680     /* generic protocol-specific function pointer set in curl_connect() */
3681     result = conn->curl_do(conn, done);
3682
3683     /* This was formerly done in transfer.c, but we better do it here */
3684
3685     if((CURLE_SEND_ERROR == result) && conn->bits.reuse) {
3686       /* This was a re-use of a connection and we got a write error in the
3687        * DO-phase. Then we DISCONNECT this connection and have another attempt
3688        * to CONNECT and then DO again! The retry cannot possibly find another
3689        * connection to re-use, since we only keep one possible connection for
3690        * each.  */
3691
3692       infof(data, "Re-used connection seems dead, get a new one\n");
3693
3694       conn->bits.close = TRUE; /* enforce close of this connection */
3695       result = Curl_done(&conn, result); /* we are so done with this */
3696
3697       /* conn may no longer be a good pointer */
3698
3699       if(CURLE_OK == result) {
3700         bool async;
3701         bool protocol_done = TRUE;
3702
3703         /* Now, redo the connect and get a new connection */
3704         result = Curl_connect(data, connp, &async, &protocol_done);
3705         if(CURLE_OK == result) {
3706           /* We have connected or sent away a name resolve query fine */
3707
3708           conn = *connp; /* setup conn to again point to something nice */
3709           if(async) {
3710             /* Now, if async is TRUE here, we need to wait for the name
3711                to resolve */
3712             result = Curl_wait_for_resolv(conn, NULL);
3713             if(result)
3714               return result;
3715
3716             /* Resolved, continue with the connection */
3717             result = Curl_async_resolved(conn, &protocol_done);
3718             if(result)
3719               return result;
3720           }
3721
3722           /* ... finally back to actually retry the DO phase */
3723           result = conn->curl_do(conn, done);
3724         }
3725       }
3726     }
3727   }
3728   return result;
3729 }
3730
3731 CURLcode Curl_do_more(struct connectdata *conn)
3732 {
3733   CURLcode result=CURLE_OK;
3734
3735   if(conn->curl_do_more)
3736     result = conn->curl_do_more(conn);
3737
3738   return result;
3739 }
3740
3741 static bool safe_strequal(char* str1, char* str2)
3742 {
3743   if(str1 && str2)
3744     /* both pointers point to something then compare them */
3745     return strequal(str1, str2);
3746   else
3747     /* if both pointers are NULL then treat them as equal */
3748     return (!str1 && !str2);
3749 }
3750
3751 bool
3752 Curl_ssl_config_matches(struct ssl_config_data* data,
3753                         struct ssl_config_data* needle)
3754 {
3755   if((data->version == needle->version) &&
3756      (data->verifypeer == needle->verifypeer) &&
3757      (data->verifyhost == needle->verifyhost) &&
3758      safe_strequal(data->CApath, needle->CApath) &&
3759      safe_strequal(data->CAfile, needle->CAfile) &&
3760      safe_strequal(data->random_file, needle->random_file) &&
3761      safe_strequal(data->egdsocket, needle->egdsocket) &&
3762      safe_strequal(data->cipher_list, needle->cipher_list))
3763     return TRUE;
3764
3765   return FALSE;
3766 }
3767
3768 bool
3769 Curl_clone_ssl_config(struct ssl_config_data *source,
3770                       struct ssl_config_data *dest)
3771 {
3772   dest->verifyhost = source->verifyhost;
3773   dest->verifypeer = source->verifypeer;
3774   dest->version = source->version;
3775
3776   if(source->CAfile) {
3777     dest->CAfile = strdup(source->CAfile);
3778     if(!dest->CAfile)
3779       return FALSE;
3780   }
3781
3782   if(source->CApath) {
3783     dest->CApath = strdup(source->CApath);
3784     if(!dest->CApath)
3785       return FALSE;
3786   }
3787
3788   if(source->cipher_list) {
3789     dest->cipher_list = strdup(source->cipher_list);
3790     if(!dest->cipher_list)
3791       return FALSE;
3792   }
3793
3794   if(source->egdsocket) {
3795     dest->egdsocket = strdup(source->egdsocket);
3796     if(!dest->egdsocket)
3797       return FALSE;
3798   }
3799
3800   if(source->random_file) {
3801     dest->random_file = strdup(source->random_file);
3802     if(!dest->random_file)
3803       return FALSE;
3804   }
3805
3806   return TRUE;
3807 }
3808
3809 void Curl_free_ssl_config(struct ssl_config_data* sslc)
3810 {
3811   if(sslc->CAfile)
3812     free(sslc->CAfile);
3813
3814   if(sslc->CApath)
3815     free(sslc->CApath);
3816
3817   if(sslc->cipher_list)
3818     free(sslc->cipher_list);
3819
3820   if(sslc->egdsocket)
3821     free(sslc->egdsocket);
3822
3823   if(sslc->random_file)
3824     free(sslc->random_file);
3825 }
3826