diff -urN --exclude=CVS curl-7.9.7/lib/connect.c /home/sylam/work/EmLinux_cvs/curl/lib/connect.c --- curl-7.9.7/lib/connect.c Fri Apr 26 03:21:52 2002 +++ /home/sylam/work/EmLinux_cvs/curl/lib/connect.c Tue May 21 12:00:25 2002 @@ -18,7 +18,7 @@ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * - * $Id: connect.c,v 1.31 2002/04/25 19:00:57 bagder Exp $ + * $Id: connect.c,v 1.4 2002/05/03 10:56:22 sylam Exp $ *****************************************************************************/ #include "setup.h" @@ -238,6 +238,7 @@ hostent_buf, sizeof(hostent_buf)); */ + if(h) free(h); return CURLE_HTTP_PORT_FAILED; } @@ -266,6 +267,7 @@ if(getsockname(sockfd, (struct sockaddr *) &add, (socklen_t *)&size)<0) { failf(data, "getsockname() failed"); + if(h) free(h); return CURLE_HTTP_PORT_FAILED; } } @@ -299,21 +301,25 @@ break; } /* end of switch(errno) */ + if(h) free(h); return CURLE_HTTP_PORT_FAILED; } /* end of else */ } /* end of if h */ else { failf(data,"could't find my own IP address (%s)", myhost); + if(h) free(h); return CURLE_HTTP_PORT_FAILED; } } /* end of inet_addr */ else { failf(data, "could't find my own IP address (%s)", myhost); + if(h) free(h); return CURLE_HTTP_PORT_FAILED; } + if(h) free(h); return CURLE_OK; } /* end of device selection support */ diff -urN --exclude=CVS curl-7.9.7/lib/ftp.c /home/sylam/work/EmLinux_cvs/curl/lib/ftp.c --- curl-7.9.7/lib/ftp.c Mon Apr 29 19:57:25 2002 +++ /home/sylam/work/EmLinux_cvs/curl/lib/ftp.c Tue May 21 12:00:25 2002 @@ -18,7 +18,7 @@ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * - * $Id: ftp.c,v 1.141 2002/04/27 13:24:06 bagder Exp $ + * $Id: ftp.c,v 1.4 2002/05/03 10:56:22 sylam Exp $ *****************************************************************************/ #include "setup.h" @@ -1249,6 +1249,7 @@ if(getsockname(portsock, (struct sockaddr *) &add, &socksize)<0) { failf(data, "getsockname() failed"); + if(h) free(h); return CURLE_FTP_PORT_FAILED; } porttouse = ntohs(add.sin_port); @@ -1256,18 +1257,21 @@ if ( listen(portsock, 1) < 0 ) { failf(data, "listen(2) failed on socket"); free(hostdataptr); + if(h) free(h); return CURLE_FTP_PORT_FAILED; } } else { failf(data, "bind(2) failed on socket"); free(hostdataptr); + if(h) free(h); return CURLE_FTP_PORT_FAILED; } } else { failf(data, "socket(2) failed (%s)"); free(hostdataptr); + if(h) free(h); return CURLE_FTP_PORT_FAILED; } } @@ -1483,16 +1487,22 @@ ftp_pasv_verbose(conn, conninfo, newhostp, connectport); if(CURLE_OK != result) + { + if(addr) free(addr); return result; - + } if (data->set.tunnel_thru_httpproxy) { /* We want "seamless" FTP operations through HTTP proxy tunnel */ result = Curl_ConnectHTTPProxyTunnel(conn, conn->secondarysocket, newhostp, newport); if(CURLE_OK != result) - return result; + { + if(addr) free(addr); + return result; + } } + if(addr) free(addr); return CURLE_OK; } diff -urN --exclude=CVS curl-7.9.7/lib/hostip.c /home/sylam/work/EmLinux_cvs/curl/lib/hostip.c --- curl-7.9.7/lib/hostip.c Wed May 1 19:36:13 2002 +++ /home/sylam/work/EmLinux_cvs/curl/lib/hostip.c Tue May 21 12:00:25 2002 @@ -18,13 +18,14 @@ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * - * $Id: hostip.c,v 1.64 2002/05/01 11:36:13 bagder Exp $ + * $Id: hostip.c,v 1.11 2002/05/03 10:56:22 sylam Exp $ *****************************************************************************/ #include "setup.h" #include #include +#include #define _REENTRANT @@ -75,11 +76,14 @@ static curl_hash hostname_cache; static int host_cache_initialized; +static pthread_mutex_t host_cache_lock=PTHREAD_MUTEX_INITIALIZER; void Curl_global_host_cache_init(void) { if (!host_cache_initialized) { + pthread_mutex_lock(&host_cache_lock); Curl_hash_init(&hostname_cache, 7, Curl_freeaddrinfo); + pthread_mutex_unlock(&host_cache_lock); host_cache_initialized = 1; } } @@ -92,13 +96,16 @@ void Curl_global_host_cache_dtor(void) { if (host_cache_initialized) { + pthread_mutex_lock(&host_cache_lock); Curl_hash_clean(&hostname_cache); + pthread_mutex_unlock(&host_cache_lock); host_cache_initialized = 0; } } struct curl_dns_cache_entry { Curl_addrinfo *addr; + int size; time_t timestamp; }; @@ -167,7 +174,7 @@ if (data->now - c->timestamp < data->cache_timeout) { return 0; } - + return 1; } @@ -187,6 +194,7 @@ /* Macro to save redundant free'ing of entry_id */ #define _hostcache_return(__v) \ { \ + pthread_mutex_unlock(&host_cache_lock); \ free(entry_id); \ return (__v); \ } @@ -195,38 +203,48 @@ char *hostname, int port) { + Curl_addrinfo *ret=NULL; char *entry_id = NULL; struct curl_dns_cache_entry *p = NULL; ssize_t entry_len; time_t now; char *bufp; + int size; + int offset; /* If the host cache timeout is 0, we don't do DNS cach'ing so fall through */ if (data->set.dns_cache_timeout == 0) { - return Curl_getaddrinfo(data, hostname, port, &bufp); + ret=Curl_getaddrinfo(data, hostname, port, &bufp, &size); + return ret; } time(&now); - + pthread_mutex_lock(&host_cache_lock); /* Remove outdated entries from the hostcache */ hostcache_prune(data->hostcache, data->set.dns_cache_timeout, now); - + pthread_mutex_unlock(&host_cache_lock); /* Create an entry id, based upon the hostname and port */ entry_len = strlen(hostname); entry_id = _create_hostcache_id(hostname, port, &entry_len); /* If we can't create the entry id, don't cache, just fall-through to the plain Curl_getaddrinfo() */ if (!entry_id) { - return Curl_getaddrinfo(data, hostname, port, &bufp); + ret=Curl_getaddrinfo(data, hostname, port, &bufp, &size); + return ret; } /* See if its already in our dns cache */ + pthread_mutex_lock(&host_cache_lock); if (entry_id && Curl_hash_find(data->hostcache, entry_id, entry_len+1, (void **) &p)) { - _hostcache_return(p->addr); + ret=(Curl_addrinfo *)malloc(p->size); + memcpy(ret, p->addr, p->size); + offset=(int)ret-(int)(p->addr); + hostcache_fixoffset(ret, offset); + _hostcache_return(ret); } /* Create a new cache entry */ @@ -236,17 +254,22 @@ _hostcache_return(NULL); } - p->addr = Curl_getaddrinfo(data, hostname, port, &bufp); + p->addr = Curl_getaddrinfo(data, hostname, port, &bufp, &size); if (!p->addr) { free(p); _hostcache_return(NULL); } p->timestamp = now; + p->size=size; /* Save it in our host cache */ Curl_hash_update(data->hostcache, entry_id, entry_len+1, (const void *) p); - _hostcache_return(p->addr); + ret=(Curl_addrinfo *)malloc(p->size); + memcpy(ret, p->addr, p->size); + offset=(int)ret-(int)(p->addr); + hostcache_fixoffset(ret, offset); + _hostcache_return(ret); } /* @@ -353,6 +376,31 @@ } #else /* following code is IPv4-only */ +static void hostcache_fixoffset(struct hostent *h, int offset) +{ + int i=0; + h->h_name=(char *)((int)h->h_name+offset); + if(h->h_aliases) + { + h->h_aliases=(char **)((int)h->h_aliases+offset); + while(h->h_aliases[i]) + { + h->h_aliases[i]=(char *)((int)h->h_aliases[i]+offset); + i++; + } + } + if(h->h_addr_list) + { + h->h_addr_list=(char **)((int)h->h_addr_list+offset); + i=0; + while(h->h_addr_list[i]) + { + h->h_addr_list[i]=(char *)((int)h->h_addr_list[i]+offset); + i++; + } + } +} + #ifndef HAVE_GETHOSTBYNAME_R /** * Performs a "deep" copy of a hostent into a buffer (returns a pointer to the @@ -360,7 +408,7 @@ * * Keith McGuigan * 10/3/2001 */ -static struct hostent* pack_hostent(char** buf, struct hostent* orig) +static struct hostent* pack_hostent(char** buf, int *size, struct hostent* orig) { char* bufptr; struct hostent* copy; @@ -427,7 +475,7 @@ } copy->h_addr_list[i] = NULL; - *buf=(char *)realloc(*buf, (int)bufptr-(int)(*buf)); + *size=(int)bufptr-(int)copy; return copy; } #endif @@ -453,53 +501,36 @@ return (addr); } +/* The original code to this function was once stolen from the Dancer source + code, written by Bjorn Reese, it has since been patched and modified + considerably. */ + #ifndef INADDR_NONE #define INADDR_NONE (in_addr_t) ~0 #endif -static void hostcache_fixoffset(struct hostent *h, int offset) -{ - int i=0; - h->h_name=(char *)((int)h->h_name+offset); - h->h_aliases=(char **)((int)h->h_aliases+offset); - while(h->h_aliases[i]) { - h->h_aliases[i]=(char *)((int)h->h_aliases[i]+offset); - i++; - } - h->h_addr_list=(char **)((int)h->h_addr_list+offset); - i=0; - while(h->h_addr_list[i]) { - h->h_addr_list[i]=(char *)((int)h->h_addr_list[i]+offset); - i++; - } -} - -/* The original code to this function was once stolen from the Dancer source - code, written by Bjorn Reese, it has since been patched and modified - considerably. */ Curl_addrinfo *Curl_getaddrinfo(struct SessionHandle *data, char *hostname, int port, - char **bufp) + char **bufp, int *size) { struct hostent *h = NULL; in_addr_t in; int ret; /* this variable is unused on several platforms but used on some */ - #define CURL_NAMELOOKUP_SIZE 9000 + char buf[CURL_NAMELOOKUP_SIZE]; + /* Allocate enough memory to hold the full name information structs and * everything. OSF1 is known to require at least 8872 bytes. The buffer * required for storing all possible aliases and IP numbers is according to * Stevens' Unix Network Programming 2nd editor, p. 304: 8192 bytes! */ port=0; /* unused in IPv4 code */ ret = 0; /* to prevent the compiler warning */ + memset(buf, 0, CURL_NAMELOOKUP_SIZE); + *size=CURL_NAMELOOKUP_SIZE; if ( (in=inet_addr(hostname)) != INADDR_NONE ) { struct in_addr *addrentry; - int *buf = (int *)malloc(128); - if(!buf) - return NULL; /* major failure */ - *bufp = (char *)buf; h = (struct hostent*)buf; h->h_addr_list = (char**)(buf + sizeof(*h)); @@ -508,24 +539,21 @@ h->h_addr_list[0] = (char*)addrentry; h->h_addr_list[1] = NULL; h->h_addrtype = AF_INET; + h->h_aliases=NULL; h->h_length = sizeof(*addrentry); h->h_name = *(h->h_addr_list) + h->h_length; /* bad one h->h_name = (char*)(h->h_addr_list + h->h_length); */ MakeIP(ntohl(in),h->h_name, 128 - (long)(h->h_name) + (long)buf); + *size=128; } #if defined(HAVE_GETHOSTBYNAME_R) else { int h_errnop; int res=ERANGE; int step_size=200; - int *buf = (int *)malloc(CURL_NAMELOOKUP_SIZE); - if(!buf) - return NULL; /* major failure */ - *bufp=(char *)buf; /* Workaround for gethostbyname_r bug in qnx nto. It is also _required_ for some of these functions. */ - memset(buf, 0, CURL_NAMELOOKUP_SIZE); #ifdef HAVE_GETHOSTBYNAME_R_5 /* Solaris, IRIX and more */ while(!h) { @@ -551,12 +579,7 @@ #endif if(h) { - int offset; - h=(struct hostent *)realloc(buf, step_size); - offset=(int)h-(int)buf; - hostcache_fixoffset(h, offset); - buf=(int *)h; - *bufp=(char *)buf; + *size=step_size; } else #endif @@ -575,12 +598,7 @@ infof(data, "gethostbyname_r() uses %d bytes\n", step_size); #endif if(!res) { - int offset; - h=(struct hostent *)realloc(buf, step_size); - offset=(int)h-(int)buf; - hostcache_fixoffset(h, offset); - buf=(int *)h; - *bufp=(char *)buf; + *size=step_size; } else #endif @@ -608,26 +626,35 @@ { infof(data, "gethostbyname_r(2) failed for %s\n", hostname); h = NULL; /* set return code to NULL */ - free(buf); - *bufp=NULL; } #else else { if ((h = gethostbyname(hostname)) == NULL ) { infof(data, "gethostbyname(2) failed for %s\n", hostname); - *bufp=NULL; } else { - char *buf=(char *)malloc(CURL_NAMELOOKUP_SIZE); /* we make a copy of the hostent right now, right here, as the static one we got a pointer to might get removed when we don't want/expect that */ - h = pack_hostent(&buf, h); - *bufp=(char *)buf; + h = pack_hostent(buf, size, h); } #endif } + if(h) + { + int offset; + h=(struct hostent *)malloc(*size); + *bufp=(char *)h; + memcpy(h, buf, *size); + offset=(int)(h)-(int)buf; + hostcache_fixoffset(h, offset); + } + else + { + *bufp=NULL; + *size=0; + } return (h); } diff -urN --exclude=CVS curl-7.9.7/lib/hostip.h /home/sylam/work/EmLinux_cvs/curl/lib/hostip.h --- curl-7.9.7/lib/hostip.h Fri Apr 26 03:21:54 2002 +++ /home/sylam/work/EmLinux_cvs/curl/lib/hostip.h Thu May 2 17:43:27 2002 @@ -20,7 +20,7 @@ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * - * $Id: hostip.h,v 1.16 2002/04/25 19:00:59 bagder Exp $ + * $Id: hostip.h,v 1.2 2002/04/29 06:55:18 sylam Exp $ *****************************************************************************/ #include "hash.h" @@ -43,7 +43,7 @@ Curl_addrinfo *Curl_getaddrinfo(struct SessionHandle *data, char *hostname, int port, - char **bufp); + char **bufp, int *size); /* free name info */ void Curl_freeaddrinfo(void *freethis); diff -urN --exclude=CVS curl-7.9.7/lib/url.c /home/sylam/work/EmLinux_cvs/curl/lib/url.c --- curl-7.9.7/lib/url.c Tue May 7 17:58:14 2002 +++ /home/sylam/work/EmLinux_cvs/curl/lib/url.c Tue May 21 12:00:25 2002 @@ -1353,7 +1331,7 @@ struct connectdata *conn_temp; char endbracket; int urllen; - Curl_addrinfo *hostaddr; + Curl_addrinfo *hostaddr=NULL; #ifdef HAVE_ALARM unsigned int prev_alarm; #endif @@ -2222,7 +2200,6 @@ /* resolve proxy */ hostaddr = Curl_resolv(data, conn->proxyhost, conn->port); - if(!hostaddr) { failf(data, "Couldn't resolve proxy '%s'", conn->proxyhost); result = CURLE_COULDNT_RESOLVE_PROXY; @@ -2270,7 +2247,10 @@ } #endif if(result) + { + if(hostaddr) free(hostaddr); return result; + } /************************************************************* * Proxy authentication @@ -2311,7 +2291,10 @@ Curl_pgrsTime(data, TIMER_CONNECT); /* connect done, good or bad */ if(CURLE_OK != result) + { + if(hostaddr) free(hostaddr); return result; + } if(data->set.verbose) verboseconnect(conn, hostaddr); @@ -2327,7 +2310,10 @@ /* Call the protocol-specific connect function */ result = conn->curl_connect(conn); if(result != CURLE_OK) + { + if(hostaddr) free(hostaddr); return result; /* pass back errors */ + } } } else { @@ -2351,6 +2337,7 @@ } #endif + if(hostaddr) free(hostaddr); return CURLE_OK; }