PageRenderTime 143ms CodeModel.GetById 70ms app.highlight 8ms RepoModel.GetById 62ms app.codeStats 0ms

/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
 29struct 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
 38#include "minissdpc.h"
 39#include "miniupnpc.h"
 40
 41#include "codelength.h"
 42
 43struct UPNPDev *
 44getDevicesFromMiniSSDPD(const char * devtype, const char * socketpath)
 45{
 46	struct UPNPDev * tmp;
 47	struct UPNPDev * devlist = NULL;
 48	unsigned char buffer[2048];
 49	ssize_t n;
 50	unsigned char * p;
 51	unsigned char * url;
 52	unsigned int i;
 53	unsigned int urlsize, stsize, usnsize, l;
 54	int s;
 55	struct sockaddr_un addr;
 56
 57	s = socket(AF_UNIX, SOCK_STREAM, 0);
 58	if(s < 0)
 59	{
 60		/*syslog(LOG_ERR, "socket(unix): %m");*/
 61		perror("socket(unix)");
 62		return NULL;
 63	}
 64	addr.sun_family = AF_UNIX;
 65	strncpy(addr.sun_path, socketpath, sizeof(addr.sun_path));
 66	/* TODO : check if we need to handle the EINTR */
 67	if(connect(s, (struct sockaddr *)&addr, sizeof(struct sockaddr_un)) < 0)
 68	{
 69		/*syslog(LOG_WARNING, "connect(\"%s\"): %m", socketpath);*/
 70		close(s);
 71		return NULL;
 72	}
 73	stsize = strlen(devtype);
 74	buffer[0] = 1; /* request type 1 : request devices/services by type */
 75	p = buffer + 1;
 76	l = stsize;	CODELENGTH(l, p);
 77	if(p + stsize > buffer + sizeof(buffer))
 78	{
 79		/* devtype is too long ! */
 80		close(s);
 81		return NULL;
 82	}
 83	memcpy(p, devtype, stsize);
 84	p += stsize;
 85	if(write(s, buffer, p - buffer) < 0)
 86	{
 87		/*syslog(LOG_ERR, "write(): %m");*/
 88		perror("minissdpc.c: write()");
 89		close(s);
 90		return NULL;
 91	}
 92	n = read(s, buffer, sizeof(buffer));
 93	if(n<=0)
 94	{
 95		perror("minissdpc.c: read()");
 96		close(s);
 97		return NULL;
 98	}
 99	p = buffer + 1;
100	for(i = 0; i < buffer[0]; i++)
101	{
102		if(p+2>=buffer+sizeof(buffer))
103			break;
104		DECODELENGTH(urlsize, p);
105		if(p+urlsize+2>=buffer+sizeof(buffer))
106			break;
107		url = p;
108		p += urlsize;
109		DECODELENGTH(stsize, p);
110		if(p+stsize+2>=buffer+sizeof(buffer))
111			break;
112		tmp = (struct UPNPDev *)malloc(sizeof(struct UPNPDev)+urlsize+stsize);
113		tmp->pNext = devlist;
114		tmp->descURL = tmp->buffer;
115		tmp->st = tmp->buffer + 1 + urlsize;
116		memcpy(tmp->buffer, url, urlsize);
117		tmp->buffer[urlsize] = '\0';
118		memcpy(tmp->buffer + urlsize + 1, p, stsize);
119		p += stsize;
120		tmp->buffer[urlsize+1+stsize] = '\0';
121		devlist = tmp;
122		/* added for compatibility with recent versions of MiniSSDPd 
123		 * >= 2007/12/19 */
124		DECODELENGTH(usnsize, p);
125		p += usnsize;
126		if(p>buffer + sizeof(buffer))
127			break;
128	}
129	close(s);
130	return devlist;
131}
132