--- embedaddon/miniupnpc/miniwget.c 2012/02/21 23:16:22 1.1.1.1 +++ embedaddon/miniupnpc/miniwget.c 2013/07/22 00:36:10 1.1.1.2 @@ -1,15 +1,16 @@ -/* $Id: miniwget.c,v 1.1.1.1 2012/02/21 23:16:22 misho Exp $ */ +/* $Id: miniwget.c,v 1.1.1.2 2013/07/22 00:36:10 misho Exp $ */ /* Project : miniupnp + * Website : http://miniupnp.free.fr/ * Author : Thomas Bernard - * Copyright (c) 2005-2011 Thomas Bernard + * Copyright (c) 2005-2012 Thomas Bernard * This software is subject to the conditions detailed in the * LICENCE file provided in this distribution. */ - + #include #include #include #include -#ifdef WIN32 +#ifdef _WIN32 #include #include #include @@ -24,7 +25,7 @@ #define strncasecmp memicmp #endif /* defined(_MSC_VER) && (_MSC_VER >= 1400) */ #endif /* #ifndef strncasecmp */ -#else /* #ifdef WIN32 */ +#else /* #ifdef _WIN32 */ #include #include #if defined(__amigaos__) && !defined(__amigaos4__) @@ -33,13 +34,15 @@ #include #endif /* #else defined(__amigaos__) && !defined(__amigaos4__) */ #include +#include #include +#include #include #define closesocket close /* defining MINIUPNPC_IGNORE_EINTR enable the ignore of interruptions * during the connect() call */ #define MINIUPNPC_IGNORE_EINTR -#endif /* #else WIN32 */ +#endif /* #else _WIN32 */ #if defined(__sun) || defined(sun) #define MIN(x,y) (((x)<(y))?(x):(y)) #endif @@ -67,20 +70,20 @@ getHTTPResponse(int s, int * size) unsigned int bytestocopy = 0; /* buffers : */ char * header_buf; - int header_buf_len = 2048; - int header_buf_used = 0; + unsigned int header_buf_len = 2048; + unsigned int header_buf_used = 0; char * content_buf; - int content_buf_len = 2048; - int content_buf_used = 0; + unsigned int content_buf_len = 2048; + unsigned int content_buf_used = 0; char chunksize_buf[32]; - int chunksize_buf_index; + unsigned int chunksize_buf_index; header_buf = malloc(header_buf_len); content_buf = malloc(content_buf_len); chunksize_buf[0] = '\0'; chunksize_buf_index = 0; - while((n = receivedata(s, buf, 2048, 5000)) > 0) + while((n = receivedata(s, buf, 2048, 5000, NULL)) > 0) { if(endofheaders == 0) { @@ -97,14 +100,14 @@ getHTTPResponse(int s, int * size) /* search for CR LF CR LF (end of headers) * recognize also LF LF */ i = 0; - while(i < (header_buf_used-1) && (endofheaders == 0)) { + while(i < ((int)header_buf_used-1) && (endofheaders == 0)) { if(header_buf[i] == '\r') { i++; if(header_buf[i] == '\n') { i++; - if(i < header_buf_used && header_buf[i] == '\r') { + if(i < (int)header_buf_used && header_buf[i] == '\r') { i++; - if(i < header_buf_used && header_buf[i] == '\n') { + if(i < (int)header_buf_used && header_buf[i] == '\n') { endofheaders = i+1; } } @@ -160,7 +163,7 @@ getHTTPResponse(int s, int * size) linestart = i; colon = linestart; valuestart = 0; - } + } } /* copy the remaining of the received data back to buf */ n = header_buf_used - endofheaders; @@ -194,7 +197,7 @@ getHTTPResponse(int s, int * size) i++; /* discarding chunk-extension */ if(i= '0' && chunksize_buf[j] <= '9') @@ -221,15 +224,15 @@ getHTTPResponse(int s, int * size) goto end_of_stream; } } - bytestocopy = ((int)chunksize < n - i)?chunksize:(n - i); - if((int)(content_buf_used + bytestocopy) > content_buf_len) + bytestocopy = ((int)chunksize < (n - i))?chunksize:(unsigned int)(n - i); + if((content_buf_used + bytestocopy) > content_buf_len) { - if(content_length >= content_buf_used + (int)bytestocopy) { + if(content_length >= (int)(content_buf_used + bytestocopy)) { content_buf_len = content_length; } else { - content_buf_len = content_buf_used + (int)bytestocopy; + content_buf_len = content_buf_used + bytestocopy; } - content_buf = (char *)realloc((void *)content_buf, + content_buf = (char *)realloc((void *)content_buf, content_buf_len); } memcpy(content_buf + content_buf_used, buf + i, bytestocopy); @@ -242,18 +245,18 @@ getHTTPResponse(int s, int * size) { /* not chunked */ if(content_length > 0 - && (content_buf_used + n) > content_length) { + && (int)(content_buf_used + n) > content_length) { /* skipping additional bytes */ n = content_length - content_buf_used; } if(content_buf_used + n > content_buf_len) { - if(content_length >= content_buf_used + n) { + if(content_length >= (int)(content_buf_used + n)) { content_buf_len = content_length; } else { content_buf_len = content_buf_used + n; } - content_buf = (char *)realloc((void *)content_buf, + content_buf = (char *)realloc((void *)content_buf, content_buf_len); } memcpy(content_buf + content_buf_used, buf, n); @@ -261,7 +264,7 @@ getHTTPResponse(int s, int * size) } } /* use the Content-Length header value if available */ - if(content_length > 0 && content_buf_used >= content_length) + if(content_length > 0 && (int)content_buf_used >= content_length) { #ifdef DEBUG printf("End of HTTP content\n"); @@ -284,10 +287,10 @@ end_of_stream: * do all the work. * Return NULL if something failed. */ static void * -miniwget3(const char * url, const char * host, +miniwget3(const char * host, unsigned short port, const char * path, int * size, char * addr_str, int addr_str_len, - const char * httpversion) + const char * httpversion, unsigned int scope_id) { char buf[2048]; int s; @@ -297,7 +300,7 @@ miniwget3(const char * url, const char * host, void * content; *size = 0; - s = connecthostport(host, port); + s = connecthostport(host, port, scope_id); if(s < 0) return NULL; @@ -343,7 +346,7 @@ miniwget3(const char * url, const char * host, NULL, 0, NI_NUMERICHOST | NI_NUMERICSERV); if(n != 0) { -#ifdef WIN32 +#ifdef _WIN32 fprintf(stderr, "getnameinfo() failed : %d\n", n); #else fprintf(stderr, "getnameinfo() failed : %s\n", gai_strerror(n)); @@ -388,24 +391,29 @@ miniwget3(const char * url, const char * host, /* miniwget2() : * Call miniwget3(); retry with HTTP/1.1 if 1.0 fails. */ static void * -miniwget2(const char * url, const char * host, +miniwget2(const char * host, unsigned short port, const char * path, - int * size, char * addr_str, int addr_str_len) + int * size, char * addr_str, int addr_str_len, + unsigned int scope_id) { char * respbuffer; - respbuffer = miniwget3(url, host, port, path, size, addr_str, addr_str_len, "1.1"); -/* - respbuffer = miniwget3(url, host, port, path, size, addr_str, addr_str_len, "1.0"); +#if 1 + respbuffer = miniwget3(host, port, path, size, + addr_str, addr_str_len, "1.1", scope_id); +#else + respbuffer = miniwget3(host, port, path, size, + addr_str, addr_str_len, "1.0", scope_id); if (*size == 0) { #ifdef DEBUG printf("Retrying with HTTP/1.1\n"); #endif free(respbuffer); - respbuffer = miniwget3(url, host, port, path, size, addr_str, addr_str_len, "1.1"); + respbuffer = miniwget3(host, port, path, size, + addr_str, addr_str_len, "1.1", scope_id); } -*/ +#endif return respbuffer; } @@ -417,12 +425,15 @@ miniwget2(const char * url, const char * host, * url : source string not modified * hostname : hostname destination string (size of MAXHOSTNAMELEN+1) * port : port (destination) - * path : pointer to the path part of the URL + * path : pointer to the path part of the URL * * Return values : * 0 - Failure * 1 - Success */ -int parseURL(const char * url, char * hostname, unsigned short * port, char * * path) +int +parseURL(const char * url, + char * hostname, unsigned short * port, + char * * path, unsigned int * scope_id) { char * p1, *p2, *p3; if(!url) @@ -438,7 +449,43 @@ int parseURL(const char * url, char * hostname, unsign if(*p1 == '[') { /* IP v6 : http://[2a00:1450:8002::6a]/path/abc */ + char * scope; + scope = strchr(p1, '%'); p2 = strchr(p1, ']'); + if(p2 && scope && scope < p2 && scope_id) { + /* parse scope */ +#ifdef IF_NAMESIZE + char tmp[IF_NAMESIZE]; + int l; + scope++; + /* "%25" is just '%' in URL encoding */ + if(scope[0] == '2' && scope[1] == '5') + scope += 2; /* skip "25" */ + l = p2 - scope; + if(l >= IF_NAMESIZE) + l = IF_NAMESIZE - 1; + memcpy(tmp, scope, l); + tmp[l] = '\0'; + *scope_id = if_nametoindex(tmp); + if(*scope_id == 0) { + *scope_id = (unsigned int)strtoul(tmp, NULL, 10); + } +#else + /* under windows, scope is numerical */ + char tmp[8]; + int l; + scope++; + /* "%25" is just '%' in URL encoding */ + if(scope[0] == '2' && scope[1] == '5') + scope += 2; /* skip "25" */ + l = p2 - scope; + if(l >= sizeof(tmp)) + l = sizeof(tmp) - 1; + memcpy(tmp, scope, l); + tmp[l] = '\0'; + *scope_id = (unsigned int)strtoul(tmp, NULL, 10); +#endif + } p3 = strchr(p1, '/'); if(p2 && p3) { @@ -488,35 +535,40 @@ int parseURL(const char * url, char * hostname, unsign return 1; } -void * miniwget(const char * url, int * size) +void * +miniwget(const char * url, int * size, unsigned int scope_id) { unsigned short port; char * path; /* protocol://host:port/chemin */ char hostname[MAXHOSTNAMELEN+1]; *size = 0; - if(!parseURL(url, hostname, &port, &path)) + if(!parseURL(url, hostname, &port, &path, &scope_id)) return NULL; #ifdef DEBUG - printf("parsed url : hostname='%s' port=%hu path='%s'\n", hostname, port, path); + printf("parsed url : hostname='%s' port=%hu path='%s' scope_id=%u\n", + hostname, port, path, scope_id); #endif - return miniwget2(url, hostname, port, path, size, 0, 0); + return miniwget2(hostname, port, path, size, 0, 0, scope_id); } -void * miniwget_getaddr(const char * url, int * size, char * addr, int addrlen) +void * +miniwget_getaddr(const char * url, int * size, + char * addr, int addrlen, unsigned int scope_id) { unsigned short port; char * path; - /* protocol://host:port/chemin */ + /* protocol://host:port/path */ char hostname[MAXHOSTNAMELEN+1]; *size = 0; if(addr) addr[0] = '\0'; - if(!parseURL(url, hostname, &port, &path)) + if(!parseURL(url, hostname, &port, &path, &scope_id)) return NULL; #ifdef DEBUG - printf("parsed url : hostname='%s' port=%hu path='%s'\n", hostname, port, path); + printf("parsed url : hostname='%s' port=%hu path='%s' scope_id=%u\n", + hostname, port, path, scope_id); #endif - return miniwget2(url, hostname, port, path, size, addr, addrlen); + return miniwget2(hostname, port, path, size, addr, addrlen, scope_id); }