Annotation of embedaddon/miniupnpc/portlistingparse.c, revision 1.1.1.1
1.1 misho 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 */
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: pdata->curelt = PortMappingEltNone;
75: }
76:
77: /* Data handler */
78: static void
79: data(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: */
128: void
129: ParsePortListing(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:
147: void
148: FreePortListing(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:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>