transmission 2.83
[tomato.git] / release / src-rt-6.x.4708 / router / transmission / third-party / miniupnp / portlistingparse.c
blob19e3054ebb5c6f1c09eeb27c7a6221ec34748dbe
1 /* $Id: portlistingparse.c,v 1.6 2012/05/29 10:26:51 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"
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}
29 /* Helper function */
30 static UNSIGNED_INTEGER
31 atoui(const char * p, int l)
33 UNSIGNED_INTEGER r = 0;
34 while(l > 0 && *p)
36 if(*p >= '0' && *p <= '9')
37 r = r*10 + (*p - '0');
38 else
39 break;
40 p++;
41 l--;
43 return r;
46 /* Start element handler */
47 static void
48 startelt(void * d, const char * name, int l)
50 int i;
51 struct PortMappingParserData * pdata = (struct PortMappingParserData *)d;
52 pdata->curelt = PortMappingEltNone;
53 for(i = 0; elements[i].str; i++)
55 if(memcmp(name, elements[i].str, l) == 0)
57 pdata->curelt = elements[i].code;
58 break;
61 if(pdata->curelt == PortMappingEntry)
63 struct PortMapping * pm;
64 pm = calloc(1, sizeof(struct PortMapping));
65 LIST_INSERT_HEAD( &(pdata->head), pm, entries);
69 /* End element handler */
70 static void
71 endelt(void * d, const char * name, int l)
73 struct PortMappingParserData * pdata = (struct PortMappingParserData *)d;
74 (void)name;
75 (void)l;
76 pdata->curelt = PortMappingEltNone;
79 /* Data handler */
80 static void
81 data(void * d, const char * data, int l)
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)
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;
128 /* Parse the PortMappingList XML document for IGD version 2
130 void
131 ParsePortListing(const char * buffer, int bufsize,
132 struct PortMappingParserData * pdata)
134 struct xmlparser parser;
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);
149 void
150 FreePortListing(struct PortMappingParserData * pdata)
152 struct PortMapping * pm;
153 while((pm = pdata->head.lh_first) != NULL)
155 LIST_REMOVE(pm, entries);
156 free(pm);