153 lines
3.5 KiB
C
153 lines
3.5 KiB
C
/* $Id: upnpreplyparse.c,v 1.11 2011/02/07 16:17:06 nanard Exp $ */
|
|
/* MiniUPnP project
|
|
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
|
* (c) 2006-2011 Thomas Bernard
|
|
* This software is subject to the conditions detailed
|
|
* in the LICENCE file provided within the distribution */
|
|
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
|
|
#include "upnpreplyparse.h"
|
|
#include "minixml.h"
|
|
|
|
static void
|
|
NameValueParserStartElt(void * d, const char * name, int l)
|
|
{
|
|
struct NameValueParserData * data = (struct NameValueParserData *)d;
|
|
if(l>63)
|
|
l = 63;
|
|
memcpy(data->curelt, name, l);
|
|
data->curelt[l] = '\0';
|
|
}
|
|
|
|
static void
|
|
NameValueParserGetData(void * d, const char * datas, int l)
|
|
{
|
|
struct NameValueParserData * data = (struct NameValueParserData *)d;
|
|
struct NameValue * nv;
|
|
if(strcmp(data->curelt, "NewPortListing") == 0)
|
|
{
|
|
/* specific case for NewPortListing which is a XML Document */
|
|
data->portListing = malloc(l + 1);
|
|
if(!data->portListing)
|
|
{
|
|
/* malloc error */
|
|
return;
|
|
}
|
|
memcpy(data->portListing, datas, l);
|
|
data->portListing[l] = '\0';
|
|
data->portListingLength = l;
|
|
}
|
|
else
|
|
{
|
|
/* standard case. Limited to 63 chars strings */
|
|
nv = malloc(sizeof(struct NameValue));
|
|
if(l>63)
|
|
l = 63;
|
|
strncpy(nv->name, data->curelt, 64);
|
|
nv->name[63] = '\0';
|
|
memcpy(nv->value, datas, l);
|
|
nv->value[l] = '\0';
|
|
LIST_INSERT_HEAD( &(data->head), nv, entries);
|
|
}
|
|
}
|
|
|
|
void
|
|
ParseNameValue(const char * buffer, int bufsize,
|
|
struct NameValueParserData * data)
|
|
{
|
|
struct xmlparser parser;
|
|
LIST_INIT(&(data->head));
|
|
data->portListing = NULL;
|
|
data->portListingLength = 0;
|
|
/* init xmlparser object */
|
|
parser.xmlstart = buffer;
|
|
parser.xmlsize = bufsize;
|
|
parser.data = data;
|
|
parser.starteltfunc = NameValueParserStartElt;
|
|
parser.endeltfunc = 0;
|
|
parser.datafunc = NameValueParserGetData;
|
|
parser.attfunc = 0;
|
|
parsexml(&parser);
|
|
}
|
|
|
|
void
|
|
ClearNameValueList(struct NameValueParserData * pdata)
|
|
{
|
|
struct NameValue * nv;
|
|
if(pdata->portListing)
|
|
{
|
|
free(pdata->portListing);
|
|
pdata->portListing = NULL;
|
|
pdata->portListingLength = 0;
|
|
}
|
|
while((nv = pdata->head.lh_first) != NULL)
|
|
{
|
|
LIST_REMOVE(nv, entries);
|
|
free(nv);
|
|
}
|
|
}
|
|
|
|
char *
|
|
GetValueFromNameValueList(struct NameValueParserData * pdata,
|
|
const char * Name)
|
|
{
|
|
struct NameValue * nv;
|
|
char * p = NULL;
|
|
for(nv = pdata->head.lh_first;
|
|
(nv != NULL) && (p == NULL);
|
|
nv = nv->entries.le_next)
|
|
{
|
|
if(strcmp(nv->name, Name) == 0)
|
|
p = nv->value;
|
|
}
|
|
return p;
|
|
}
|
|
|
|
#if 0
|
|
/* useless now that minixml ignores namespaces by itself */
|
|
char *
|
|
GetValueFromNameValueListIgnoreNS(struct NameValueParserData * pdata,
|
|
const char * Name)
|
|
{
|
|
struct NameValue * nv;
|
|
char * p = NULL;
|
|
char * pname;
|
|
for(nv = pdata->head.lh_first;
|
|
(nv != NULL) && (p == NULL);
|
|
nv = nv->entries.le_next)
|
|
{
|
|
pname = strrchr(nv->name, ':');
|
|
if(pname)
|
|
pname++;
|
|
else
|
|
pname = nv->name;
|
|
if(strcmp(pname, Name)==0)
|
|
p = nv->value;
|
|
}
|
|
return p;
|
|
}
|
|
#endif
|
|
|
|
/* debug all-in-one function
|
|
* do parsing then display to stdout */
|
|
#ifdef DEBUG
|
|
void
|
|
DisplayNameValueList(char * buffer, int bufsize)
|
|
{
|
|
struct NameValueParserData pdata;
|
|
struct NameValue * nv;
|
|
ParseNameValue(buffer, bufsize, &pdata);
|
|
for(nv = pdata.head.lh_first;
|
|
nv != NULL;
|
|
nv = nv->entries.le_next)
|
|
{
|
|
printf("%s = %s\n", nv->name, nv->value);
|
|
}
|
|
ClearNameValueList(&pdata);
|
|
}
|
|
#endif
|
|
|