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

http://github.com/tomahawk-player/tomahawk · C · 132 lines · 112 code · 5 blank · 15 comment · 13 complexity · 0fa650dd23703dea2fcb2c1920dcb3ae MD5 · raw file

  1. /* $Id: minissdpc.c,v 1.14 2010/11/25 09:57:25 nanard Exp $ */
  2. /* Project : miniupnp
  3. * Author : Thomas BERNARD
  4. * copyright (c) 2005-2009 Thomas Bernard
  5. * This software is subjet to the conditions detailed in the
  6. * provided LICENCE file. */
  7. /*#include <syslog.h>*/
  8. #include <stdio.h>
  9. #include <string.h>
  10. #include <stdlib.h>
  11. #include <unistd.h>
  12. #include <sys/types.h>
  13. #if defined(WIN32) || defined(__amigaos__) || defined(__amigaos4__)
  14. #ifdef WIN32
  15. #include <winsock2.h>
  16. #include <ws2tcpip.h>
  17. #include <io.h>
  18. #include <winsock.h>
  19. #include <stdint.h>
  20. #endif
  21. #if defined(__amigaos__) || defined(__amigaos4__)
  22. #include <sys/socket.h>
  23. #endif
  24. #if defined(__amigaos__)
  25. #define uint16_t unsigned short
  26. #endif
  27. /* Hack */
  28. #define UNIX_PATH_LEN 108
  29. struct sockaddr_un {
  30. uint16_t sun_family;
  31. char sun_path[UNIX_PATH_LEN];
  32. };
  33. #else
  34. #include <sys/socket.h>
  35. #include <sys/un.h>
  36. #endif
  37. #include "minissdpc.h"
  38. #include "miniupnpc.h"
  39. #include "codelength.h"
  40. struct UPNPDev *
  41. getDevicesFromMiniSSDPD(const char * devtype, const char * socketpath)
  42. {
  43. struct UPNPDev * tmp;
  44. struct UPNPDev * devlist = NULL;
  45. unsigned char buffer[2048];
  46. ssize_t n;
  47. unsigned char * p;
  48. unsigned char * url;
  49. unsigned int i;
  50. unsigned int urlsize, stsize, usnsize, l;
  51. int s;
  52. struct sockaddr_un addr;
  53. s = socket(AF_UNIX, SOCK_STREAM, 0);
  54. if(s < 0)
  55. {
  56. /*syslog(LOG_ERR, "socket(unix): %m");*/
  57. perror("socket(unix)");
  58. return NULL;
  59. }
  60. addr.sun_family = AF_UNIX;
  61. strncpy(addr.sun_path, socketpath, sizeof(addr.sun_path));
  62. /* TODO : check if we need to handle the EINTR */
  63. if(connect(s, (struct sockaddr *)&addr, sizeof(struct sockaddr_un)) < 0)
  64. {
  65. /*syslog(LOG_WARNING, "connect(\"%s\"): %m", socketpath);*/
  66. close(s);
  67. return NULL;
  68. }
  69. stsize = strlen(devtype);
  70. buffer[0] = 1; /* request type 1 : request devices/services by type */
  71. p = buffer + 1;
  72. l = stsize; CODELENGTH(l, p);
  73. if(p + stsize > buffer + sizeof(buffer))
  74. {
  75. /* devtype is too long ! */
  76. close(s);
  77. return NULL;
  78. }
  79. memcpy(p, devtype, stsize);
  80. p += stsize;
  81. if(write(s, buffer, p - buffer) < 0)
  82. {
  83. /*syslog(LOG_ERR, "write(): %m");*/
  84. perror("minissdpc.c: write()");
  85. close(s);
  86. return NULL;
  87. }
  88. n = read(s, buffer, sizeof(buffer));
  89. if(n<=0)
  90. {
  91. perror("minissdpc.c: read()");
  92. close(s);
  93. return NULL;
  94. }
  95. p = buffer + 1;
  96. for(i = 0; i < buffer[0]; i++)
  97. {
  98. if(p+2>=buffer+sizeof(buffer))
  99. break;
  100. DECODELENGTH(urlsize, p);
  101. if(p+urlsize+2>=buffer+sizeof(buffer))
  102. break;
  103. url = p;
  104. p += urlsize;
  105. DECODELENGTH(stsize, p);
  106. if(p+stsize+2>=buffer+sizeof(buffer))
  107. break;
  108. tmp = (struct UPNPDev *)malloc(sizeof(struct UPNPDev)+urlsize+stsize);
  109. tmp->pNext = devlist;
  110. tmp->descURL = tmp->buffer;
  111. tmp->st = tmp->buffer + 1 + urlsize;
  112. memcpy(tmp->buffer, url, urlsize);
  113. tmp->buffer[urlsize] = '\0';
  114. memcpy(tmp->buffer + urlsize + 1, p, stsize);
  115. p += stsize;
  116. tmp->buffer[urlsize+1+stsize] = '\0';
  117. devlist = tmp;
  118. /* added for compatibility with recent versions of MiniSSDPd
  119. * >= 2007/12/19 */
  120. DECODELENGTH(usnsize, p);
  121. p += usnsize;
  122. if(p>buffer + sizeof(buffer))
  123. break;
  124. }
  125. close(s);
  126. return devlist;
  127. }