File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / miniupnpc / portlistingparse.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Mon Jul 22 00:36:10 2013 UTC (10 years, 11 months ago) by misho
Branches: miniupnpc, elwix, MAIN
CVS tags: v1_8p0, v1_8, HEAD
1.8

    1: /* $Id: portlistingparse.c,v 1.1.1.2 2013/07/22 00:36:10 misho 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 */
   13: static 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 */
   30: static UNSIGNED_INTEGER
   31: atoui(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 */
   47: static void
   48: startelt(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 */
   70: static void
   71: endelt(void * d, const char * name, int l)
   72: {
   73: 	struct PortMappingParserData * pdata = (struct PortMappingParserData *)d;
   74: 	(void)name;
   75: 	(void)l;
   76: 	pdata->curelt = PortMappingEltNone;
   77: }
   78: 
   79: /* Data handler */
   80: static void
   81: data(void * d, const char * data, int l)
   82: {
   83: 	struct PortMapping * pm;
   84: 	struct PortMappingParserData * pdata = (struct PortMappingParserData *)d;
   85: 	pm = pdata->head.lh_first;
   86: 	if(!pm)
   87: 		return;
   88: 	if(l > 63)
   89: 		l = 63;
   90: 	switch(pdata->curelt)
   91: 	{
   92: 	case NewRemoteHost:
   93: 		memcpy(pm->remoteHost, data, l);
   94: 		pm->remoteHost[l] = '\0';
   95: 		break;
   96: 	case NewExternalPort:
   97: 		pm->externalPort = (unsigned short)atoui(data, l);
   98: 		break;
   99: 	case NewProtocol:
  100: 		if(l > 3)
  101: 			l = 3;
  102: 		memcpy(pm->protocol, data, l);
  103: 		pm->protocol[l] = '\0';
  104: 		break;
  105: 	case NewInternalPort:
  106: 		pm->internalPort = (unsigned short)atoui(data, l);
  107: 		break;
  108: 	case NewInternalClient:
  109: 		memcpy(pm->internalClient, data, l);
  110: 		pm->internalClient[l] = '\0';
  111: 		break;
  112: 	case NewEnabled:
  113: 		pm->enabled = (unsigned char)atoui(data, l);
  114: 		break;
  115: 	case NewDescription:
  116: 		memcpy(pm->description, data, l);
  117: 		pm->description[l] = '\0';
  118: 		break;
  119: 	case NewLeaseTime:
  120: 		pm->leaseTime = atoui(data, l);
  121: 		break;
  122: 	default:
  123: 		break;
  124: 	}
  125: }
  126: 
  127: 
  128: /* Parse the PortMappingList XML document for IGD version 2
  129:  */
  130: void
  131: ParsePortListing(const char * buffer, int bufsize,
  132:                  struct PortMappingParserData * pdata)
  133: {
  134: 	struct xmlparser parser;
  135: 
  136: 	memset(pdata, 0, sizeof(struct PortMappingParserData));
  137: 	LIST_INIT(&(pdata->head));
  138: 	/* init xmlparser */
  139: 	parser.xmlstart = buffer;
  140: 	parser.xmlsize = bufsize;
  141: 	parser.data = pdata;
  142: 	parser.starteltfunc = startelt;
  143: 	parser.endeltfunc = endelt;
  144: 	parser.datafunc = data;
  145: 	parser.attfunc = 0;
  146: 	parsexml(&parser);
  147: }
  148: 
  149: void
  150: FreePortListing(struct PortMappingParserData * pdata)
  151: {
  152: 	struct PortMapping * pm;
  153: 	while((pm = pdata->head.lh_first) != NULL)
  154: 	{
  155: 		LIST_REMOVE(pm, entries);
  156: 		free(pm);
  157: 	}
  158: }
  159: 

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