File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / miniupnpd / miniupnpc / src / miniwget.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Sep 27 11:25:11 2023 UTC (18 months, 1 week ago) by misho
Branches: miniupnpd, MAIN
CVS tags: v2_3_3p0, HEAD
Version 2.3.3p0

    1: /* $Id: miniwget.c,v 1.1.1.1 2023/09/27 11:25:11 misho Exp $ */
    2: /* Project : miniupnp
    3:  * Website : http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/
    4:  * Author : Thomas Bernard
    5:  * Copyright (c) 2005-2020 Thomas Bernard
    6:  * This software is subject to the conditions detailed in the
    7:  * LICENCE file provided in this distribution. */
    8: 
    9: #include <stdio.h>
   10: #include <stdlib.h>
   11: #include <string.h>
   12: #include <ctype.h>
   13: #ifdef _WIN32
   14: #include <winsock2.h>
   15: #include <ws2tcpip.h>
   16: #include <io.h>
   17: #define MAXHOSTNAMELEN 64
   18: #include "win32_snprintf.h"
   19: #define socklen_t int
   20: #ifndef strncasecmp
   21: #if defined(_MSC_VER) && (_MSC_VER >= 1400)
   22: #define strncasecmp _memicmp
   23: #else /* defined(_MSC_VER) && (_MSC_VER >= 1400) */
   24: #define strncasecmp memicmp
   25: #endif /* defined(_MSC_VER) && (_MSC_VER >= 1400) */
   26: #endif /* #ifndef strncasecmp */
   27: #else /* #ifdef _WIN32 */
   28: #include <unistd.h>
   29: #include <sys/param.h>
   30: #if defined(__amigaos__) && !defined(__amigaos4__)
   31: #define socklen_t int
   32: #else /* #if defined(__amigaos__) && !defined(__amigaos4__) */
   33: #include <sys/select.h>
   34: #endif /* #else defined(__amigaos__) && !defined(__amigaos4__) */
   35: #include <sys/socket.h>
   36: #include <netinet/in.h>
   37: #include <arpa/inet.h>
   38: #include <net/if.h>
   39: #include <netdb.h>
   40: #define closesocket close
   41: #include <strings.h>
   42: #endif /* #else _WIN32 */
   43: #ifdef __GNU__
   44: #define MAXHOSTNAMELEN 64
   45: #endif /* __GNU__ */
   46: 
   47: #ifndef MIN
   48: #define MIN(x,y) (((x)<(y))?(x):(y))
   49: #endif /* MIN */
   50: 
   51: 
   52: #include "miniupnpcstrings.h"
   53: #include "miniwget.h"
   54: #include "connecthostport.h"
   55: #include "receivedata.h"
   56: 
   57: #ifndef MAXHOSTNAMELEN
   58: #define MAXHOSTNAMELEN 64
   59: #endif
   60: 
   61: /*
   62:  * Read a HTTP response from a socket.
   63:  * Process Content-Length and Transfer-encoding headers.
   64:  * return a pointer to the content buffer, which length is saved
   65:  * to the length parameter.
   66:  */
   67: void *
   68: getHTTPResponse(SOCKET s, int * size, int * status_code)
   69: {
   70: 	char buf[2048];
   71: 	int n;
   72: 	int endofheaders = 0;
   73: 	int chunked = 0;
   74: 	int content_length = -1;
   75: 	unsigned int chunksize = 0;
   76: 	unsigned int bytestocopy = 0;
   77: 	/* buffers : */
   78: 	char * header_buf;
   79: 	unsigned int header_buf_len = 2048;
   80: 	unsigned int header_buf_used = 0;
   81: 	char * content_buf;
   82: 	unsigned int content_buf_len = 2048;
   83: 	unsigned int content_buf_used = 0;
   84: 	char chunksize_buf[32];
   85: 	unsigned int chunksize_buf_index;
   86: #ifdef DEBUG
   87: 	char * reason_phrase = NULL;
   88: 	int reason_phrase_len = 0;
   89: #endif
   90: 
   91: 	if(status_code) *status_code = -1;
   92: 	header_buf = malloc(header_buf_len);
   93: 	if(header_buf == NULL)
   94: 	{
   95: #ifdef DEBUG
   96: 		fprintf(stderr, "%s: Memory allocation error\n", "getHTTPResponse");
   97: #endif /* DEBUG */
   98: 		*size = -1;
   99: 		return NULL;
  100: 	}
  101: 	content_buf = malloc(content_buf_len);
  102: 	if(content_buf == NULL)
  103: 	{
  104: 		free(header_buf);
  105: #ifdef DEBUG
  106: 		fprintf(stderr, "%s: Memory allocation error\n", "getHTTPResponse");
  107: #endif /* DEBUG */
  108: 		*size = -1;
  109: 		return NULL;
  110: 	}
  111: 	chunksize_buf[0] = '\0';
  112: 	chunksize_buf_index = 0;
  113: 
  114: 	while((n = receivedata(s, buf, sizeof(buf), 5000, NULL)) > 0)
  115: 	{
  116: 		if(endofheaders == 0)
  117: 		{
  118: 			int i;
  119: 			int linestart=0;
  120: 			int colon=0;
  121: 			int valuestart=0;
  122: 			if(header_buf_used + n > header_buf_len) {
  123: 				char * tmp = realloc(header_buf, header_buf_used + n);
  124: 				if(tmp == NULL) {
  125: 					/* memory allocation error */
  126: 					free(header_buf);
  127: 					free(content_buf);
  128: 					*size = -1;
  129: 					return NULL;
  130: 				}
  131: 				header_buf = tmp;
  132: 				header_buf_len = header_buf_used + n;
  133: 			}
  134: 			memcpy(header_buf + header_buf_used, buf, n);
  135: 			header_buf_used += n;
  136: 			/* search for CR LF CR LF (end of headers)
  137: 			 * recognize also LF LF */
  138: 			i = 0;
  139: 			while(i < ((int)header_buf_used-1) && (endofheaders == 0)) {
  140: 				if(header_buf[i] == '\r') {
  141: 					i++;
  142: 					if(header_buf[i] == '\n') {
  143: 						i++;
  144: 						if(i < (int)header_buf_used && header_buf[i] == '\r') {
  145: 							i++;
  146: 							if(i < (int)header_buf_used && header_buf[i] == '\n') {
  147: 								endofheaders = i+1;
  148: 							}
  149: 						}
  150: 					}
  151: 				} else if(header_buf[i] == '\n') {
  152: 					i++;
  153: 					if(header_buf[i] == '\n') {
  154: 						endofheaders = i+1;
  155: 					}
  156: 				}
  157: 				i++;
  158: 			}
  159: 			if(endofheaders == 0)
  160: 				continue;
  161: 			/* parse header lines */
  162: 			for(i = 0; i < endofheaders - 1; i++) {
  163: 				if(linestart > 0 && colon <= linestart && header_buf[i]==':')
  164: 				{
  165: 					colon = i;
  166: 					while(i < (endofheaders-1)
  167: 					      && (header_buf[i+1] == ' ' || header_buf[i+1] == '\t'))
  168: 						i++;
  169: 					valuestart = i + 1;
  170: 				}
  171: 				/* detecting end of line */
  172: 				else if(header_buf[i]=='\r' || header_buf[i]=='\n')
  173: 				{
  174: 					if(linestart == 0 && status_code)
  175: 					{
  176: 						/* Status line
  177: 						 * HTTP-Version SP Status-Code SP Reason-Phrase CRLF */
  178: 						int sp;
  179: 						for(sp = 0; sp < i - 1; sp++)
  180: 							if(header_buf[sp] == ' ')
  181: 							{
  182: 								if(*status_code < 0)
  183: 								{
  184: 									if (header_buf[sp+1] >= '1' && header_buf[sp+1] <= '9')
  185: 										*status_code = atoi(header_buf + sp + 1);
  186: 								}
  187: 								else
  188: 								{
  189: #ifdef DEBUG
  190: 									reason_phrase = header_buf + sp + 1;
  191: 									reason_phrase_len = i - sp - 1;
  192: #endif
  193: 									break;
  194: 								}
  195: 							}
  196: #ifdef DEBUG
  197: 						printf("HTTP status code = %d, Reason phrase = %.*s\n",
  198: 						       *status_code, reason_phrase_len, reason_phrase);
  199: #endif
  200: 					}
  201: 					else if(colon > linestart && valuestart > colon)
  202: 					{
  203: #ifdef DEBUG
  204: 						printf("header='%.*s', value='%.*s'\n",
  205: 						       colon-linestart, header_buf+linestart,
  206: 						       i-valuestart, header_buf+valuestart);
  207: #endif
  208: 						if(0==strncasecmp(header_buf+linestart, "content-length", colon-linestart))
  209: 						{
  210: 							content_length = atoi(header_buf+valuestart);
  211: #ifdef DEBUG
  212: 							printf("Content-Length: %d\n", content_length);
  213: #endif
  214: 						}
  215: 						else if(0==strncasecmp(header_buf+linestart, "transfer-encoding", colon-linestart)
  216: 						   && 0==strncasecmp(header_buf+valuestart, "chunked", 7))
  217: 						{
  218: #ifdef DEBUG
  219: 							printf("chunked transfer-encoding!\n");
  220: #endif
  221: 							chunked = 1;
  222: 						}
  223: 					}
  224: 					while((i < (int)header_buf_used) && (header_buf[i]=='\r' || header_buf[i] == '\n'))
  225: 						i++;
  226: 					linestart = i;
  227: 					colon = linestart;
  228: 					valuestart = 0;
  229: 				}
  230: 			}
  231: 			/* copy the remaining of the received data back to buf */
  232: 			n = header_buf_used - endofheaders;
  233: 			memcpy(buf, header_buf + endofheaders, n);
  234: 			/* if(headers) */
  235: 		}
  236: 		/* if we get there, endofheaders != 0.
  237: 		 * In the other case, there was a continue above */
  238: 		/* content */
  239: 		if(chunked)
  240: 		{
  241: 			int i = 0;
  242: 			while(i < n)
  243: 			{
  244: 				if(chunksize == 0)
  245: 				{
  246: 					/* reading chunk size */
  247: 					if(chunksize_buf_index == 0) {
  248: 						/* skipping any leading CR LF */
  249: 						if(buf[i] == '\r') i++;
  250: 						if(i<n && buf[i] == '\n') i++;
  251: 					}
  252: 					while(i<n && isxdigit(buf[i])
  253: 					     && chunksize_buf_index < (sizeof(chunksize_buf)-1))
  254: 					{
  255: 						chunksize_buf[chunksize_buf_index++] = buf[i];
  256: 						chunksize_buf[chunksize_buf_index] = '\0';
  257: 						i++;
  258: 					}
  259: 					while(i<n && buf[i] != '\r' && buf[i] != '\n')
  260: 						i++; /* discarding chunk-extension */
  261: 					if(i<n && buf[i] == '\r') i++;
  262: 					if(i<n && buf[i] == '\n') {
  263: 						unsigned int j;
  264: 						for(j = 0; j < chunksize_buf_index; j++) {
  265: 						if(chunksize_buf[j] >= '0'
  266: 						   && chunksize_buf[j] <= '9')
  267: 							chunksize = (chunksize << 4) + (chunksize_buf[j] - '0');
  268: 						else
  269: 							chunksize = (chunksize << 4) + ((chunksize_buf[j] | 32) - 'a' + 10);
  270: 						}
  271: 						chunksize_buf[0] = '\0';
  272: 						chunksize_buf_index = 0;
  273: 						i++;
  274: 					} else {
  275: 						/* not finished to get chunksize */
  276: 						continue;
  277: 					}
  278: #ifdef DEBUG
  279: 					printf("chunksize = %u (%x)\n", chunksize, chunksize);
  280: #endif
  281: 					if(chunksize == 0)
  282: 					{
  283: #ifdef DEBUG
  284: 						printf("end of HTTP content - %d %d\n", i, n);
  285: 						/*printf("'%.*s'\n", n-i, buf+i);*/
  286: #endif
  287: 						goto end_of_stream;
  288: 					}
  289: 				}
  290: 				/* it is guaranteed that (n >= i) */
  291: 				bytestocopy = (chunksize < (unsigned int)(n - i))?chunksize:(unsigned int)(n - i);
  292: 				if((content_buf_used + bytestocopy) > content_buf_len)
  293: 				{
  294: 					char * tmp;
  295: 					if((content_length >= 0) && ((unsigned int)content_length >= (content_buf_used + bytestocopy))) {
  296: 						content_buf_len = content_length;
  297: 					} else {
  298: 						content_buf_len = content_buf_used + bytestocopy;
  299: 					}
  300: 					tmp = realloc(content_buf, content_buf_len);
  301: 					if(tmp == NULL) {
  302: 						/* memory allocation error */
  303: 						free(content_buf);
  304: 						free(header_buf);
  305: 						*size = -1;
  306: 						return NULL;
  307: 					}
  308: 					content_buf = tmp;
  309: 				}
  310: 				memcpy(content_buf + content_buf_used, buf + i, bytestocopy);
  311: 				content_buf_used += bytestocopy;
  312: 				i += bytestocopy;
  313: 				chunksize -= bytestocopy;
  314: 			}
  315: 		}
  316: 		else
  317: 		{
  318: 			/* not chunked */
  319: 			if(content_length > 0
  320: 			   && (content_buf_used + n) > (unsigned int)content_length) {
  321: 				/* skipping additional bytes */
  322: 				n = content_length - content_buf_used;
  323: 			}
  324: 			if(content_buf_used + n > content_buf_len)
  325: 			{
  326: 				char * tmp;
  327: 				if(content_length >= 0
  328: 				   && (unsigned int)content_length >= (content_buf_used + n)) {
  329: 					content_buf_len = content_length;
  330: 				} else {
  331: 					content_buf_len = content_buf_used + n;
  332: 				}
  333: 				tmp = realloc(content_buf, content_buf_len);
  334: 				if(tmp == NULL) {
  335: 					/* memory allocation error */
  336: 					free(content_buf);
  337: 					free(header_buf);
  338: 					*size = -1;
  339: 					return NULL;
  340: 				}
  341: 				content_buf = tmp;
  342: 			}
  343: 			memcpy(content_buf + content_buf_used, buf, n);
  344: 			content_buf_used += n;
  345: 		}
  346: 		/* use the Content-Length header value if available */
  347: 		if(content_length > 0 && content_buf_used >= (unsigned int)content_length)
  348: 		{
  349: #ifdef DEBUG
  350: 			printf("End of HTTP content\n");
  351: #endif
  352: 			break;
  353: 		}
  354: 	}
  355: end_of_stream:
  356: 	free(header_buf);
  357: 	*size = content_buf_used;
  358: 	if(content_buf_used == 0)
  359: 	{
  360: 		free(content_buf);
  361: 		content_buf = NULL;
  362: 	}
  363: 	return content_buf;
  364: }
  365: 
  366: /* miniwget3() :
  367:  * do all the work.
  368:  * Return NULL if something failed. */
  369: static void *
  370: miniwget3(const char * host,
  371:           unsigned short port, const char * path,
  372:           int * size, char * addr_str, int addr_str_len,
  373:           const char * httpversion, unsigned int scope_id,
  374:           int * status_code)
  375: {
  376: 	char buf[2048];
  377: 	SOCKET s;
  378: 	int n;
  379: 	int len;
  380: 	int sent;
  381: 	void * content;
  382: 
  383: 	*size = 0;
  384: 	s = connecthostport(host, port, scope_id);
  385: 	if(ISINVALID(s))
  386: 		return NULL;
  387: 
  388: 	/* get address for caller ! */
  389: 	if(addr_str)
  390: 	{
  391: 		struct sockaddr_storage saddr;
  392: 		socklen_t saddrlen;
  393: 
  394: 		saddrlen = sizeof(saddr);
  395: 		if(getsockname(s, (struct sockaddr *)&saddr, &saddrlen) < 0)
  396: 		{
  397: 			perror("getsockname");
  398: 		}
  399: 		else
  400: 		{
  401: #if defined(__amigaos__) && !defined(__amigaos4__)
  402: 	/* using INT WINAPI WSAAddressToStringA(LPSOCKADDR, DWORD, LPWSAPROTOCOL_INFOA, LPSTR, LPDWORD);
  403:      * But his function make a string with the port :  nn.nn.nn.nn:port */
  404: /*		if(WSAAddressToStringA((SOCKADDR *)&saddr, sizeof(saddr),
  405:                             NULL, addr_str, (DWORD *)&addr_str_len))
  406: 		{
  407: 		    printf("WSAAddressToStringA() failed : %d\n", WSAGetLastError());
  408: 		}*/
  409: 			/* the following code is only compatible with ip v4 addresses */
  410: 			strncpy(addr_str, inet_ntoa(((struct sockaddr_in *)&saddr)->sin_addr), addr_str_len);
  411: #else
  412: #if 0
  413: 			if(saddr.sa_family == AF_INET6) {
  414: 				inet_ntop(AF_INET6,
  415: 				          &(((struct sockaddr_in6 *)&saddr)->sin6_addr),
  416: 				          addr_str, addr_str_len);
  417: 			} else {
  418: 				inet_ntop(AF_INET,
  419: 				          &(((struct sockaddr_in *)&saddr)->sin_addr),
  420: 				          addr_str, addr_str_len);
  421: 			}
  422: #endif
  423: 			/* getnameinfo return ip v6 address with the scope identifier
  424: 			 * such as : 2a01:e35:8b2b:7330::%4281128194 */
  425: 			n = getnameinfo((const struct sockaddr *)&saddr, saddrlen,
  426: 			                addr_str, addr_str_len,
  427: 			                NULL, 0,
  428: 			                NI_NUMERICHOST | NI_NUMERICSERV);
  429: 			if(n != 0) {
  430: #ifdef _WIN32
  431: 				fprintf(stderr, "getnameinfo() failed : %d\n", n);
  432: #else
  433: 				fprintf(stderr, "getnameinfo() failed : %s\n", gai_strerror(n));
  434: #endif
  435: 			}
  436: #endif
  437: 		}
  438: #ifdef DEBUG
  439: 		printf("address miniwget : %s\n", addr_str);
  440: #endif
  441: 	}
  442: 
  443: 	len = snprintf(buf, sizeof(buf),
  444:                  "GET %s HTTP/%s\r\n"
  445: 			     "Host: %s:%d\r\n"
  446: 				 "Connection: Close\r\n"
  447: 				 "User-Agent: " OS_STRING ", " UPNP_VERSION_STRING ", MiniUPnPc/" MINIUPNPC_VERSION_STRING "\r\n"
  448: 
  449: 				 "\r\n",
  450: 			   path, httpversion, host, port);
  451: 	if ((unsigned int)len >= sizeof(buf))
  452: 	{
  453: 		closesocket(s);
  454: 		return NULL;
  455: 	}
  456: 	sent = 0;
  457: 	/* sending the HTTP request */
  458: 	while(sent < len)
  459: 	{
  460: 		n = send(s, buf+sent, len-sent, 0);
  461: 		if(n < 0)
  462: 		{
  463: 			perror("send");
  464: 			closesocket(s);
  465: 			return NULL;
  466: 		}
  467: 		else
  468: 		{
  469: 			sent += n;
  470: 		}
  471: 	}
  472: 	content = getHTTPResponse(s, size, status_code);
  473: 	closesocket(s);
  474: 	return content;
  475: }
  476: 
  477: /* miniwget2() :
  478:  * Call miniwget3(); retry with HTTP/1.1 if 1.0 fails. */
  479: static void *
  480: miniwget2(const char * host,
  481:           unsigned short port, const char * path,
  482:           int * size, char * addr_str, int addr_str_len,
  483:           unsigned int scope_id, int * status_code)
  484: {
  485: 	char * respbuffer;
  486: 
  487: #if 1
  488: 	respbuffer = miniwget3(host, port, path, size,
  489: 	                       addr_str, addr_str_len, "1.1",
  490: 	                       scope_id, status_code);
  491: #else
  492: 	respbuffer = miniwget3(host, port, path, size,
  493: 	                       addr_str, addr_str_len, "1.0",
  494: 	                       scope_id, status_code);
  495: 	if (*size == 0)
  496: 	{
  497: #ifdef DEBUG
  498: 		printf("Retrying with HTTP/1.1\n");
  499: #endif
  500: 		free(respbuffer);
  501: 		respbuffer = miniwget3(host, port, path, size,
  502: 		                       addr_str, addr_str_len, "1.1",
  503: 		                       scope_id, status_code);
  504: 	}
  505: #endif
  506: 	return respbuffer;
  507: }
  508: 
  509: 
  510: 
  511: 
  512: /* parseURL()
  513:  * arguments :
  514:  *   url :		source string not modified
  515:  *   hostname :	hostname destination string (size of MAXHOSTNAMELEN+1)
  516:  *   port :		port (destination)
  517:  *   path :		pointer to the path part of the URL
  518:  *
  519:  * Return values :
  520:  *    0 - Failure
  521:  *    1 - Success         */
  522: int
  523: parseURL(const char * url,
  524:          char * hostname, unsigned short * port,
  525:          char * * path, unsigned int * scope_id)
  526: {
  527: 	char * p1, *p2, *p3;
  528: 	if(!url)
  529: 		return 0;
  530: 	p1 = strstr(url, "://");
  531: 	if(!p1)
  532: 		return 0;
  533: 	p1 += 3;
  534: 	if(  (url[0]!='h') || (url[1]!='t')
  535: 	   ||(url[2]!='t') || (url[3]!='p'))
  536: 		return 0;
  537: 	memset(hostname, 0, MAXHOSTNAMELEN + 1);
  538: 	if(*p1 == '[')
  539: 	{
  540: 		/* IP v6 : http://[2a00:1450:8002::6a]/path/abc */
  541: 		char * scope;
  542: 		scope = strchr(p1, '%');
  543: 		p2 = strchr(p1, ']');
  544: 		if(p2 && scope && scope < p2 && scope_id) {
  545: 			/* parse scope */
  546: #ifdef IF_NAMESIZE
  547: 			char tmp[IF_NAMESIZE];
  548: 			int l;
  549: 			scope++;
  550: 			/* "%25" is just '%' in URL encoding */
  551: 			if(scope[0] == '2' && scope[1] == '5')
  552: 				scope += 2;	/* skip "25" */
  553: 			l = p2 - scope;
  554: 			if(l >= IF_NAMESIZE)
  555: 				l = IF_NAMESIZE - 1;
  556: 			memcpy(tmp, scope, l);
  557: 			tmp[l] = '\0';
  558: 			*scope_id = if_nametoindex(tmp);
  559: 			if(*scope_id == 0) {
  560: 				*scope_id = (unsigned int)strtoul(tmp, NULL, 10);
  561: 			}
  562: #else
  563: 			/* under windows, scope is numerical */
  564: 			char tmp[8];
  565: 			size_t l;
  566: 			scope++;
  567: 			/* "%25" is just '%' in URL encoding */
  568: 			if(scope[0] == '2' && scope[1] == '5')
  569: 				scope += 2;	/* skip "25" */
  570: 			l = p2 - scope;
  571: 			if(l >= sizeof(tmp))
  572: 				l = sizeof(tmp) - 1;
  573: 			memcpy(tmp, scope, l);
  574: 			tmp[l] = '\0';
  575: 			*scope_id = (unsigned int)strtoul(tmp, NULL, 10);
  576: #endif
  577: 		}
  578: 		p3 = strchr(p1, '/');
  579: 		if(p2 && p3)
  580: 		{
  581: 			p2++;
  582: 			strncpy(hostname, p1, MIN(MAXHOSTNAMELEN, (int)(p2-p1)));
  583: 			if(*p2 == ':')
  584: 			{
  585: 				*port = 0;
  586: 				p2++;
  587: 				while( (*p2 >= '0') && (*p2 <= '9'))
  588: 				{
  589: 					*port *= 10;
  590: 					*port += (unsigned short)(*p2 - '0');
  591: 					p2++;
  592: 				}
  593: 			}
  594: 			else
  595: 			{
  596: 				*port = 80;
  597: 			}
  598: 			*path = p3;
  599: 			return 1;
  600: 		}
  601: 	}
  602: 	p2 = strchr(p1, ':');
  603: 	p3 = strchr(p1, '/');
  604: 	if(!p3)
  605: 		return 0;
  606: 	if(!p2 || (p2>p3))
  607: 	{
  608: 		strncpy(hostname, p1, MIN(MAXHOSTNAMELEN, (int)(p3-p1)));
  609: 		*port = 80;
  610: 	}
  611: 	else
  612: 	{
  613: 		strncpy(hostname, p1, MIN(MAXHOSTNAMELEN, (int)(p2-p1)));
  614: 		*port = 0;
  615: 		p2++;
  616: 		while( (*p2 >= '0') && (*p2 <= '9'))
  617: 		{
  618: 			*port *= 10;
  619: 			*port += (unsigned short)(*p2 - '0');
  620: 			p2++;
  621: 		}
  622: 	}
  623: 	*path = p3;
  624: 	return 1;
  625: }
  626: 
  627: void *
  628: miniwget(const char * url, int * size,
  629:          unsigned int scope_id, int * status_code)
  630: {
  631: 	unsigned short port;
  632: 	char * path;
  633: 	/* protocol://host:port/chemin */
  634: 	char hostname[MAXHOSTNAMELEN+1];
  635: 	*size = 0;
  636: 	if(!parseURL(url, hostname, &port, &path, &scope_id))
  637: 		return NULL;
  638: #ifdef DEBUG
  639: 	printf("parsed url : hostname='%s' port=%hu path='%s' scope_id=%u\n",
  640: 	       hostname, port, path, scope_id);
  641: #endif
  642: 	return miniwget2(hostname, port, path, size, 0, 0, scope_id, status_code);
  643: }
  644: 
  645: void *
  646: miniwget_getaddr(const char * url, int * size,
  647:                  char * addr, int addrlen, unsigned int scope_id,
  648:                  int * status_code)
  649: {
  650: 	unsigned short port;
  651: 	char * path;
  652: 	/* protocol://host:port/path */
  653: 	char hostname[MAXHOSTNAMELEN+1];
  654: 	*size = 0;
  655: 	if(addr)
  656: 		addr[0] = '\0';
  657: 	if(!parseURL(url, hostname, &port, &path, &scope_id))
  658: 		return NULL;
  659: #ifdef DEBUG
  660: 	printf("parsed url : hostname='%s' port=%hu path='%s' scope_id=%u\n",
  661: 	       hostname, port, path, scope_id);
  662: #endif
  663: 	return miniwget2(hostname, port, path, size, addr, addrlen, scope_id, status_code);
  664: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>