PageRenderTime 92ms CodeModel.GetById 40ms app.highlight 10ms RepoModel.GetById 40ms app.codeStats 0ms

/thirdparty/libportfwd/third-party/miniupnpc-1.6/portlistingparse.c

http://github.com/tomahawk-player/tomahawk
C | 157 lines | 133 code | 10 blank | 14 comment | 12 complexity | 19de9946b23e616d40e644803bff6e2b MD5 | raw file
  1/* $Id: portlistingparse.c,v 1.4 2011/03/18 11:02:17 nanard Exp $ */
  2/* MiniUPnP project
  3 * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
  4 * (c) 2011 Thomas Bernard 
  5 * This software is subject to the conditions detailed
  6 * in the LICENCE file provided within the distribution */
  7#include <string.h>
  8#include <stdlib.h>
  9#include "portlistingparse.h"
 10#include "minixml.h"
 11
 12/* list of the elements */
 13static const struct {
 14	const portMappingElt code;
 15	const char * const str;
 16} elements[] = {
 17	{ PortMappingEntry, "PortMappingEntry"},
 18	{ NewRemoteHost, "NewRemoteHost"},
 19	{ NewExternalPort, "NewExternalPort"},
 20	{ NewProtocol, "NewProtocol"},
 21	{ NewInternalPort, "NewInternalPort"},
 22	{ NewInternalClient, "NewInternalClient"},
 23	{ NewEnabled, "NewEnabled"},
 24	{ NewDescription, "NewDescription"},
 25	{ NewLeaseTime, "NewLeaseTime"},
 26	{ PortMappingEltNone, NULL}
 27};
 28
 29/* Helper function */
 30static UNSIGNED_INTEGER
 31atoui(const char * p, int l)
 32{
 33	UNSIGNED_INTEGER r = 0;
 34	while(l > 0 && *p)
 35	{
 36		if(*p >= '0' && *p <= '9')
 37			r = r*10 + (*p - '0');
 38		else
 39			break;
 40		p++;
 41		l--;
 42	}
 43	return r;
 44}
 45
 46/* Start element handler */
 47static void
 48startelt(void * d, const char * name, int l)
 49{
 50	int i;
 51	struct PortMappingParserData * pdata = (struct PortMappingParserData *)d;
 52	pdata->curelt = PortMappingEltNone;
 53	for(i = 0; elements[i].str; i++)
 54	{
 55		if(memcmp(name, elements[i].str, l) == 0)
 56		{
 57			pdata->curelt = elements[i].code;
 58			break;
 59		}
 60	}
 61	if(pdata->curelt == PortMappingEntry)
 62	{
 63		struct PortMapping * pm;
 64		pm = calloc(1, sizeof(struct PortMapping));
 65		LIST_INSERT_HEAD( &(pdata->head), pm, entries);
 66	}
 67}
 68
 69/* End element handler */
 70static void
 71endelt(void * d, const char * name, int l)
 72{
 73	struct PortMappingParserData * pdata = (struct PortMappingParserData *)d;
 74	pdata->curelt = PortMappingEltNone;
 75}
 76
 77/* Data handler */
 78static void
 79data(void * d, const char * data, int l)
 80{
 81	struct PortMapping * pm;
 82	struct PortMappingParserData * pdata = (struct PortMappingParserData *)d;
 83	pm = pdata->head.lh_first;
 84	if(!pm)
 85		return;
 86	if(l > 63)
 87		l = 63;
 88	switch(pdata->curelt)
 89	{
 90	case NewRemoteHost:
 91		memcpy(pm->remoteHost, data, l);
 92		pm->remoteHost[l] = '\0';
 93		break;
 94	case NewExternalPort:
 95		pm->externalPort = (unsigned short)atoui(data, l);
 96		break;
 97	case NewProtocol:
 98		if(l > 3)
 99			l = 3;
100		memcpy(pm->protocol, data, l);
101		pm->protocol[l] = '\0';
102		break;
103	case NewInternalPort:
104		pm->internalPort = (unsigned short)atoui(data, l);
105		break;
106	case NewInternalClient:
107		memcpy(pm->internalClient, data, l);
108		pm->internalClient[l] = '\0';
109		break;
110	case NewEnabled:
111		pm->enabled = (unsigned char)atoui(data, l);
112		break;
113	case NewDescription:
114		memcpy(pm->description, data, l);
115		pm->description[l] = '\0';
116		break;
117	case NewLeaseTime:
118		pm->leaseTime = atoui(data, l);
119		break;
120	default:
121		break;
122	}
123}
124
125
126/* Parse the PortMappingList XML document for IGD version 2
127 */
128void
129ParsePortListing(const char * buffer, int bufsize,
130                 struct PortMappingParserData * pdata)
131{
132	struct xmlparser parser;
133
134	memset(pdata, 0, sizeof(struct PortMappingParserData));
135	LIST_INIT(&(pdata->head));
136	/* init xmlparser */
137	parser.xmlstart = buffer;
138	parser.xmlsize = bufsize;
139	parser.data = pdata;
140	parser.starteltfunc = startelt;
141	parser.endeltfunc = endelt;
142	parser.datafunc = data;
143	parser.attfunc = 0;
144	parsexml(&parser);
145}
146
147void
148FreePortListing(struct PortMappingParserData * pdata)
149{
150	struct PortMapping * pm;
151	while((pm = pdata->head.lh_first) != NULL)
152	{
153		LIST_REMOVE(pm, entries);
154		free(pm);
155	}
156}
157