/thirdparty/libportfwd/third-party/miniupnpc-1.6/portlistingparse.c

http://github.com/tomahawk-player/tomahawk · C · 157 lines · 133 code · 10 blank · 14 comment · 15 complexity · 19de9946b23e616d40e644803bff6e2b MD5 · raw file

  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. /* list of the elements */
  12. static const struct {
  13. const portMappingElt code;
  14. const char * const str;
  15. } elements[] = {
  16. { PortMappingEntry, "PortMappingEntry"},
  17. { NewRemoteHost, "NewRemoteHost"},
  18. { NewExternalPort, "NewExternalPort"},
  19. { NewProtocol, "NewProtocol"},
  20. { NewInternalPort, "NewInternalPort"},
  21. { NewInternalClient, "NewInternalClient"},
  22. { NewEnabled, "NewEnabled"},
  23. { NewDescription, "NewDescription"},
  24. { NewLeaseTime, "NewLeaseTime"},
  25. { PortMappingEltNone, NULL}
  26. };
  27. /* Helper function */
  28. static UNSIGNED_INTEGER
  29. atoui(const char * p, int l)
  30. {
  31. UNSIGNED_INTEGER r = 0;
  32. while(l > 0 && *p)
  33. {
  34. if(*p >= '0' && *p <= '9')
  35. r = r*10 + (*p - '0');
  36. else
  37. break;
  38. p++;
  39. l--;
  40. }
  41. return r;
  42. }
  43. /* Start element handler */
  44. static void
  45. startelt(void * d, const char * name, int l)
  46. {
  47. int i;
  48. struct PortMappingParserData * pdata = (struct PortMappingParserData *)d;
  49. pdata->curelt = PortMappingEltNone;
  50. for(i = 0; elements[i].str; i++)
  51. {
  52. if(memcmp(name, elements[i].str, l) == 0)
  53. {
  54. pdata->curelt = elements[i].code;
  55. break;
  56. }
  57. }
  58. if(pdata->curelt == PortMappingEntry)
  59. {
  60. struct PortMapping * pm;
  61. pm = calloc(1, sizeof(struct PortMapping));
  62. LIST_INSERT_HEAD( &(pdata->head), pm, entries);
  63. }
  64. }
  65. /* End element handler */
  66. static void
  67. endelt(void * d, const char * name, int l)
  68. {
  69. struct PortMappingParserData * pdata = (struct PortMappingParserData *)d;
  70. pdata->curelt = PortMappingEltNone;
  71. }
  72. /* Data handler */
  73. static void
  74. data(void * d, const char * data, int l)
  75. {
  76. struct PortMapping * pm;
  77. struct PortMappingParserData * pdata = (struct PortMappingParserData *)d;
  78. pm = pdata->head.lh_first;
  79. if(!pm)
  80. return;
  81. if(l > 63)
  82. l = 63;
  83. switch(pdata->curelt)
  84. {
  85. case NewRemoteHost:
  86. memcpy(pm->remoteHost, data, l);
  87. pm->remoteHost[l] = '\0';
  88. break;
  89. case NewExternalPort:
  90. pm->externalPort = (unsigned short)atoui(data, l);
  91. break;
  92. case NewProtocol:
  93. if(l > 3)
  94. l = 3;
  95. memcpy(pm->protocol, data, l);
  96. pm->protocol[l] = '\0';
  97. break;
  98. case NewInternalPort:
  99. pm->internalPort = (unsigned short)atoui(data, l);
  100. break;
  101. case NewInternalClient:
  102. memcpy(pm->internalClient, data, l);
  103. pm->internalClient[l] = '\0';
  104. break;
  105. case NewEnabled:
  106. pm->enabled = (unsigned char)atoui(data, l);
  107. break;
  108. case NewDescription:
  109. memcpy(pm->description, data, l);
  110. pm->description[l] = '\0';
  111. break;
  112. case NewLeaseTime:
  113. pm->leaseTime = atoui(data, l);
  114. break;
  115. default:
  116. break;
  117. }
  118. }
  119. /* Parse the PortMappingList XML document for IGD version 2
  120. */
  121. void
  122. ParsePortListing(const char * buffer, int bufsize,
  123. struct PortMappingParserData * pdata)
  124. {
  125. struct xmlparser parser;
  126. memset(pdata, 0, sizeof(struct PortMappingParserData));
  127. LIST_INIT(&(pdata->head));
  128. /* init xmlparser */
  129. parser.xmlstart = buffer;
  130. parser.xmlsize = bufsize;
  131. parser.data = pdata;
  132. parser.starteltfunc = startelt;
  133. parser.endeltfunc = endelt;
  134. parser.datafunc = data;
  135. parser.attfunc = 0;
  136. parsexml(&parser);
  137. }
  138. void
  139. FreePortListing(struct PortMappingParserData * pdata)
  140. {
  141. struct PortMapping * pm;
  142. while((pm = pdata->head.lh_first) != NULL)
  143. {
  144. LIST_REMOVE(pm, entries);
  145. free(pm);
  146. }
  147. }