upnpreplyparse.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. #define _CRT_SECURE_NO_WARNINGS
  2. /* $Id: upnpreplyparse.c,v 1.19 2015/07/15 10:29:11 nanard Exp $ */
  3. /* MiniUPnP project
  4. * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
  5. * (c) 2006-2015 Thomas Bernard
  6. * This software is subject to the conditions detailed
  7. * in the LICENCE file provided within the distribution */
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include <stdio.h>
  11. #include "upnpreplyparse.h"
  12. #include "minixml.h"
  13. static void
  14. NameValueParserStartElt(void * d, const char * name, int l)
  15. {
  16. struct NameValueParserData * data = (struct NameValueParserData *)d;
  17. data->topelt = 1;
  18. if(l>63)
  19. l = 63;
  20. memcpy(data->curelt, name, l);
  21. data->curelt[l] = '\0';
  22. data->cdata = NULL;
  23. data->cdatalen = 0;
  24. }
  25. static void
  26. NameValueParserEndElt(void * d, const char * name, int l)
  27. {
  28. struct NameValueParserData * data = (struct NameValueParserData *)d;
  29. struct NameValue * nv;
  30. (void)name;
  31. (void)l;
  32. if(!data->topelt)
  33. return;
  34. if(strcmp(data->curelt, "NewPortListing") != 0)
  35. {
  36. int l;
  37. /* standard case. Limited to n chars strings */
  38. l = data->cdatalen;
  39. nv = malloc(sizeof(struct NameValue));
  40. if(nv == NULL)
  41. {
  42. /* malloc error */
  43. #ifdef DEBUG
  44. fprintf(stderr, "%s: error allocating memory",
  45. "NameValueParserEndElt");
  46. #endif /* DEBUG */
  47. return;
  48. }
  49. if(l>=(int)sizeof(nv->value))
  50. l = sizeof(nv->value) - 1;
  51. strncpy(nv->name, data->curelt, 64);
  52. nv->name[63] = '\0';
  53. if(data->cdata != NULL)
  54. {
  55. memcpy(nv->value, data->cdata, l);
  56. nv->value[l] = '\0';
  57. }
  58. else
  59. {
  60. nv->value[0] = '\0';
  61. }
  62. nv->l_next = data->l_head; /* insert in list */
  63. data->l_head = nv;
  64. }
  65. data->cdata = NULL;
  66. data->cdatalen = 0;
  67. data->topelt = 0;
  68. }
  69. static void
  70. NameValueParserGetData(void * d, const char * datas, int l)
  71. {
  72. struct NameValueParserData * data = (struct NameValueParserData *)d;
  73. if(strcmp(data->curelt, "NewPortListing") == 0)
  74. {
  75. /* specific case for NewPortListing which is a XML Document */
  76. data->portListing = malloc(l + 1);
  77. if(!data->portListing)
  78. {
  79. /* malloc error */
  80. #ifdef DEBUG
  81. fprintf(stderr, "%s: error allocating memory",
  82. "NameValueParserGetData");
  83. #endif /* DEBUG */
  84. return;
  85. }
  86. memcpy(data->portListing, datas, l);
  87. data->portListing[l] = '\0';
  88. data->portListingLength = l;
  89. }
  90. else
  91. {
  92. /* standard case. */
  93. data->cdata = datas;
  94. data->cdatalen = l;
  95. }
  96. }
  97. void
  98. ParseNameValue(const char * buffer, int bufsize,
  99. struct NameValueParserData * data)
  100. {
  101. struct xmlparser parser;
  102. data->l_head = NULL;
  103. data->portListing = NULL;
  104. data->portListingLength = 0;
  105. /* init xmlparser object */
  106. parser.xmlstart = buffer;
  107. parser.xmlsize = bufsize;
  108. parser.data = data;
  109. parser.starteltfunc = NameValueParserStartElt;
  110. parser.endeltfunc = NameValueParserEndElt;
  111. parser.datafunc = NameValueParserGetData;
  112. parser.attfunc = 0;
  113. parsexml(&parser);
  114. }
  115. void
  116. ClearNameValueList(struct NameValueParserData * pdata)
  117. {
  118. struct NameValue * nv;
  119. if(pdata->portListing)
  120. {
  121. free(pdata->portListing);
  122. pdata->portListing = NULL;
  123. pdata->portListingLength = 0;
  124. }
  125. while((nv = pdata->l_head) != NULL)
  126. {
  127. pdata->l_head = nv->l_next;
  128. free(nv);
  129. }
  130. }
  131. char *
  132. GetValueFromNameValueList(struct NameValueParserData * pdata,
  133. const char * Name)
  134. {
  135. struct NameValue * nv;
  136. char * p = NULL;
  137. for(nv = pdata->l_head;
  138. (nv != NULL) && (p == NULL);
  139. nv = nv->l_next)
  140. {
  141. if(strcmp(nv->name, Name) == 0)
  142. p = nv->value;
  143. }
  144. return p;
  145. }
  146. #if 0
  147. /* useless now that minixml ignores namespaces by itself */
  148. char *
  149. GetValueFromNameValueListIgnoreNS(struct NameValueParserData * pdata,
  150. const char * Name)
  151. {
  152. struct NameValue * nv;
  153. char * p = NULL;
  154. char * pname;
  155. for(nv = pdata->head.lh_first;
  156. (nv != NULL) && (p == NULL);
  157. nv = nv->entries.le_next)
  158. {
  159. pname = strrchr(nv->name, ':');
  160. if(pname)
  161. pname++;
  162. else
  163. pname = nv->name;
  164. if(strcmp(pname, Name)==0)
  165. p = nv->value;
  166. }
  167. return p;
  168. }
  169. #endif
  170. /* debug all-in-one function
  171. * do parsing then display to stdout */
  172. #ifdef DEBUG
  173. void
  174. DisplayNameValueList(char * buffer, int bufsize)
  175. {
  176. struct NameValueParserData pdata;
  177. struct NameValue * nv;
  178. ParseNameValue(buffer, bufsize, &pdata);
  179. for(nv = pdata.l_head;
  180. nv != NULL;
  181. nv = nv->l_next)
  182. {
  183. printf("%s = %s\n", nv->name, nv->value);
  184. }
  185. ClearNameValueList(&pdata);
  186. }
  187. #endif /* DEBUG */