upnpreplyparse.c 4.4 KB

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