use Thomas Bernard's miniupnp library instead of rolling our own.

This commit is contained in:
Charles Kerr
2007-11-06 16:02:50 +00:00
parent cfa809bc47
commit 9df263326d
43 changed files with 4256 additions and 3000 deletions

View File

@@ -10,5 +10,6 @@ transmission_cli_SOURCES = transmissioncli.c
transmission_cli_LDADD = \
$(top_builddir)/libtransmission/libtransmission.a \
$(top_builddir)/third-party/libevent/libevent.la \
$(top_builddir)/third-party/miniupnp/libminiupnp.a \
$(OPENSSL_LIBS) $(PTHREAD_LIBS) -lm

View File

@@ -207,6 +207,7 @@ AC_CONFIG_FILES([Makefile
daemon/Makefile
libtransmission/Makefile
third-party/Makefile
third-party/miniupnp/Makefile
macosx/Makefile
wx/Makefile
wx/images/Makefile

View File

@@ -28,6 +28,7 @@ bin_PROGRAMS = \
COMMON_LDADD = \
./libdaemon.a \
$(top_builddir)/libtransmission/libtransmission.a \
$(top_builddir)/third-party/miniupnp/libminiupnp.a \
$(top_builddir)/third-party/libevent/libevent.la \
$(OPENSSL_LIBS) $(PTHREAD_LIBS) -lm

View File

@@ -55,6 +55,7 @@ dist_man_MANS = transmission.1
transmission_LDADD = \
$(top_builddir)/libtransmission/libtransmission.a \
$(top_builddir)/third-party/libevent/libevent.la \
$(top_builddir)/third-party/miniupnp/libminiupnp.a \
$(GTK_LIBS) \
$(OPENSSL_LIBS) \
$(PTHREAD_LIBS) -lm

View File

@@ -1,4 +1,4 @@
AM_CPPFLAGS = -I. -I$(top_srcdir) -D__TRANSMISSION__ $(LIBEVENT_CPPFLAGS)
AM_CPPFLAGS = -I. -I$(top_srcdir) -I$(top_srcdir)/third-party/ -D__TRANSMISSION__ $(LIBEVENT_CPPFLAGS)
AM_CFLAGS = $(OPENSSL_CFLAGS) $(PTHREAD_CFLAGS)
noinst_LIBRARIES = libtransmission.a
@@ -11,7 +11,6 @@ libtransmission_a_SOURCES = \
fastresume.c \
fdlimit.c \
handshake.c \
http.c \
inout.c \
ipcparse.c \
list.c \
@@ -34,8 +33,7 @@ libtransmission_a_SOURCES = \
transmission.c \
trevent.c \
upnp.c \
utils.c \
xml.c
utils.c
noinst_HEADERS = \
bencode.h \
@@ -46,7 +44,6 @@ noinst_HEADERS = \
fastresume.h \
fdlimit.h \
handshake.h \
http.h \
inout.h \
internal.h \
ipcparse.h \
@@ -69,8 +66,7 @@ noinst_HEADERS = \
trcompat.h \
trevent.h \
upnp.h \
utils.h \
xml.h
utils.h
EXTRA_libtransmission_a_SOURCES = \
version.h

View File

@@ -1,907 +0,0 @@
/******************************************************************************
* $Id$
*
* Copyright (c) 2006-2007 Transmission authors and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*****************************************************************************/
#include <assert.h>
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include "evdns.h"
#ifdef __BEOS__
extern int vasprintf( char **, const char *, va_list );
#endif
#include "transmission.h"
#include "http.h"
#include "net.h"
#include "trcompat.h"
#include "utils.h"
#define HTTP_PORT 80 /* default http port 80 */
#define HTTP_TIMEOUT 60000 /* one minute http timeout */
#define HTTP_BUFSIZE 1500 /* 1.5K buffer size increment */
#define LF "\012"
#define CR "\015"
#define SP( cc ) ( ' ' == (cc) || '\t' == (cc) )
#define NL( cc ) ( '\015' == (cc) || '\012' == (cc) )
#define NUM( cc ) ( '0' <= (cc) && '9' >= (cc) )
#define ALEN( aa ) ( (int)(sizeof( (aa) ) / sizeof( (aa)[0] ) ) )
#define SKIP( off, len, done ) \
while( (off) < (len) && (done) ) { (off)++; };
static const char *
slice( const char * data, int * len, const char * delim );
static tr_tristate_t
sendrequest( tr_http_t * http );
static tr_tristate_t
receiveresponse( tr_http_t * http );
static int
checklength( tr_http_t * http );
static int
learnlength( tr_http_t * http );
#define EXPANDBUF( bs ) &(bs).buf, &(bs).used, &(bs).size
struct buf {
char * buf;
int size;
int used;
};
struct tr_http_s {
#define HTTP_STATE_CONSTRUCT 1
#define HTTP_STATE_RESOLVE 2
#define HTTP_STATE_CONNECT 3
#define HTTP_STATE_RECEIVE 4
#define HTTP_STATE_DONE 5
#define HTTP_STATE_ERROR 6
char state;
#define HTTP_LENGTH_UNKNOWN 1
#define HTTP_LENGTH_EOF 2
#define HTTP_LENGTH_FIXED 3
#define HTTP_LENGTH_CHUNKED 4
char lengthtype;
char * host;
int port;
int sock;
struct buf header;
struct buf body;
uint64_t date;
/*
eof: unused
fixed: lenptr is the start of the body, lenint is the body length
chunked: lenptr is start of chunk (after length), lenint is chunk size
*/
int chunkoff;
int chunklen;
};
int
tr_httpRequestType( const char * data, int len, char ** method, char ** uri )
{
const char * words[6];
int ii, ret;
const char * end;
/* find the end of the line */
for( end = data; data + len > end; end++ )
{
if( NL( *data) )
{
break;
}
}
/* find the first three "words" in the line */
for( ii = 0; ALEN( words ) > ii && data < end; ii++ )
{
/* find the next space or non-space */
while( data < end && ( ii % 2 ? !SP( *data ) : SP( *data ) ) )
{
data++;
}
/* save the beginning of the word */
words[ii] = data;
}
/* check for missing words */
if( ALEN( words) > ii )
{
return -1;
}
/* parse HTTP version */
ret = -1;
if( 8 <= words[5] - words[4] )
{
if( 0 == tr_strncasecmp( words[4], "HTTP/1.1", 8 ) )
{
ret = 11;
}
else if( 0 == tr_strncasecmp( words[4], "HTTP/1.0", 8 ) )
{
ret = 10;
}
}
/* copy the method */
if( 0 <= ret && NULL != method )
{
*method = tr_strndup( words[0], words[1] - words[0] );
if( NULL == *method )
{
ret = -1;
}
}
/* copy uri */
if( 0 <= ret && NULL != uri )
{
*uri = tr_strndup( words[2], words[3] - words[2] );
if( NULL == *uri )
{
free( *method );
ret = -1;
}
}
return ret;
}
int
tr_httpResponseCode( const char * data, int len )
{
char code[4];
int ret;
/* check for the minimum legal length */
if( 12 > len ||
/* check for valid http version */
0 != tr_strncasecmp( data, "HTTP/1.", 7 ) ||
( '1' != data[7] && '0' != data[7] ) ||
/* there should be at least one space after the version */
!SP( data[8] ) )
{
return -1;
}
/* skip any extra spaces */
data += 9;
len -= 9;
while( 0 < len && SP( *data ) )
{
data++;
len--;
}
/* check for a valid three-digit code */
if( 3 > len || !NUM( data[0] ) || !NUM( data[1] ) || !NUM( data[2] ) ||
( 3 < len && NUM( data[3] ) ) )
{
return -1;
}
/* parse and return the code */
memcpy( code, data, 3 );
code[3] = '\0';
ret = strtol( code, NULL, 10 );
if( 100 > ret )
{
ret = -1;
}
return ret;
}
char *
tr_httpParse( const char * data, int len, tr_http_header_t *headers )
{
const char * body, * begin;
int ii, jj, full;
/* find the end of the http headers */
body = slice( data, &len, CR LF CR LF );
if( NULL == body )
{
body = slice( data, &len, LF LF );
if( NULL == body )
{
body = slice( data, &len, CR CR );
if( NULL == body )
{
return NULL;
}
}
}
/* return if no headers were requested */
if( NULL == headers || NULL == headers[0].name )
{
return (char*) body;
}
/* NULL out all the header's data pointers */
for( ii = 0; NULL != headers[ii].name; ii++ )
{
headers[ii].data = NULL;
headers[ii].len = 0;
}
/* skip the http request or response line */
ii = 0;
SKIP( ii, len, !NL( data[ii] ) );
SKIP( ii, len, NL( data[ii] ) );
/* find the requested headers */
while(ii < len )
{
/* skip leading spaces and find the header name */
SKIP( ii, len, SP( data[ii] ) );
begin = data + ii;
SKIP( ii, len, ':' != data[ii] && !NL( data[ii] ) );
if( ':' == data[ii] )
{
full = 1;
/* try to match the found header with one of the requested */
for( jj = 0; NULL != headers[jj].name; jj++ )
{
if( NULL == headers[jj].data )
{
full = 0;
if( 0 == tr_strncasecmp( headers[jj].name, begin,
( data + ii ) - begin ) )
{
ii++;
/* skip leading whitespace and save the header value */
SKIP( ii, len, SP( data[ii] ) );
headers[jj].data = data + ii;
SKIP( ii, len, !NL( data[ii] ) );
headers[jj].len = ( data + ii ) - headers[jj].data;
break;
}
}
}
if( full )
{
break;
}
/* skip to the end of the header */
SKIP( ii, len, !NL( data[ii] ) );
}
/* skip past the newline */
SKIP( ii, len, NL( data[ii] ) );
}
return (char*)body;
}
static const char *
slice( const char * data, int * len, const char * delim )
{
const char *body;
int dlen;
dlen = strlen( delim );
body = tr_memmem( data, *len, delim, dlen );
if( NULL != body )
{
*len = body - data;
body += dlen;
}
return body;
}
int
tr_httpIsUrl( const char * url, int len )
{
if( 0 > len )
{
len = strlen( url );
}
/* check for protocol */
if( 7 > len || 0 != tr_strncasecmp( url, "http://", 7 ) )
{
return 0;
}
return 7;
}
int
tr_httpParseUrl( const char * url, int len,
char ** host, int * port, char ** path )
{
const char * pathstart, * hostend;
int ii, colon, portnum;
char str[6];
if( 0 > len )
{
len = strlen( url );
}
while( len && url && isspace(*url) )
{
--len;
++url;
}
ii = tr_httpIsUrl( url, len );
if( 0 >= ii )
{
return 1;
}
url += ii;
len -= ii;
/* find the hostname and port */
colon = -1;
for( ii = 0; len > ii && '/' != url[ii]; ii++ )
{
if( ':' == url[ii] )
{
colon = ii;
}
}
hostend = url + ( 0 > colon ? ii : colon );
pathstart = url + ii;
/* parse the port number */
portnum = HTTP_PORT;
if( 0 <= colon )
{
colon++;
memset( str, 0, sizeof( str ) );
memcpy( str, url + colon, MIN( (int) sizeof( str) - 1, ii - colon ) );
portnum = strtol( str, NULL, 10 );
if( 0 >= portnum || 0xffff <= portnum )
{
tr_err( "Invalid port (%i)", portnum );
return 1;
}
}
if( NULL != host )
{
*host = tr_strndup( url, hostend - url );
}
if( NULL != port )
{
*port = portnum;
}
if( NULL != path )
{
if( 0 < len - ( pathstart - url ) )
{
*path = tr_strndup( pathstart, len - ( pathstart - url ) );
}
else
{
*path = strdup( "/" );
}
}
return 0;
}
tr_http_t *
tr_httpClient( int method, const char * host, int port, const char * fmt, ... )
{
tr_http_t * http;
va_list ap1, ap2;
char * methodstr;
http = malloc( sizeof( *http ) );
if( NULL == http )
{
return NULL;
}
memset( http, 0, sizeof( *http ) );
http->state = HTTP_STATE_CONSTRUCT;
http->lengthtype = HTTP_LENGTH_UNKNOWN;
http->host = strdup( host );
http->port = port;
http->sock = -1;
if( NULL == http->host || NULL == fmt )
{
goto err;
}
switch( method )
{
case TR_HTTP_GET:
methodstr = "GET";
break;
case TR_HTTP_POST:
methodstr = "POST";
break;
case TR_HTTP_M_POST:
methodstr = "M-POST";
break;
default:
goto err;
}
if( tr_sprintf( EXPANDBUF( http->header ), "%s ", methodstr ) )
{
goto err;
}
va_start( ap1, fmt );
va_start( ap2, fmt );
if( tr_vsprintf( EXPANDBUF( http->header ), fmt, ap1, ap2 ) )
{
va_end( ap2 );
va_end( ap1 );
goto err;
}
va_end( ap2 );
va_end( ap1 );
if( tr_sprintf( EXPANDBUF( http->header ), " HTTP/1.1" CR LF
"Host: %s:%d" CR LF
"User-Agent: " TR_NAME "/" LONG_VERSION_STRING CR LF
"Connection: close" CR LF,
http->host, http->port ) )
{
goto err;
}
return http;
err:
tr_httpClose( http );
return NULL;
}
tr_http_t *
tr_httpClientUrl( int method, const char * fmt, ... )
{
char * url, * host, * path;
int port;
va_list ap;
tr_http_t * ret;
va_start( ap, fmt );
url = NULL;
vasprintf( &url, fmt, ap );
va_end( ap );
if( tr_httpParseUrl( url, -1, &host, &port, &path ) )
{
tr_err( "Invalid HTTP URL: %s", url );
free( url );
return NULL;
}
free( url );
ret = tr_httpClient( method, host, port, "%s", path );
free( host );
free( path );
return ret;
}
void
tr_httpAddHeader( tr_http_t * http, const char * name, const char * value )
{
if( HTTP_STATE_CONSTRUCT == http->state )
{
if( tr_sprintf( EXPANDBUF( http->header ),
"%s: %s" CR LF, name, value ) )
{
http->state = HTTP_STATE_ERROR;
}
}
else
{
assert( HTTP_STATE_ERROR == http->state );
}
}
void
tr_httpAddBody( tr_http_t * http , const char * fmt , ... )
{
va_list ap1, ap2;
if( HTTP_STATE_CONSTRUCT == http->state )
{
va_start( ap1, fmt );
va_start( ap2, fmt );
if( tr_vsprintf( EXPANDBUF( http->body ), fmt, ap1, ap2 ) )
{
http->state = HTTP_STATE_ERROR;
}
va_end( ap2 );
va_end( ap1 );
}
else
{
assert( HTTP_STATE_ERROR == http->state );
}
}
void
tr_httpGetHeaders( tr_http_t * http, const char ** buf, int * len )
{
*buf = http->header.buf;
*len = http->header.used;
}
void
tr_httpGetBody( tr_http_t * http, const char ** buf, int * len )
{
*buf = http->body.buf;
*len = http->body.used;
}
static void
resolve_cb( int result, char type, int count, int ttl, void *addresses, void *arg)
{
tr_http_t * http = (tr_http_t *) arg;
if( (result!=DNS_ERR_NONE) || (type!=DNS_IPv4_A) || (ttl<0) || (count<1) )
http->state = HTTP_STATE_ERROR;
else {
struct in_addr *in_addrs = addresses;
http->sock = tr_netOpenTCP( &in_addrs[0], htons(http->port), 1 );
http->state = HTTP_STATE_CONNECT;
}
}
tr_tristate_t
tr_httpPulse( tr_http_t * http, const char ** data, int * len )
{
struct in_addr addr;
switch( http->state )
{
case HTTP_STATE_CONSTRUCT:
if( tr_sprintf( EXPANDBUF( http->header ), "Content-length: %i"
CR LF CR LF, http->body.used ) )
{
goto err;
}
if( !tr_netResolve( http->host, &addr ) )
{
http->sock = tr_netOpenTCP( &addr, htons( http->port ), 1 );
http->state = HTTP_STATE_CONNECT;
break;
}
if( evdns_resolve_ipv4( http->host, 0, resolve_cb, http ) )
{
goto err;
}
http->state = HTTP_STATE_RESOLVE;
/* fallthrough */
case HTTP_STATE_RESOLVE:
return TR_NET_WAIT;
case HTTP_STATE_CONNECT:
switch( sendrequest( http ) )
{
case TR_NET_WAIT:
return TR_NET_WAIT;
case TR_NET_ERROR:
goto err;
case TR_NET_OK:
http->state = HTTP_STATE_RECEIVE;
}
/* fallthrough */
case HTTP_STATE_RECEIVE:
switch( receiveresponse( http ) )
{
case TR_NET_WAIT:
return TR_NET_WAIT;
case TR_NET_ERROR:
goto err;
case TR_NET_OK:
goto ok;
}
break;
case HTTP_STATE_DONE:
goto ok;
case HTTP_STATE_ERROR:
goto err;
}
return TR_NET_WAIT;
err:
http->state = HTTP_STATE_ERROR;
return TR_NET_ERROR;
ok:
http->state = HTTP_STATE_DONE;
if( NULL != data )
{
*data = http->header.buf;
}
if( NULL != len )
{
*len = http->header.used;
}
return TR_NET_OK;
}
static tr_tristate_t
sendrequest( tr_http_t * http )
{
struct buf * buf;
if( !http->date )
http->date = tr_date();
if( 0 > http->sock || tr_date() > http->date + HTTP_TIMEOUT )
{
return TR_NET_ERROR;
}
buf = ( 0 < http->header.used ? &http->header : &http->body );
while( 0 < buf->used )
{
const int ret = tr_netSend( http->sock, buf->buf, buf->used );
if( ret & TR_NET_CLOSE ) return TR_NET_ERROR;
if( ret & TR_NET_BLOCK ) return TR_NET_WAIT;
buf->used = 0;
buf = &http->body;
}
free( http->body.buf );
http->body.buf = NULL;
http->body.size = 0;
http->date = 0;
return TR_NET_OK;
}
static tr_tristate_t
receiveresponse( tr_http_t * http )
{
int ret, before;
void * newbuf;
if( 0 == http->date )
{
http->date = tr_date();
}
before = http->header.used;
for(;;)
{
if( http->header.size - http->header.used < HTTP_BUFSIZE )
{
newbuf = realloc( http->header.buf,
http->header.size + HTTP_BUFSIZE );
if( NULL == newbuf )
{
return TR_NET_ERROR;
}
http->header.buf = newbuf;
http->header.size += HTTP_BUFSIZE;
}
ret = tr_netRecv( http->sock,
(uint8_t *) ( http->header.buf + http->header.used ),
http->header.size - http->header.used );
if( ret & TR_NET_CLOSE )
{
checklength( http );
return TR_NET_OK;
}
else if( ret & TR_NET_BLOCK )
{
break;
}
else
{
http->header.used += ret;
}
}
if( before < http->header.used && checklength( http ) )
{
return TR_NET_OK;
}
if( tr_date() > HTTP_TIMEOUT + http->date )
{
return TR_NET_ERROR;
}
return TR_NET_WAIT;
}
static int
checklength( tr_http_t * http )
{
char * buf;
int num, ii, len, lastnum;
switch( http->lengthtype )
{
case HTTP_LENGTH_UNKNOWN:
if( learnlength( http ) )
{
return checklength( http );
}
break;
case HTTP_LENGTH_EOF:
break;
case HTTP_LENGTH_FIXED:
if( http->header.used >= http->chunkoff + http->chunklen )
{
http->header.used = http->chunkoff + http->chunklen;
return 1;
}
break;
case HTTP_LENGTH_CHUNKED:
buf = http->header.buf;
lastnum = -1;
while( http->header.used > http->chunkoff + http->chunklen )
{
num = http->chunkoff + http->chunklen;
if( lastnum == num )
{
/* ugh, some trackers send Transfer-encoding: chunked
and then don't encode the body */
http->lengthtype = HTTP_LENGTH_EOF;
return checklength( http );
}
lastnum = num;
while( http->header.used > num && NL( buf[num] ) )
{
num++;
}
ii = num;
while( http->header.used > ii && !NL( buf[ii] ) )
{
ii++;
}
if( http->header.used > ii )
{
/* strtol should stop at the newline */
len = strtol( buf + num, NULL, 16 );
if( 0 == len )
{
/* XXX should handle invalid length
differently than 0 length chunk */
http->header.used = http->chunkoff + http->chunklen;
return 1;
}
if( http->header.used > ii + 1 )
{
ii += ( 0 == memcmp( buf + ii, CR LF, 2 ) ? 2 : 1 );
if( http->header.used > ii )
{
memmove( buf + http->chunkoff + http->chunklen,
buf + ii, http->header.used - ii );
}
http->header.used -=
ii - ( http->chunkoff + http->chunklen );
http->chunkoff += http->chunklen;
http->chunklen = len;
}
}
}
break;
}
return 0;
}
static int
learnlength( tr_http_t * http )
{
tr_http_header_t hdr[] = {
{ "Content-Length", NULL, 0 },
/*
XXX this probably doesn't handle multiple encodings correctly
http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.41
*/
{ "Transfer-Encoding", NULL, 0 },
{ NULL, NULL, 0 }
};
const char * body;
char * duped;
body = tr_httpParse( http->header.buf, http->header.used, hdr );
if( NULL != body )
{
if( 0 < hdr[1].len &&
0 == tr_strncasecmp( "chunked", hdr[1].data, hdr[1].len ) )
{
http->lengthtype = HTTP_LENGTH_CHUNKED;
http->chunkoff = body - http->header.buf;
http->chunklen = 0;
}
else if( 0 < hdr[0].len )
{
http->lengthtype = HTTP_LENGTH_FIXED;
http->chunkoff = body - http->header.buf;
duped = tr_strndup( hdr[0].data, hdr[0].len );
http->chunklen = strtol( duped, NULL, 10 );
free( duped );
}
else
{
http->lengthtype = HTTP_LENGTH_EOF;
}
return 1;
}
return 0;
}
char *
tr_httpWhatsMyAddress( tr_http_t * http )
{
struct sockaddr_in sin;
socklen_t size;
char buf[INET_ADDRSTRLEN];
if( 0 > http->sock )
{
return NULL;
}
size = sizeof( sin );
if( 0 > getsockname( http->sock, (struct sockaddr *) &sin, &size ) )
{
return NULL;
}
tr_netNtop( &sin.sin_addr, buf, sizeof( buf ) );
return strdup( buf );
}
void
tr_httpClose( tr_http_t * http )
{
free( http->host );
tr_netClose( http->sock );
free( http->header.buf );
free( http->body.buf );
free( http );
}

View File

@@ -1,72 +0,0 @@
/******************************************************************************
* $Id$
*
* Copyright (c) 2006 Transmission authors and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*****************************************************************************/
#ifndef TR_HTTP_H
#define TR_HTTP_H 1
/*
Parse an HTTP request header to find the method, uri, and version.
The version will be 11, 10, or -1 on parse error. The method and/or
uri pointers may be NULL if the caller is not interested.
*/
int tr_httpRequestType( const char * data, int len,
char ** method, char ** uri );
/* Return the HTTP status code for the response, or -1 for parse error */
int tr_httpResponseCode( const char * data, int len );
#define TR_HTTP_STATUS_OK( st ) ( 200 <= (st) && 299 >= (st) )
#define TR_HTTP_STATUS_REDIRECT( st ) ( 300 <= (st) && 399 >= (st) )
#define TR_HTTP_STATUS_FAIL( st ) ( 400 <= (st) && 599 >= (st) )
#define TR_HTTP_STATUS_FAIL_CLIENT( st ) ( 400 <= (st) && 499 >= (st) )
#define TR_HTTP_STATUS_FAIL_SERVER( st ) ( 500 <= (st) && 599 >= (st) )
/*
Parse an HTTP request or response, locating specified headers and
the body. The length of the body will be len - ( body - data ).
*/
typedef struct { const char * name; const char * data; int len; }
tr_http_header_t;
char * tr_httpParse( const char * data, int len, tr_http_header_t *headers );
int tr_httpIsUrl( const char *, int );
int tr_httpParseUrl( const char *, int, char **, int *, char ** );
/* fetch a file via HTTP from a standard http:// url */
typedef struct tr_http_s tr_http_t;
#define TR_HTTP_GET 1
#define TR_HTTP_POST 2
#define TR_HTTP_M_POST 3
tr_http_t * tr_httpClient( int, const char *, int, const char *, ... );
tr_http_t * tr_httpClientUrl( int, const char *, ... );
/* only add headers or body before first pulse */
void tr_httpAddHeader( tr_http_t *, const char *, const char * );
void tr_httpAddBody( tr_http_t *, const char *, ... );
void tr_httpGetHeaders( tr_http_t *, const char **, int * );
void tr_httpGetBody( tr_http_t *, const char **, int * );
tr_tristate_t tr_httpPulse( tr_http_t *, const char **, int * );
char * tr_httpWhatsMyAddress( tr_http_t * );
void tr_httpClose( tr_http_t * );
#endif

View File

@@ -31,14 +31,39 @@
#include <sys/stat.h>
#include <unistd.h> /* unlink, stat */
#include <miniupnp/miniwget.h> /* parseURL */
#include "transmission.h"
#include "bencode.h"
#include "crypto.h" /* tr_sha1 */
#include "http.h" /* tr_httpParseUrl */
#include "metainfo.h"
#include "platform.h"
#include "utils.h"
static int
tr_httpParseUrl( const char * url_in, int len,
char ** setme_host, int * setme_port, char ** setme_path )
{
char * url = tr_strndup( url_in, len );
char * path;
char host[4096+1];
unsigned short port;
int success;
success = parseURL( url, host, &port, &path );
if( success ) {
*setme_host = tr_strdup( host );
*setme_port = port;
*setme_path = tr_strdup( path );
}
tr_free( url );
return !success;
}
/***********************************************************************
* Local prototypes
**********************************************************************/

View File

@@ -83,7 +83,7 @@ typedef struct tr_natpmp_req_s
int gotport;
} tr_natpmp_req_t;
struct tr_natpmp_s
struct tr_natpmp
{
#define PMP_STATE_IDLE 1
#define PMP_STATE_ADDING 2
@@ -114,7 +114,7 @@ typedef struct tr_natpmp_parse_s
tr_natpmp_parse_t;
static void
unmap( tr_natpmp_t * pmp );
unmap( tr_natpmp * pmp );
static int
checktime( tr_natpmp_uptime_t * uptime, uint32_t seen );
static void
@@ -126,20 +126,20 @@ killreq( tr_natpmp_req_t ** req );
static void
resetreq( tr_natpmp_req_t * req );
static tr_tristate_t
pulsereq( tr_natpmp_t * req );
pulsereq( tr_natpmp * req );
static int
sendreq( tr_natpmp_req_t * req );
static int
mcastsetup();
static void
mcastpulse( tr_natpmp_t * pmp );
mcastpulse( tr_natpmp * pmp );
static tr_tristate_t
parseresponse( uint8_t * buf, int len, int port, tr_natpmp_parse_t * parse );
tr_natpmp_t *
tr_natpmp *
tr_natpmpInit()
{
tr_natpmp_t * pmp;
tr_natpmp * pmp;
pmp = calloc( 1, sizeof( *pmp ) );
if( NULL == pmp )
@@ -170,7 +170,7 @@ tr_natpmpInit()
}
void
tr_natpmpStart( tr_natpmp_t * pmp )
tr_natpmpStart( tr_natpmp * pmp )
{
if( !pmp->active )
{
@@ -184,7 +184,7 @@ tr_natpmpStart( tr_natpmp_t * pmp )
}
void
tr_natpmpStop( tr_natpmp_t * pmp )
tr_natpmpStop( tr_natpmp * pmp )
{
if( pmp->active )
{
@@ -196,7 +196,7 @@ tr_natpmpStop( tr_natpmp_t * pmp )
}
int
tr_natpmpStatus( tr_natpmp_t * pmp )
tr_natpmpStatus( tr_natpmp * pmp )
{
int ret;
@@ -239,14 +239,14 @@ tr_natpmpStatus( tr_natpmp_t * pmp )
}
void
tr_natpmpForwardPort( tr_natpmp_t * pmp, int port )
tr_natpmpForwardPort( tr_natpmp * pmp, int port )
{
tr_inf( "nat-pmp set port %i", port );
pmp->newport = port;
}
void
tr_natpmpRemoveForwarding( tr_natpmp_t * pmp )
tr_natpmpRemoveForwarding( tr_natpmp * pmp )
{
tr_inf( "nat-pmp unset port" );
pmp->newport = -1;
@@ -254,7 +254,7 @@ tr_natpmpRemoveForwarding( tr_natpmp_t * pmp )
}
void
tr_natpmpClose( tr_natpmp_t * pmp )
tr_natpmpClose( tr_natpmp * pmp )
{
/* try to send at least one delete request if we have a port mapping */
tr_natpmpStop( pmp );
@@ -265,7 +265,7 @@ tr_natpmpClose( tr_natpmp_t * pmp )
}
void
tr_natpmpPulse( tr_natpmp_t * pmp, int * publicPort )
tr_natpmpPulse( tr_natpmp * pmp, int * publicPort )
{
if( 0 <= pmp->mcastfd )
{
@@ -443,7 +443,7 @@ tr_natpmpPulse( tr_natpmp_t * pmp, int * publicPort )
}
void
unmap( tr_natpmp_t * pmp )
unmap( tr_natpmp * pmp )
{
switch( pmp->state )
{
@@ -567,7 +567,7 @@ resetreq( tr_natpmp_req_t * req )
}
static tr_tristate_t
pulsereq( tr_natpmp_t * pmp )
pulsereq( tr_natpmp * pmp )
{
tr_natpmp_req_t * req = pmp->req;
struct sockaddr_in sin;
@@ -692,7 +692,7 @@ mcastsetup()
}
static void
mcastpulse( tr_natpmp_t * pmp )
mcastpulse( tr_natpmp * pmp )
{
struct sockaddr_in sin;
uint8_t buf[16];

View File

@@ -25,15 +25,15 @@
#ifndef TR_NATPMP_H
#define TR_NATPMP_H 1
typedef struct tr_natpmp_s tr_natpmp_t;
typedef struct tr_natpmp tr_natpmp;
tr_natpmp_t * tr_natpmpInit();
void tr_natpmpStart( tr_natpmp_t * );
void tr_natpmpStop( tr_natpmp_t * );
int tr_natpmpStatus( tr_natpmp_t * );
void tr_natpmpForwardPort( tr_natpmp_t *, int );
void tr_natpmpRemoveForwarding( tr_natpmp_t * );
void tr_natpmpPulse( tr_natpmp_t *, int * );
void tr_natpmpClose( tr_natpmp_t * );
tr_natpmp * tr_natpmpInit();
void tr_natpmpStart( tr_natpmp * );
void tr_natpmpStop( tr_natpmp * );
int tr_natpmpStatus( tr_natpmp * );
void tr_natpmpForwardPort( tr_natpmp *, int );
void tr_natpmpRemoveForwarding( tr_natpmp * );
void tr_natpmpPulse( tr_natpmp *, int * );
void tr_natpmpClose( tr_natpmp * );
#endif

View File

@@ -52,8 +52,8 @@ struct tr_shared
int bindSocket;
/* NAT-PMP/UPnP */
tr_natpmp_t * natpmp;
tr_upnp_t * upnp;
tr_natpmp * natpmp;
tr_upnp * upnp;
};
/***********************************************************************

View File

@@ -624,7 +624,7 @@ buildTrackerRequestURI( const tr_tracker * t,
char * ann = getCurrentAddress(t)->announce;
evbuffer_add_printf( buf, "%s"
"%sinfo_hash=%s"
"%cinfo_hash=%s"
"&peer_id=%s"
"&port=%d"
"&uploaded=%"PRIu64
@@ -639,7 +639,7 @@ buildTrackerRequestURI( const tr_tracker * t,
"%s%s"
"%s%s",
ann,
( strchr(ann, '?') == NULL ? "?" : "&" ),
strchr(ann, '?') ? '&' : '?',
t->escaped,
t->peer_id,
tr_sharedGetPublicPort( t->handle->shared ),

File diff suppressed because it is too large Load Diff

View File

@@ -25,15 +25,15 @@
#ifndef TR_UPNP_H
#define TR_UPNP_H 1
typedef struct tr_upnp_s tr_upnp_t;
typedef struct tr_upnp tr_upnp;
tr_upnp_t * tr_upnpInit ( void );
void tr_upnpStart ( tr_upnp_t * );
void tr_upnpStop ( tr_upnp_t * );
int tr_upnpStatus ( tr_upnp_t * );
void tr_upnpForwardPort ( tr_upnp_t *, int );
void tr_upnpRemoveForwarding ( tr_upnp_t * );
void tr_upnpPulse ( tr_upnp_t * );
void tr_upnpClose ( tr_upnp_t * );
tr_upnp * tr_upnpInit ( void );
void tr_upnpStart ( tr_upnp * );
void tr_upnpStop ( tr_upnp * );
int tr_upnpStatus ( tr_upnp * );
void tr_upnpForwardPort ( tr_upnp *, int );
void tr_upnpRemoveForwarding ( tr_upnp * );
void tr_upnpPulse ( tr_upnp * );
void tr_upnpClose ( tr_upnp * );
#endif

View File

@@ -295,40 +295,6 @@ tr_set_compare( const void * va, size_t aCount,
****
***/
void * tr_memmem ( const void *vbig, size_t big_len,
const void *vlittle, size_t little_len )
{
const char *big = vbig;
const char *little = vlittle;
size_t ii, jj;
if( 0 == big_len || 0 == little_len )
{
return NULL;
}
for( ii = 0; ii + little_len <= big_len; ii++ )
{
for( jj = 0; jj < little_len; jj++ )
{
if( big[ii + jj] != little[jj] )
{
break;
}
}
if( jj == little_len )
{
return (char*)big + ii;
}
}
return NULL;
}
/**
***
**/
int
tr_compareUint16( uint16_t a, uint16_t b )
{
@@ -476,22 +442,6 @@ tr_mkdirp( const char * path_in, int permissions )
return 0;
}
int
tr_strncasecmp( const char * s1, const char * s2, size_t n )
{
if ( !n )
return 0;
while( n-- != 0 && tolower( *s1 ) == tolower( *s2 ) ) {
if( !n || !*s1 || !*s2 )
break;
++s1;
++s2;
}
return tolower(*(unsigned char *) s1) - tolower(*(unsigned char *) s2);
}
int tr_sprintf( char ** buf, int * used, int * max, const char * format, ... )
{
va_list ap1, ap2;

View File

@@ -42,8 +42,6 @@ char* tr_getLogTimeStr( char * buf, int buflen );
int tr_rand ( int );
void * tr_memmem( const void *, size_t, const void *, size_t );
/***********************************************************************
* tr_mkdirp
***********************************************************************
@@ -56,14 +54,6 @@ int tr_mkdir( const char * path, int permissions );
uint8_t* tr_loadFile( const char * filename, size_t * size );
/***********************************************************************
* tr_strcasecmp
***********************************************************************
* A case-insensitive strncmp()
**********************************************************************/
#define tr_strcasecmp( ff, ss ) ( tr_strncasecmp( (ff), (ss), ULONG_MAX ) )
int tr_strncasecmp( const char * first, const char * second, size_t len );
/***********************************************************************
* tr_sprintf
***********************************************************************

View File

@@ -1,426 +0,0 @@
/******************************************************************************
* $Id$
*
* Copyright (c) 2006 Transmission authors and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*****************************************************************************/
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include "utils.h"
#include "xml.h"
/* http://www.w3.org/TR/2004/REC-xml-20040204/ */
#define WS( cc ) \
( ' ' == (cc) || '\t' == (cc) || '\n' == (cc) || '\r' == (cc) )
#define TAGBEGIN '<'
#define TAGEND '>'
#define TAGCLOSE '/'
#define NAMESPACESEP ':'
#define SQUOTEC '\''
#define DQUOTEC '"'
#define SQUOTES "'"
#define DQUOTES "\""
#define COMMENTBEGIN "<!--"
#define COMMENTEND "-->"
#define PROCINSTBEGIN "<?"
#define PROCINSTEND "?>"
#define CDATABEGIN "<![CDATA["
#define CDATAEND "]]>"
#define BANGBEGIN "<!"
#define BANGEND ">"
#define CHECKNULL( bb, ee, rr ) \
{ if( NULL == (bb) || (ee) <= (bb) ) return (rr); }
#define justskip( bb, ee, ap, ot, ct ) \
( skipthingy( (bb), (ee), (ap), (ot), (ct), NULL, NULL ) )
static char *
catrange( char * str, const char * begin, const char * end );
static int
skipall( const char * begin, const char * end, const char ** afterpos );
static int
nexttag( const char * begin, const char * end, const char ** tagpos );
static int
overtag( const char * begin, const char * end, const char ** overpos );
static int
tagname( const char * begin, const char * end,
const char ** tagstart, const char ** namestart, int * namelen );
static int
skipthingy( const char * begin, const char * end, const char ** afterpos,
const char * openthingy, const char * closethingy,
const char ** databegin, const char ** dataend );
/* XXX check document charset, in http headers and/or <?xml> tag */
const char *
tr_xmlFindTag( const char * begin, const char * end, const char * tag )
{
const char * name;
int len;
CHECKNULL( begin, end, NULL );
while( tagname( begin, end, &begin, &name, &len ) )
{
assert( NULL != begin && NULL != name && 0 < len );
if( 0 == tr_strncasecmp( tag, name, len ) )
{
return begin;
}
begin = tr_xmlSkipTag( begin, end );
}
return NULL;
}
const char *
tr_xmlTagName( const char * begin, const char * end, int * len )
{
CHECKNULL( begin, end, NULL );
if( tagname( begin, end, NULL, &begin, len ) )
{
return begin;
}
return NULL;
}
const char *
tr_xmlTagContents( const char * begin, const char * end )
{
CHECKNULL( begin, end, NULL );
if( nexttag( begin, end, &begin ) && overtag( begin, end, &begin ) )
{
begin = NULL;
}
return begin;
}
int
tr_xmlVerifyContents( const char * begin, const char * end, const char * data,
int ignorecase )
{
int len;
CHECKNULL( begin, end, 1 );
len = strlen( data );
while( end > begin && WS( *begin ) )
{
begin++;
}
if( end - begin > len )
{
if( ignorecase )
{
return ( 0 != tr_strncasecmp( begin, data, len ) );
}
else
{
return ( 0 != memcmp( begin, data, len ) );
}
}
return 1;
}
const char *
tr_xmlSkipTag( const char * begin, const char * end )
{
CHECKNULL( begin, end, NULL );
if( nexttag( begin, end, &begin ) )
{
if( overtag( begin, end, &begin ) )
{
return begin;
}
while( NULL != begin )
{
if( nexttag( begin, end, &begin ) )
{
begin = tr_xmlSkipTag( begin, end );
}
else
{
CHECKNULL( begin, end, NULL );
overtag( begin, end, &begin );
return begin;
}
}
}
return NULL;
}
char *
tr_xmlDupContents( const char * begin, const char * end )
{
const char * ii, * cbegin, * cend;
char * ret;
int len;
CHECKNULL( begin, end, NULL );
ret = NULL;
len = strlen( CDATABEGIN );
while( end > begin )
{
ii = memchr( begin, TAGBEGIN, end - begin );
if( NULL == ii )
{
free( ret );
return NULL;
}
/* XXX expand entity references and such here */
ret = catrange( ret, begin, ii );
if( NULL == ret )
{
return NULL;
}
if( !skipthingy( ii, end, &begin, CDATABEGIN, CDATAEND,
&cbegin, &cend ) )
{
ret = catrange( ret, cbegin, cend );
if( NULL == ret )
{
return NULL;
}
}
else if( skipall( ii, end, &begin ) )
{
if( end > ii + 1 && TAGCLOSE == ii[1] )
{
return ret;
}
begin = tr_xmlSkipTag( ii, end );
}
}
free( ret );
return NULL;
}
static char *
catrange( char * str, const char * begin, const char * end )
{
int len;
char * ret;
if( NULL == str )
{
return tr_strndup( begin, end - begin );
}
len = strlen( str );
ret = realloc( str, len + end - begin + 1 );
if( NULL == ret )
{
free( str );
return NULL;
}
memcpy( ret + len, begin, end - begin );
ret[len + end - begin] = '\0';
return ret;
}
static int
skipall( const char * begin, const char * end, const char ** afterpos )
{
return ( justskip( begin, end, afterpos, COMMENTBEGIN, COMMENTEND ) &&
justskip( begin, end, afterpos, CDATABEGIN, CDATAEND ) &&
justskip( begin, end, afterpos, PROCINSTBEGIN, PROCINSTEND ) &&
justskip( begin, end, afterpos, BANGBEGIN, BANGEND ) );
}
/* returns true if a tag was found and it's a start or empty element tag */
static int
nexttag( const char * begin, const char * end, const char ** tagpos )
{
*tagpos = NULL;
CHECKNULL( begin, end, 0 );
while( end > begin )
{
begin = memchr( begin, TAGBEGIN, end - begin );
CHECKNULL( begin, end, 0 );
if( justskip( begin, end, &begin, COMMENTBEGIN, COMMENTEND ) &&
justskip( begin, end, &begin, CDATABEGIN, CDATAEND ) &&
justskip( begin, end, &begin, PROCINSTBEGIN, PROCINSTEND ) &&
justskip( begin, end, &begin, BANGBEGIN, BANGEND ) )
{
*tagpos = begin;
begin++;
return ( end > begin && TAGCLOSE != *begin );
}
}
return 0;
}
/* returns true if the tag is an empty element such as <foo/> */
static int
overtag( const char * begin, const char * end, const char ** overpos )
{
const char * ii;
assert( NULL != begin && end > begin && TAGBEGIN == *begin );
ii = begin + 1;
while( end > ii )
{
switch( *ii )
{
case DQUOTEC:
justskip( ii, end, &ii, DQUOTES, DQUOTES );
break;
case SQUOTEC:
justskip( ii, end, &ii, SQUOTES, SQUOTES );
break;
case TAGEND:
*overpos = ii + 1;
for( ii--; begin < ii; ii-- )
{
if( TAGCLOSE == *ii )
{
return 1;
}
if( !WS( *ii ) )
{
break;
}
}
return 0;
default:
ii++;
break;
}
}
*overpos = NULL;
return 0;
}
static int
tagname( const char * begin, const char * end,
const char ** tagstart, const char ** namestart, int * namelen )
{
const char * name, * ii;
CHECKNULL( begin, end, 0 );
if( nexttag( begin, end, &begin ) )
{
assert( NULL != begin && TAGBEGIN == *begin );
ii = begin + 1;
while( end > ii && WS( *ii ) )
{
ii++;
}
name = ii;
while( end > ii && TAGEND != *ii && !WS( *ii ) )
{
if( NAMESPACESEP == *ii )
{
name = ii + 1;
}
ii++;
}
if( end > ii && ii > name )
{
if( NULL != tagstart )
{
*tagstart = begin;
}
if( NULL != namestart )
{
*namestart = name;
}
if( NULL != namelen )
{
*namelen = ii - name;
}
return 1;
}
}
return 0;
}
static int
skipthingy( const char * begin, const char * end, const char ** afterpos,
const char * openthingy, const char * closethingy,
const char ** databegin, const char ** dataend )
{
int len;
CHECKNULL( begin, end, 1 );
len = strlen( openthingy );
if( 0 != memcmp( begin, openthingy, MIN( end - begin, len ) ) )
{
return 1;
}
if( NULL != afterpos )
{
*afterpos = NULL;
}
if( NULL != databegin )
{
*databegin = NULL;
}
if( NULL != dataend )
{
*dataend = NULL;
}
if( end - begin <= len )
{
return 0;
}
begin += len;
if( NULL != databegin )
{
*databegin = begin;
}
len = strlen( closethingy );
begin = tr_memmem( begin, end - begin, closethingy, len );
if( NULL != dataend )
{
*dataend = begin;
}
if( NULL != afterpos && NULL != begin )
{
*afterpos = ( begin + len >= end ? NULL : begin + len );
}
return 0;
}

View File

@@ -1,57 +0,0 @@
/******************************************************************************
* $Id$
*
* Copyright (c) 2006 Transmission authors and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*****************************************************************************/
#ifndef TR_XML_H
#define TR_XML_H 1
const char *
tr_xmlFindTag( const char * begin, const char * end, const char * tag );
const char *
tr_xmlTagName( const char * begin, const char * end, int * len );
const char *
tr_xmlTagContents( const char * begin, const char * end );
#define tr_xmlFindTagContents( bb, ee, tt ) \
( tr_xmlTagContents( tr_xmlFindTag( (bb), (ee), (tt) ), (ee) ) )
int
tr_xmlVerifyContents( const char * begin, const char * end, const char * data,
int ignorecase );
#define tr_xmlFindTagVerifyContents( bb, ee, tt, dd, ic ) \
( tr_xmlVerifyContents( tr_xmlFindTagContents( (bb), (ee), (tt) ), \
(ee), (dd), (ic) ) )
const char *
tr_xmlSkipTag( const char * begin, const char * end );
char *
tr_xmlDupContents( const char * begin, const char * end );
#define tr_xmlDupTagContents( bb, ee, tt ) \
( tr_xmlDupContents( tr_xmlFindTagContents( (bb), (ee), (tt) ), (ee) ) )
#endif

View File

@@ -1,4 +1,4 @@
SUBDIRS = libevent
SUBDIRS = libevent miniupnp
EXTRA_DIST = \
macosx-libevent-config.h

26
third-party/miniupnp/LICENCE vendored Normal file
View File

@@ -0,0 +1,26 @@
Copyright (c) 2005-2007, Thomas BERNARD
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

541
third-party/miniupnp/Makefile vendored Normal file
View File

@@ -0,0 +1,541 @@
# Makefile.in generated by automake 1.10 from Makefile.am.
# third-party/miniupnp/Makefile. Generated from Makefile.in by configure.
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
pkgdatadir = $(datadir)/transmission
pkglibdir = $(libdir)/transmission
pkgincludedir = $(includedir)/transmission
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = x86_64-unknown-linux-gnu
host_triplet = x86_64-unknown-linux-gnu
subdir = third-party/miniupnp
DIST_COMMON = README $(noinst_HEADERS) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/acintltool.m4 \
$(top_srcdir)/m4/acx-pthread.m4 \
$(top_srcdir)/m4/glib-gettext.m4 $(top_srcdir)/m4/pkg.m4 \
$(top_srcdir)/m4/wxwin.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_CLEAN_FILES =
LIBRARIES = $(noinst_LIBRARIES)
ARFLAGS = cru
libminiupnp_a_AR = $(AR) $(ARFLAGS)
libminiupnp_a_LIBADD =
am_libminiupnp_a_OBJECTS = igd_desc_parse.$(OBJEXT) minisoap.$(OBJEXT) \
minissdpc.$(OBJEXT) miniupnpc.$(OBJEXT) miniwget.$(OBJEXT) \
minixml.$(OBJEXT) upnpcommands.$(OBJEXT) \
upnpreplyparse.$(OBJEXT)
libminiupnp_a_OBJECTS = $(am_libminiupnp_a_OBJECTS)
DEFAULT_INCLUDES = -I.
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
$(LDFLAGS) -o $@
SOURCES = $(libminiupnp_a_SOURCES)
DIST_SOURCES = $(libminiupnp_a_SOURCES)
HEADERS = $(noinst_HEADERS)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = ${SHELL} /home/charles/Desktop/T/missing --run aclocal-1.10
ALL_LINGUAS =
AMTAR = ${SHELL} /home/charles/Desktop/T/missing --run tar
AR = ar
AUTOCONF = ${SHELL} /home/charles/Desktop/T/missing --run autoconf
AUTOHEADER = ${SHELL} /home/charles/Desktop/T/missing --run autoheader
AUTOMAKE = ${SHELL} /home/charles/Desktop/T/missing --run automake-1.10
AWK = gawk
CATALOGS =
CATOBJEXT = .gmo
CC = gcc
CCDEPMODE = depmode=gcc3
CFLAGS = -g -Wall -W -O3 -funroll-loops
CPP = gcc -E
CPPFLAGS =
CXX = g++
CXXCPP = g++ -E
CXXDEPMODE = depmode=gcc3
CXXFLAGS = -g -Wall -W -O3 -funroll-loops
CYGPATH_W = echo
DATADIRNAME = share
DEFS = -DPACKAGE_NAME=\"transmission\" -DPACKAGE_TARNAME=\"transmission\" -DPACKAGE_VERSION=\"0.92Z\" -DPACKAGE_STRING=\"transmission\ 0.92Z\" -DPACKAGE_BUGREPORT=\"http://transmission.m0k.org/trac/newticket\" -DPACKAGE=\"transmission\" -DVERSION=\"0.92Z\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_DLFCN_H=1 -DSTDC_HEADERS=1 -DTIME_WITH_SYS_TIME=1 -DHAVE_DAEMON=1 -DHAVE_DIRNAME=1 -DHAVE_BASENAME=1 -DSIZEOF_VOIDP=8 -DHAVE_PTHREAD=1 -DGETTEXT_PACKAGE=\"transmission\" -DHAVE_LOCALE_H=1 -DHAVE_LC_MESSAGES=1 -DHAVE_BIND_TEXTDOMAIN_CODESET=1 -DHAVE_GETTEXT=1 -DHAVE_DCGETTEXT=1 -DENABLE_NLS=1
DEPDIR = .deps
ECHO = echo
ECHO_C =
ECHO_N = -n
ECHO_T =
EGREP = /bin/grep -E
EXEEXT =
F77 = gfortran
FFLAGS = -g -O2
GETTEXT_PACKAGE = transmission
GLIB_MINIMUM = 2.6.0
GMOFILES =
GMSGFMT = /usr/bin/msgfmt
GREP = /bin/grep
GTK_CFLAGS = -pthread -I/usr/include/gtk-2.0 -I/usr/lib64/gtk-2.0/include -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/pango-1.0 -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include
GTK_LIBS = -Wl,--export-dynamic -pthread -lgtk-x11-2.0 -lgdk-x11-2.0 -latk-1.0 -lgdk_pixbuf-2.0 -lpng12 -lm -lpangocairo-1.0 -lpango-1.0 -lcairo -lgobject-2.0 -lgmodule-2.0 -ldl -lgthread-2.0 -lrt -lglib-2.0
GTK_MINIMUM = 2.6.0
INSTALL = /usr/bin/install -c
INSTALL_DATA = ${INSTALL} -m 644
INSTALL_PROGRAM = ${INSTALL}
INSTALL_SCRIPT = ${INSTALL}
INSTALL_STRIP_PROGRAM = $(install_sh) -c -s
INSTOBJEXT = .mo
INTLLIBS =
INTLTOOL_CAVES_RULE = %.caves: %.caves.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@
INTLTOOL_DESKTOP_RULE = %.desktop: %.desktop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@
INTLTOOL_DIRECTORY_RULE = %.directory: %.directory.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@
INTLTOOL_EXTRACT = $(top_builddir)/intltool-extract
INTLTOOL_ICONV = /usr/bin/iconv
INTLTOOL_KBD_RULE = %.kbd: %.kbd.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -m -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@
INTLTOOL_KEYS_RULE = %.keys: %.keys.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -k -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@
INTLTOOL_MERGE = $(top_builddir)/intltool-merge
INTLTOOL_MSGFMT = /usr/bin/msgfmt
INTLTOOL_MSGMERGE = /usr/bin/msgmerge
INTLTOOL_OAF_RULE = %.oaf: %.oaf.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -o -p $(top_srcdir)/po $< $@
INTLTOOL_PERL = /usr/bin/perl
INTLTOOL_PONG_RULE = %.pong: %.pong.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@
INTLTOOL_PROP_RULE = %.prop: %.prop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@
INTLTOOL_SCHEMAS_RULE = %.schemas: %.schemas.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -s -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@
INTLTOOL_SERVER_RULE = %.server: %.server.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -o -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@
INTLTOOL_SERVICE_RULE = %.service: %.service.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@
INTLTOOL_SHEET_RULE = %.sheet: %.sheet.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@
INTLTOOL_SOUNDLIST_RULE = %.soundlist: %.soundlist.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@
INTLTOOL_THEME_RULE = %.theme: %.theme.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@
INTLTOOL_UI_RULE = %.ui: %.ui.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@
INTLTOOL_UPDATE = $(top_builddir)/intltool-update
INTLTOOL_XAM_RULE = %.xam: %.xml.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@
INTLTOOL_XGETTEXT = /usr/bin/xgettext
INTLTOOL_XML_NOMERGE_RULE = %.xml: %.xml.in $(INTLTOOL_MERGE) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u /tmp $< $@
INTLTOOL_XML_RULE = %.xml: %.xml.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@
LDFLAGS =
LIBEVENT_CPPFLAGS = -I$(top_srcdir)/third-party/libevent
LIBOBJS =
LIBS =
LIBTOOL = $(SHELL) $(top_builddir)/libtool
LN_S = ln -s
LTLIBOBJS =
MAKEINFO = ${SHELL} /home/charles/Desktop/T/missing --run makeinfo
MKDIR_P = /bin/mkdir -p
MKINSTALLDIRS = ./mkinstalldirs
MSGFMT = /usr/bin/msgfmt
OBJEXT = o
OPENSSL_CFLAGS = -I/usr/kerberos/include
OPENSSL_LIBS = -L/usr/kerberos/lib64 -lssl -lcrypto -ldl -lz
PACKAGE = transmission
PACKAGE_BUGREPORT = http://transmission.m0k.org/trac/newticket
PACKAGE_NAME = transmission
PACKAGE_STRING = transmission 0.92Z
PACKAGE_TARNAME = transmission
PACKAGE_VERSION = 0.92Z
PATH_SEPARATOR = :
PEERID_PREFIX = -TR092Z-
PKG_CONFIG = /usr/bin/pkg-config
POFILES =
POSUB = po
PO_IN_DATADIR_FALSE =
PO_IN_DATADIR_TRUE =
PTHREAD_CC = gcc
PTHREAD_CFLAGS = -pthread
PTHREAD_LIBS =
RANLIB = ranlib
SED = /bin/sed
SET_MAKE =
SHELL = /bin/sh
STRIP = strip
USERAGENT_PREFIX = 0.92+
USE_NLS = yes
VERSION = 0.92Z
WINDRES =
WX_CFLAGS = -I/usr/lib64/wx/include/gtk2-unicode-release-2.8 -I/usr/include/wx-2.8 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILES -D__WXGTK__ -pthread
WX_CFLAGS_ONLY = -pthread
WX_CONFIG_PATH = /usr/bin/wx-config
WX_CPPFLAGS = -I/usr/lib64/wx/include/gtk2-unicode-release-2.8 -I/usr/include/wx-2.8 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILES -D__WXGTK__
WX_CXXFLAGS = -I/usr/lib64/wx/include/gtk2-unicode-release-2.8 -I/usr/include/wx-2.8 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILES -D__WXGTK__ -pthread
WX_CXXFLAGS_ONLY =
WX_LIBS = -pthread -lwx_gtk2u_aui-2.8 -lwx_gtk2u_xrc-2.8 -lwx_gtk2u_qa-2.8 -lwx_gtk2u_html-2.8 -lwx_gtk2u_adv-2.8 -lwx_gtk2u_core-2.8 -lwx_baseu_xml-2.8 -lwx_baseu_net-2.8 -lwx_baseu-2.8
WX_LIBS_STATIC =
WX_MINIMUM = 2.6.0
WX_RESCOMP =
WX_VERSION = 2.8.4
XGETTEXT = /usr/bin/xgettext
abs_builddir = /home/charles/Desktop/T/third-party/miniupnp
abs_srcdir = /home/charles/Desktop/T/third-party/miniupnp
abs_top_builddir = /home/charles/Desktop/T
abs_top_srcdir = /home/charles/Desktop/T
ac_ct_CC = gcc
ac_ct_CXX = g++
ac_ct_F77 = gfortran
acx_pthread_config =
am__include = include
am__leading_dot = .
am__quote =
am__tar = tar --format=ustar -chf - "$$tardir"
am__untar = tar -xf -
bindir = ${exec_prefix}/bin
build = x86_64-unknown-linux-gnu
build_alias =
build_cpu = x86_64
build_os = linux-gnu
build_vendor = unknown
builddir = .
datadir = ${datarootdir}
datarootdir = ${prefix}/share
docdir = ${datarootdir}/doc/${PACKAGE_TARNAME}
dvidir = ${docdir}
exec_prefix = ${prefix}
host = x86_64-unknown-linux-gnu
host_alias =
host_cpu = x86_64
host_os = linux-gnu
host_vendor = unknown
htmldir = ${docdir}
includedir = ${prefix}/include
infodir = ${datarootdir}/info
install_sh = $(SHELL) /home/charles/Desktop/T/install-sh
libdir = ${exec_prefix}/lib
libexecdir = ${exec_prefix}/libexec
localedir = ${datarootdir}/locale
localstatedir = ${prefix}/var
mandir = ${datarootdir}/man
mkdir_p = /bin/mkdir -p
oldincludedir = /usr/include
pdfdir = ${docdir}
prefix = /usr/local
program_transform_name = s,x,x,
psdir = ${docdir}
sbindir = ${exec_prefix}/sbin
sharedstatedir = ${prefix}/com
srcdir = .
subdirs = third-party/libevent
sysconfdir = ${prefix}/etc
target_alias =
top_builddir = ../..
top_srcdir = ../..
transmissionlocaledir = ${prefix}/${DATADIRNAME}/locale
noinst_LIBRARIES = libminiupnp.a
AM_CPPFLAGS = -DNDEBUG
libminiupnp_a_SOURCES = \
igd_desc_parse.c \
minisoap.c \
minissdpc.c \
miniupnpc.c \
miniwget.c \
minixml.c \
upnpcommands.c \
upnpreplyparse.c
noinst_HEADERS = \
bsdqueue.h \
declspec.h \
igd_desc_parse.h \
minisoap.h \
minissdpc.h \
miniupnpc.h \
miniwget.h \
minixml.h \
upnpcommands.h \
upnpreplyparse.h
extra_DIST = \
README \
LICENSE
all: all-am
.SUFFIXES:
.SUFFIXES: .c .lo .o .obj
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu third-party/miniupnp/Makefile'; \
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu third-party/miniupnp/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
clean-noinstLIBRARIES:
-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
libminiupnp.a: $(libminiupnp_a_OBJECTS) $(libminiupnp_a_DEPENDENCIES)
-rm -f libminiupnp.a
$(libminiupnp_a_AR) libminiupnp.a $(libminiupnp_a_OBJECTS) $(libminiupnp_a_LIBADD)
$(RANLIB) libminiupnp.a
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
include ./$(DEPDIR)/igd_desc_parse.Po
include ./$(DEPDIR)/minisoap.Po
include ./$(DEPDIR)/minissdpc.Po
include ./$(DEPDIR)/miniupnpc.Po
include ./$(DEPDIR)/miniwget.Po
include ./$(DEPDIR)/minixml.Po
include ./$(DEPDIR)/upnpcommands.Po
include ./$(DEPDIR)/upnpreplyparse.Po
.c.o:
$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
# source='$<' object='$@' libtool=no \
# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
# $(COMPILE) -c $<
.c.obj:
$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
# source='$<' object='$@' libtool=no \
# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
# $(COMPILE) -c `$(CYGPATH_W) '$<'`
.c.lo:
$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
# source='$<' object='$@' libtool=yes \
# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
# $(LTCOMPILE) -c -o $@ $<
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique; \
fi
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(LIBRARIES) $(HEADERS)
installdirs:
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libtool clean-noinstLIBRARIES \
mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
info: info-am
info-am:
install-data-am:
install-dvi: install-dvi-am
install-exec-am:
install-html: install-html-am
install-info: install-info-am
install-man:
install-pdf: install-pdf-am
install-ps: install-ps-am
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am:
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
clean-libtool clean-noinstLIBRARIES ctags distclean \
distclean-compile distclean-generic distclean-libtool \
distclean-tags distdir dvi dvi-am html html-am info info-am \
install install-am install-data install-data-am install-dvi \
install-dvi-am install-exec install-exec-am install-html \
install-html-am install-info install-info-am install-man \
install-pdf install-pdf-am install-ps install-ps-am \
install-strip installcheck installcheck-am installdirs \
maintainer-clean maintainer-clean-generic mostlyclean \
mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
pdf pdf-am ps ps-am tags uninstall uninstall-am
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

29
third-party/miniupnp/Makefile.am vendored Normal file
View File

@@ -0,0 +1,29 @@
noinst_LIBRARIES = libminiupnp.a
AM_CPPFLAGS = -DNDEBUG
libminiupnp_a_SOURCES = \
igd_desc_parse.c \
minisoap.c \
minissdpc.c \
miniupnpc.c \
miniwget.c \
minixml.c \
upnpcommands.c \
upnpreplyparse.c
noinst_HEADERS = \
bsdqueue.h \
declspec.h \
igd_desc_parse.h \
minisoap.h \
minissdpc.h \
miniupnpc.h \
miniwget.h \
minixml.h \
upnpcommands.h \
upnpreplyparse.h
extra_DIST = \
README \
LICENSE

541
third-party/miniupnp/Makefile.in vendored Normal file
View File

@@ -0,0 +1,541 @@
# Makefile.in generated by automake 1.10 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = third-party/miniupnp
DIST_COMMON = README $(noinst_HEADERS) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/acintltool.m4 \
$(top_srcdir)/m4/acx-pthread.m4 \
$(top_srcdir)/m4/glib-gettext.m4 $(top_srcdir)/m4/pkg.m4 \
$(top_srcdir)/m4/wxwin.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_CLEAN_FILES =
LIBRARIES = $(noinst_LIBRARIES)
ARFLAGS = cru
libminiupnp_a_AR = $(AR) $(ARFLAGS)
libminiupnp_a_LIBADD =
am_libminiupnp_a_OBJECTS = igd_desc_parse.$(OBJEXT) minisoap.$(OBJEXT) \
minissdpc.$(OBJEXT) miniupnpc.$(OBJEXT) miniwget.$(OBJEXT) \
minixml.$(OBJEXT) upnpcommands.$(OBJEXT) \
upnpreplyparse.$(OBJEXT)
libminiupnp_a_OBJECTS = $(am_libminiupnp_a_OBJECTS)
DEFAULT_INCLUDES = -I.@am__isrc@
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
$(LDFLAGS) -o $@
SOURCES = $(libminiupnp_a_SOURCES)
DIST_SOURCES = $(libminiupnp_a_SOURCES)
HEADERS = $(noinst_HEADERS)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
ALL_LINGUAS = @ALL_LINGUAS@
AMTAR = @AMTAR@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CATALOGS = @CATALOGS@
CATOBJEXT = @CATOBJEXT@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DATADIRNAME = @DATADIRNAME@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
F77 = @F77@
FFLAGS = @FFLAGS@
GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
GLIB_MINIMUM = @GLIB_MINIMUM@
GMOFILES = @GMOFILES@
GMSGFMT = @GMSGFMT@
GREP = @GREP@
GTK_CFLAGS = @GTK_CFLAGS@
GTK_LIBS = @GTK_LIBS@
GTK_MINIMUM = @GTK_MINIMUM@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
INSTOBJEXT = @INSTOBJEXT@
INTLLIBS = @INTLLIBS@
INTLTOOL_CAVES_RULE = @INTLTOOL_CAVES_RULE@
INTLTOOL_DESKTOP_RULE = @INTLTOOL_DESKTOP_RULE@
INTLTOOL_DIRECTORY_RULE = @INTLTOOL_DIRECTORY_RULE@
INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
INTLTOOL_ICONV = @INTLTOOL_ICONV@
INTLTOOL_KBD_RULE = @INTLTOOL_KBD_RULE@
INTLTOOL_KEYS_RULE = @INTLTOOL_KEYS_RULE@
INTLTOOL_MERGE = @INTLTOOL_MERGE@
INTLTOOL_MSGFMT = @INTLTOOL_MSGFMT@
INTLTOOL_MSGMERGE = @INTLTOOL_MSGMERGE@
INTLTOOL_OAF_RULE = @INTLTOOL_OAF_RULE@
INTLTOOL_PERL = @INTLTOOL_PERL@
INTLTOOL_PONG_RULE = @INTLTOOL_PONG_RULE@
INTLTOOL_PROP_RULE = @INTLTOOL_PROP_RULE@
INTLTOOL_SCHEMAS_RULE = @INTLTOOL_SCHEMAS_RULE@
INTLTOOL_SERVER_RULE = @INTLTOOL_SERVER_RULE@
INTLTOOL_SERVICE_RULE = @INTLTOOL_SERVICE_RULE@
INTLTOOL_SHEET_RULE = @INTLTOOL_SHEET_RULE@
INTLTOOL_SOUNDLIST_RULE = @INTLTOOL_SOUNDLIST_RULE@
INTLTOOL_THEME_RULE = @INTLTOOL_THEME_RULE@
INTLTOOL_UI_RULE = @INTLTOOL_UI_RULE@
INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
INTLTOOL_XAM_RULE = @INTLTOOL_XAM_RULE@
INTLTOOL_XGETTEXT = @INTLTOOL_XGETTEXT@
INTLTOOL_XML_NOMERGE_RULE = @INTLTOOL_XML_NOMERGE_RULE@
INTLTOOL_XML_RULE = @INTLTOOL_XML_RULE@
LDFLAGS = @LDFLAGS@
LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
MKINSTALLDIRS = @MKINSTALLDIRS@
MSGFMT = @MSGFMT@
OBJEXT = @OBJEXT@
OPENSSL_CFLAGS = @OPENSSL_CFLAGS@
OPENSSL_LIBS = @OPENSSL_LIBS@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PEERID_PREFIX = @PEERID_PREFIX@
PKG_CONFIG = @PKG_CONFIG@
POFILES = @POFILES@
POSUB = @POSUB@
PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
PTHREAD_CC = @PTHREAD_CC@
PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
PTHREAD_LIBS = @PTHREAD_LIBS@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
USERAGENT_PREFIX = @USERAGENT_PREFIX@
USE_NLS = @USE_NLS@
VERSION = @VERSION@
WINDRES = @WINDRES@
WX_CFLAGS = @WX_CFLAGS@
WX_CFLAGS_ONLY = @WX_CFLAGS_ONLY@
WX_CONFIG_PATH = @WX_CONFIG_PATH@
WX_CPPFLAGS = @WX_CPPFLAGS@
WX_CXXFLAGS = @WX_CXXFLAGS@
WX_CXXFLAGS_ONLY = @WX_CXXFLAGS_ONLY@
WX_LIBS = @WX_LIBS@
WX_LIBS_STATIC = @WX_LIBS_STATIC@
WX_MINIMUM = @WX_MINIMUM@
WX_RESCOMP = @WX_RESCOMP@
WX_VERSION = @WX_VERSION@
XGETTEXT = @XGETTEXT@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_F77 = @ac_ct_F77@
acx_pthread_config = @acx_pthread_config@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
subdirs = @subdirs@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
transmissionlocaledir = @transmissionlocaledir@
noinst_LIBRARIES = libminiupnp.a
AM_CPPFLAGS = -DNDEBUG
libminiupnp_a_SOURCES = \
igd_desc_parse.c \
minisoap.c \
minissdpc.c \
miniupnpc.c \
miniwget.c \
minixml.c \
upnpcommands.c \
upnpreplyparse.c
noinst_HEADERS = \
bsdqueue.h \
declspec.h \
igd_desc_parse.h \
minisoap.h \
minissdpc.h \
miniupnpc.h \
miniwget.h \
minixml.h \
upnpcommands.h \
upnpreplyparse.h
extra_DIST = \
README \
LICENSE
all: all-am
.SUFFIXES:
.SUFFIXES: .c .lo .o .obj
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu third-party/miniupnp/Makefile'; \
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu third-party/miniupnp/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
clean-noinstLIBRARIES:
-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
libminiupnp.a: $(libminiupnp_a_OBJECTS) $(libminiupnp_a_DEPENDENCIES)
-rm -f libminiupnp.a
$(libminiupnp_a_AR) libminiupnp.a $(libminiupnp_a_OBJECTS) $(libminiupnp_a_LIBADD)
$(RANLIB) libminiupnp.a
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/igd_desc_parse.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/minisoap.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/minissdpc.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/miniupnpc.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/miniwget.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/minixml.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/upnpcommands.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/upnpreplyparse.Po@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c $<
.c.obj:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
.c.lo:
@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique; \
fi
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(LIBRARIES) $(HEADERS)
installdirs:
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libtool clean-noinstLIBRARIES \
mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
info: info-am
info-am:
install-data-am:
install-dvi: install-dvi-am
install-exec-am:
install-html: install-html-am
install-info: install-info-am
install-man:
install-pdf: install-pdf-am
install-ps: install-ps-am
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am:
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
clean-libtool clean-noinstLIBRARIES ctags distclean \
distclean-compile distclean-generic distclean-libtool \
distclean-tags distdir dvi dvi-am html html-am info info-am \
install install-am install-data install-data-am install-dvi \
install-dvi-am install-exec install-exec-am install-html \
install-html-am install-info install-info-am install-man \
install-pdf install-pdf-am install-ps install-ps-am \
install-strip installcheck installcheck-am installdirs \
maintainer-clean maintainer-clean-generic mostlyclean \
mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
pdf pdf-am ps ps-am tags uninstall uninstall-am
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

3
third-party/miniupnp/README vendored Normal file
View File

@@ -0,0 +1,3 @@
MiniUPnP is written by Thomas Bernard.
Its homepage is http://miniupnp.free.fr/
This code is from the miniupnpc-20071103 snapshot

531
third-party/miniupnp/bsdqueue.h vendored Normal file
View File

@@ -0,0 +1,531 @@
/* $OpenBSD: queue.h,v 1.31 2005/11/25 08:06:25 otto Exp $ */
/* $NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $ */
/*
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)queue.h 8.5 (Berkeley) 8/20/94
*/
#ifndef _SYS_QUEUE_H_
#define _SYS_QUEUE_H_
/*
* This file defines five types of data structures: singly-linked lists,
* lists, simple queues, tail queues, and circular queues.
*
*
* A singly-linked list is headed by a single forward pointer. The elements
* are singly linked for minimum space and pointer manipulation overhead at
* the expense of O(n) removal for arbitrary elements. New elements can be
* added to the list after an existing element or at the head of the list.
* Elements being removed from the head of the list should use the explicit
* macro for this purpose for optimum efficiency. A singly-linked list may
* only be traversed in the forward direction. Singly-linked lists are ideal
* for applications with large datasets and few or no removals or for
* implementing a LIFO queue.
*
* A list is headed by a single forward pointer (or an array of forward
* pointers for a hash table header). The elements are doubly linked
* so that an arbitrary element can be removed without a need to
* traverse the list. New elements can be added to the list before
* or after an existing element or at the head of the list. A list
* may only be traversed in the forward direction.
*
* A simple queue is headed by a pair of pointers, one the head of the
* list and the other to the tail of the list. The elements are singly
* linked to save space, so elements can only be removed from the
* head of the list. New elements can be added to the list before or after
* an existing element, at the head of the list, or at the end of the
* list. A simple queue may only be traversed in the forward direction.
*
* A tail queue is headed by a pair of pointers, one to the head of the
* list and the other to the tail of the list. The elements are doubly
* linked so that an arbitrary element can be removed without a need to
* traverse the list. New elements can be added to the list before or
* after an existing element, at the head of the list, or at the end of
* the list. A tail queue may be traversed in either direction.
*
* A circle queue is headed by a pair of pointers, one to the head of the
* list and the other to the tail of the list. The elements are doubly
* linked so that an arbitrary element can be removed without a need to
* traverse the list. New elements can be added to the list before or after
* an existing element, at the head of the list, or at the end of the list.
* A circle queue may be traversed in either direction, but has a more
* complex end of list detection.
*
* For details on the use of these macros, see the queue(3) manual page.
*/
#ifdef QUEUE_MACRO_DEBUG
#define _Q_INVALIDATE(a) (a) = ((void *)-1)
#else
#define _Q_INVALIDATE(a)
#endif
/*
* Singly-linked List definitions.
*/
#define SLIST_HEAD(name, type) \
struct name { \
struct type *slh_first; /* first element */ \
}
#define SLIST_HEAD_INITIALIZER(head) \
{ NULL }
#ifdef SLIST_ENTRY
#undef SLIST_ENTRY
#endif
#define SLIST_ENTRY(type) \
struct { \
struct type *sle_next; /* next element */ \
}
/*
* Singly-linked List access methods.
*/
#define SLIST_FIRST(head) ((head)->slh_first)
#define SLIST_END(head) NULL
#define SLIST_EMPTY(head) (SLIST_FIRST(head) == SLIST_END(head))
#define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
#define SLIST_FOREACH(var, head, field) \
for((var) = SLIST_FIRST(head); \
(var) != SLIST_END(head); \
(var) = SLIST_NEXT(var, field))
#define SLIST_FOREACH_PREVPTR(var, varp, head, field) \
for ((varp) = &SLIST_FIRST((head)); \
((var) = *(varp)) != SLIST_END(head); \
(varp) = &SLIST_NEXT((var), field))
/*
* Singly-linked List functions.
*/
#define SLIST_INIT(head) { \
SLIST_FIRST(head) = SLIST_END(head); \
}
#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \
(elm)->field.sle_next = (slistelm)->field.sle_next; \
(slistelm)->field.sle_next = (elm); \
} while (0)
#define SLIST_INSERT_HEAD(head, elm, field) do { \
(elm)->field.sle_next = (head)->slh_first; \
(head)->slh_first = (elm); \
} while (0)
#define SLIST_REMOVE_NEXT(head, elm, field) do { \
(elm)->field.sle_next = (elm)->field.sle_next->field.sle_next; \
} while (0)
#define SLIST_REMOVE_HEAD(head, field) do { \
(head)->slh_first = (head)->slh_first->field.sle_next; \
} while (0)
#define SLIST_REMOVE(head, elm, type, field) do { \
if ((head)->slh_first == (elm)) { \
SLIST_REMOVE_HEAD((head), field); \
} else { \
struct type *curelm = (head)->slh_first; \
\
while (curelm->field.sle_next != (elm)) \
curelm = curelm->field.sle_next; \
curelm->field.sle_next = \
curelm->field.sle_next->field.sle_next; \
_Q_INVALIDATE((elm)->field.sle_next); \
} \
} while (0)
/*
* List definitions.
*/
#define LIST_HEAD(name, type) \
struct name { \
struct type *lh_first; /* first element */ \
}
#define LIST_HEAD_INITIALIZER(head) \
{ NULL }
#define LIST_ENTRY(type) \
struct { \
struct type *le_next; /* next element */ \
struct type **le_prev; /* address of previous next element */ \
}
/*
* List access methods
*/
#define LIST_FIRST(head) ((head)->lh_first)
#define LIST_END(head) NULL
#define LIST_EMPTY(head) (LIST_FIRST(head) == LIST_END(head))
#define LIST_NEXT(elm, field) ((elm)->field.le_next)
#define LIST_FOREACH(var, head, field) \
for((var) = LIST_FIRST(head); \
(var)!= LIST_END(head); \
(var) = LIST_NEXT(var, field))
/*
* List functions.
*/
#define LIST_INIT(head) do { \
LIST_FIRST(head) = LIST_END(head); \
} while (0)
#define LIST_INSERT_AFTER(listelm, elm, field) do { \
if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \
(listelm)->field.le_next->field.le_prev = \
&(elm)->field.le_next; \
(listelm)->field.le_next = (elm); \
(elm)->field.le_prev = &(listelm)->field.le_next; \
} while (0)
#define LIST_INSERT_BEFORE(listelm, elm, field) do { \
(elm)->field.le_prev = (listelm)->field.le_prev; \
(elm)->field.le_next = (listelm); \
*(listelm)->field.le_prev = (elm); \
(listelm)->field.le_prev = &(elm)->field.le_next; \
} while (0)
#define LIST_INSERT_HEAD(head, elm, field) do { \
if (((elm)->field.le_next = (head)->lh_first) != NULL) \
(head)->lh_first->field.le_prev = &(elm)->field.le_next;\
(head)->lh_first = (elm); \
(elm)->field.le_prev = &(head)->lh_first; \
} while (0)
#define LIST_REMOVE(elm, field) do { \
if ((elm)->field.le_next != NULL) \
(elm)->field.le_next->field.le_prev = \
(elm)->field.le_prev; \
*(elm)->field.le_prev = (elm)->field.le_next; \
_Q_INVALIDATE((elm)->field.le_prev); \
_Q_INVALIDATE((elm)->field.le_next); \
} while (0)
#define LIST_REPLACE(elm, elm2, field) do { \
if (((elm2)->field.le_next = (elm)->field.le_next) != NULL) \
(elm2)->field.le_next->field.le_prev = \
&(elm2)->field.le_next; \
(elm2)->field.le_prev = (elm)->field.le_prev; \
*(elm2)->field.le_prev = (elm2); \
_Q_INVALIDATE((elm)->field.le_prev); \
_Q_INVALIDATE((elm)->field.le_next); \
} while (0)
/*
* Simple queue definitions.
*/
#define SIMPLEQ_HEAD(name, type) \
struct name { \
struct type *sqh_first; /* first element */ \
struct type **sqh_last; /* addr of last next element */ \
}
#define SIMPLEQ_HEAD_INITIALIZER(head) \
{ NULL, &(head).sqh_first }
#define SIMPLEQ_ENTRY(type) \
struct { \
struct type *sqe_next; /* next element */ \
}
/*
* Simple queue access methods.
*/
#define SIMPLEQ_FIRST(head) ((head)->sqh_first)
#define SIMPLEQ_END(head) NULL
#define SIMPLEQ_EMPTY(head) (SIMPLEQ_FIRST(head) == SIMPLEQ_END(head))
#define SIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next)
#define SIMPLEQ_FOREACH(var, head, field) \
for((var) = SIMPLEQ_FIRST(head); \
(var) != SIMPLEQ_END(head); \
(var) = SIMPLEQ_NEXT(var, field))
/*
* Simple queue functions.
*/
#define SIMPLEQ_INIT(head) do { \
(head)->sqh_first = NULL; \
(head)->sqh_last = &(head)->sqh_first; \
} while (0)
#define SIMPLEQ_INSERT_HEAD(head, elm, field) do { \
if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \
(head)->sqh_last = &(elm)->field.sqe_next; \
(head)->sqh_first = (elm); \
} while (0)
#define SIMPLEQ_INSERT_TAIL(head, elm, field) do { \
(elm)->field.sqe_next = NULL; \
*(head)->sqh_last = (elm); \
(head)->sqh_last = &(elm)->field.sqe_next; \
} while (0)
#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\
(head)->sqh_last = &(elm)->field.sqe_next; \
(listelm)->field.sqe_next = (elm); \
} while (0)
#define SIMPLEQ_REMOVE_HEAD(head, field) do { \
if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \
(head)->sqh_last = &(head)->sqh_first; \
} while (0)
/*
* Tail queue definitions.
*/
#define TAILQ_HEAD(name, type) \
struct name { \
struct type *tqh_first; /* first element */ \
struct type **tqh_last; /* addr of last next element */ \
}
#define TAILQ_HEAD_INITIALIZER(head) \
{ NULL, &(head).tqh_first }
#define TAILQ_ENTRY(type) \
struct { \
struct type *tqe_next; /* next element */ \
struct type **tqe_prev; /* address of previous next element */ \
}
/*
* tail queue access methods
*/
#define TAILQ_FIRST(head) ((head)->tqh_first)
#define TAILQ_END(head) NULL
#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
#define TAILQ_LAST(head, headname) \
(*(((struct headname *)((head)->tqh_last))->tqh_last))
/* XXX */
#define TAILQ_PREV(elm, headname, field) \
(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
#define TAILQ_EMPTY(head) \
(TAILQ_FIRST(head) == TAILQ_END(head))
#define TAILQ_FOREACH(var, head, field) \
for((var) = TAILQ_FIRST(head); \
(var) != TAILQ_END(head); \
(var) = TAILQ_NEXT(var, field))
#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \
for((var) = TAILQ_LAST(head, headname); \
(var) != TAILQ_END(head); \
(var) = TAILQ_PREV(var, headname, field))
/*
* Tail queue functions.
*/
#define TAILQ_INIT(head) do { \
(head)->tqh_first = NULL; \
(head)->tqh_last = &(head)->tqh_first; \
} while (0)
#define TAILQ_INSERT_HEAD(head, elm, field) do { \
if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \
(head)->tqh_first->field.tqe_prev = \
&(elm)->field.tqe_next; \
else \
(head)->tqh_last = &(elm)->field.tqe_next; \
(head)->tqh_first = (elm); \
(elm)->field.tqe_prev = &(head)->tqh_first; \
} while (0)
#define TAILQ_INSERT_TAIL(head, elm, field) do { \
(elm)->field.tqe_next = NULL; \
(elm)->field.tqe_prev = (head)->tqh_last; \
*(head)->tqh_last = (elm); \
(head)->tqh_last = &(elm)->field.tqe_next; \
} while (0)
#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
(elm)->field.tqe_next->field.tqe_prev = \
&(elm)->field.tqe_next; \
else \
(head)->tqh_last = &(elm)->field.tqe_next; \
(listelm)->field.tqe_next = (elm); \
(elm)->field.tqe_prev = &(listelm)->field.tqe_next; \
} while (0)
#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
(elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
(elm)->field.tqe_next = (listelm); \
*(listelm)->field.tqe_prev = (elm); \
(listelm)->field.tqe_prev = &(elm)->field.tqe_next; \
} while (0)
#define TAILQ_REMOVE(head, elm, field) do { \
if (((elm)->field.tqe_next) != NULL) \
(elm)->field.tqe_next->field.tqe_prev = \
(elm)->field.tqe_prev; \
else \
(head)->tqh_last = (elm)->field.tqe_prev; \
*(elm)->field.tqe_prev = (elm)->field.tqe_next; \
_Q_INVALIDATE((elm)->field.tqe_prev); \
_Q_INVALIDATE((elm)->field.tqe_next); \
} while (0)
#define TAILQ_REPLACE(head, elm, elm2, field) do { \
if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != NULL) \
(elm2)->field.tqe_next->field.tqe_prev = \
&(elm2)->field.tqe_next; \
else \
(head)->tqh_last = &(elm2)->field.tqe_next; \
(elm2)->field.tqe_prev = (elm)->field.tqe_prev; \
*(elm2)->field.tqe_prev = (elm2); \
_Q_INVALIDATE((elm)->field.tqe_prev); \
_Q_INVALIDATE((elm)->field.tqe_next); \
} while (0)
/*
* Circular queue definitions.
*/
#define CIRCLEQ_HEAD(name, type) \
struct name { \
struct type *cqh_first; /* first element */ \
struct type *cqh_last; /* last element */ \
}
#define CIRCLEQ_HEAD_INITIALIZER(head) \
{ CIRCLEQ_END(&head), CIRCLEQ_END(&head) }
#define CIRCLEQ_ENTRY(type) \
struct { \
struct type *cqe_next; /* next element */ \
struct type *cqe_prev; /* previous element */ \
}
/*
* Circular queue access methods
*/
#define CIRCLEQ_FIRST(head) ((head)->cqh_first)
#define CIRCLEQ_LAST(head) ((head)->cqh_last)
#define CIRCLEQ_END(head) ((void *)(head))
#define CIRCLEQ_NEXT(elm, field) ((elm)->field.cqe_next)
#define CIRCLEQ_PREV(elm, field) ((elm)->field.cqe_prev)
#define CIRCLEQ_EMPTY(head) \
(CIRCLEQ_FIRST(head) == CIRCLEQ_END(head))
#define CIRCLEQ_FOREACH(var, head, field) \
for((var) = CIRCLEQ_FIRST(head); \
(var) != CIRCLEQ_END(head); \
(var) = CIRCLEQ_NEXT(var, field))
#define CIRCLEQ_FOREACH_REVERSE(var, head, field) \
for((var) = CIRCLEQ_LAST(head); \
(var) != CIRCLEQ_END(head); \
(var) = CIRCLEQ_PREV(var, field))
/*
* Circular queue functions.
*/
#define CIRCLEQ_INIT(head) do { \
(head)->cqh_first = CIRCLEQ_END(head); \
(head)->cqh_last = CIRCLEQ_END(head); \
} while (0)
#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
(elm)->field.cqe_next = (listelm)->field.cqe_next; \
(elm)->field.cqe_prev = (listelm); \
if ((listelm)->field.cqe_next == CIRCLEQ_END(head)) \
(head)->cqh_last = (elm); \
else \
(listelm)->field.cqe_next->field.cqe_prev = (elm); \
(listelm)->field.cqe_next = (elm); \
} while (0)
#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \
(elm)->field.cqe_next = (listelm); \
(elm)->field.cqe_prev = (listelm)->field.cqe_prev; \
if ((listelm)->field.cqe_prev == CIRCLEQ_END(head)) \
(head)->cqh_first = (elm); \
else \
(listelm)->field.cqe_prev->field.cqe_next = (elm); \
(listelm)->field.cqe_prev = (elm); \
} while (0)
#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \
(elm)->field.cqe_next = (head)->cqh_first; \
(elm)->field.cqe_prev = CIRCLEQ_END(head); \
if ((head)->cqh_last == CIRCLEQ_END(head)) \
(head)->cqh_last = (elm); \
else \
(head)->cqh_first->field.cqe_prev = (elm); \
(head)->cqh_first = (elm); \
} while (0)
#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \
(elm)->field.cqe_next = CIRCLEQ_END(head); \
(elm)->field.cqe_prev = (head)->cqh_last; \
if ((head)->cqh_first == CIRCLEQ_END(head)) \
(head)->cqh_first = (elm); \
else \
(head)->cqh_last->field.cqe_next = (elm); \
(head)->cqh_last = (elm); \
} while (0)
#define CIRCLEQ_REMOVE(head, elm, field) do { \
if ((elm)->field.cqe_next == CIRCLEQ_END(head)) \
(head)->cqh_last = (elm)->field.cqe_prev; \
else \
(elm)->field.cqe_next->field.cqe_prev = \
(elm)->field.cqe_prev; \
if ((elm)->field.cqe_prev == CIRCLEQ_END(head)) \
(head)->cqh_first = (elm)->field.cqe_next; \
else \
(elm)->field.cqe_prev->field.cqe_next = \
(elm)->field.cqe_next; \
_Q_INVALIDATE((elm)->field.cqe_prev); \
_Q_INVALIDATE((elm)->field.cqe_next); \
} while (0)
#define CIRCLEQ_REPLACE(head, elm, elm2, field) do { \
if (((elm2)->field.cqe_next = (elm)->field.cqe_next) == \
CIRCLEQ_END(head)) \
(head).cqh_last = (elm2); \
else \
(elm2)->field.cqe_next->field.cqe_prev = (elm2); \
if (((elm2)->field.cqe_prev = (elm)->field.cqe_prev) == \
CIRCLEQ_END(head)) \
(head).cqh_first = (elm2); \
else \
(elm2)->field.cqe_prev->field.cqe_next = (elm2); \
_Q_INVALIDATE((elm)->field.cqe_prev); \
_Q_INVALIDATE((elm)->field.cqe_next); \
} while (0)
#endif /* !_SYS_QUEUE_H_ */

15
third-party/miniupnp/declspec.h vendored Normal file
View File

@@ -0,0 +1,15 @@
#ifndef __DECLSPEC_H__
#define __DECLSPEC_H__
#if defined(WIN32) && !defined(STATICLIB)
#ifdef MINIUPNP_EXPORTS
#define LIBSPEC __declspec(dllexport)
#else
#define LIBSPEC __declspec(dllimport)
#endif
#else
#define LIBSPEC
#endif
#endif

115
third-party/miniupnp/igd_desc_parse.c vendored Normal file
View File

@@ -0,0 +1,115 @@
/* $Id: igd_desc_parse.c,v 1.7 2006/11/19 22:32:33 nanard Exp $ */
/* Project : miniupnp
* http://miniupnp.free.fr/
* Author : Thomas Bernard
* Copyright (c) 2005 Thomas Bernard
* This software is subject to the conditions detailed in the
* LICENCE file provided in this distribution.
* */
#include "igd_desc_parse.h"
#include <stdio.h>
#include <string.h>
/* Start element handler :
* update nesting level counter and copy element name */
void IGDstartelt(void * d, const char * name, int l)
{
struct IGDdatas * datas = (struct IGDdatas *)d;
memcpy( datas->cureltname, name, l);
datas->cureltname[l] = '\0';
datas->level++;
}
/* End element handler :
* update nesting level counter and update parser state if
* service element is parsed */
void IGDendelt(void * d, const char * name, int l)
{
struct IGDdatas * datas = (struct IGDdatas *)d;
datas->level--;
/*printf("endelt %2d %.*s\n", datas->level, l, name);*/
if( (l==7) && !memcmp(name, "service", l) )
{
/*datas->state++; */
/*
if( datas->state < 1
&& !strcmp(datas->servicetype,
// "urn:schemas-upnp-org:service:WANIPConnection:1") )
"urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1"))
datas->state ++;
*/
if(0==strcmp(datas->servicetype_CIF,
"urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1"))
datas->state = 2;
if(0==strcmp(datas->servicetype,
"urn:schemas-upnp-org:service:WANIPConnection:1") )
datas->state = 3;
/* if(0==strcmp(datas->servicetype,
"urn:schemas-upnp-org:service:WANPPPConnection:1") )
datas->state = 4; */
}
}
/* Data handler :
* copy data depending on the current element name and state */
void IGDdata(void * d, const char * data, int l)
{
struct IGDdatas * datas = (struct IGDdatas *)d;
char * dstmember = 0;
/*printf("%2d %s : %.*s\n",
datas->level, datas->cureltname, l, data); */
if( !strcmp(datas->cureltname, "URLBase") )
dstmember = datas->urlbase;
else if(datas->state<=1)
{
if( !strcmp(datas->cureltname, "serviceType") )
dstmember = datas->servicetype_CIF;
else if( !strcmp(datas->cureltname, "controlURL") )
dstmember = datas->controlurl_CIF;
else if( !strcmp(datas->cureltname, "eventSubURL") )
dstmember = datas->eventsuburl_CIF;
else if( !strcmp(datas->cureltname, "SCPDURL") )
dstmember = datas->scpdurl_CIF;
else if( !strcmp(datas->cureltname, "deviceType") )
dstmember = datas->devicetype_CIF;
}
else if(datas->state==2)
{
if( !strcmp(datas->cureltname, "serviceType") )
dstmember = datas->servicetype;
else if( !strcmp(datas->cureltname, "controlURL") )
dstmember = datas->controlurl;
else if( !strcmp(datas->cureltname, "eventSubURL") )
dstmember = datas->eventsuburl;
else if( !strcmp(datas->cureltname, "SCPDURL") )
dstmember = datas->scpdurl;
else if( !strcmp(datas->cureltname, "deviceType") )
dstmember = datas->devicetype;
}
if(dstmember)
{
if(l>=MINIUPNPC_URL_MAXSIZE)
l = MINIUPNPC_URL_MAXSIZE-1;
memcpy(dstmember, data, l);
dstmember[l] = '\0';
}
}
void printIGD(struct IGDdatas * d)
{
printf("urlbase = %s\n", d->urlbase);
printf("WAN Device (Common interface config) :\n");
printf(" deviceType = %s\n", d->devicetype_CIF);
printf(" serviceType = %s\n", d->servicetype_CIF);
printf(" controlURL = %s\n", d->controlurl_CIF);
printf(" eventSubURL = %s\n", d->eventsuburl_CIF);
printf(" SCPDURL = %s\n", d->scpdurl_CIF);
printf("WAN Connection Device :\n");
printf(" deviceType = %s\n", d->devicetype);
printf(" servicetype = %s\n", d->servicetype);
printf(" controlURL = %s\n", d->controlurl);
printf(" eventSubURL = %s\n", d->eventsuburl);
printf(" SCPDURL = %s\n", d->scpdurl);
}

38
third-party/miniupnp/igd_desc_parse.h vendored Normal file
View File

@@ -0,0 +1,38 @@
/* $Id: igd_desc_parse.h,v 1.5 2007/04/11 15:21:09 nanard Exp $ */
/* Project : miniupnp
* http://miniupnp.free.fr/
* Author : Thomas Bernard
* Copyright (c) 2005 Thomas Bernard
* This software is subject to the conditions detailed in the
* LICENCE file provided in this distribution.
* */
#ifndef __IGD_DESC_PARSE_H__
#define __IGD_DESC_PARSE_H__
/* Structure to store the result of the parsing of UPnP
* descriptions of Internet Gateway Devices */
#define MINIUPNPC_URL_MAXSIZE (128)
struct IGDdatas {
char cureltname[MINIUPNPC_URL_MAXSIZE];
char urlbase[MINIUPNPC_URL_MAXSIZE];
int level;
int state;
char controlurl_CIF[MINIUPNPC_URL_MAXSIZE];
char eventsuburl_CIF[MINIUPNPC_URL_MAXSIZE];
char scpdurl_CIF[MINIUPNPC_URL_MAXSIZE];
char servicetype_CIF[MINIUPNPC_URL_MAXSIZE];
char devicetype_CIF[MINIUPNPC_URL_MAXSIZE];
char controlurl[MINIUPNPC_URL_MAXSIZE];
char eventsuburl[MINIUPNPC_URL_MAXSIZE];
char scpdurl[MINIUPNPC_URL_MAXSIZE];
char servicetype[MINIUPNPC_URL_MAXSIZE];
char devicetype[MINIUPNPC_URL_MAXSIZE];
};
void IGDstartelt(void *, const char *, int);
void IGDendelt(void *, const char *, int);
void IGDdata(void *, const char *, int);
void printIGD(struct IGDdatas *);
#endif

77
third-party/miniupnp/minisoap.c vendored Normal file
View File

@@ -0,0 +1,77 @@
/* $Id: minisoap.c,v 1.11 2007/05/19 13:13:08 nanard Exp $ */
/* Project : miniupnp
* Author : Thomas Bernard
* Copyright (c) 2005 Thomas Bernard
* This software is subject to the conditions detailed in the
* LICENCE file provided in this distribution.
*
* Minimal SOAP implementation for UPnP protocol.
*/
#include <stdio.h>
#include <string.h>
#ifdef WIN32
#include <io.h>
#include <winsock2.h>
#define snprintf _snprintf
#else
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#endif
#include "minisoap.h"
/* only for malloc */
#include <stdlib.h>
/* httpWrite sends the headers and the body to the socket
* and returns the number of bytes sent */
static int
httpWrite(int fd, const char * body, int bodysize,
const char * headers, int headerssize)
{
int n = 0;
/*n = write(fd, headers, headerssize);*/
/*if(bodysize>0)
n += write(fd, body, bodysize);*/
/* Note : my old linksys router only took into account
* soap request that are sent into only one packet */
char * p;
p = malloc(headerssize+bodysize);
memcpy(p, headers, headerssize);
memcpy(p+headerssize, body, bodysize);
/*n = write(fd, p, headerssize+bodysize);*/
n = send(fd, p, headerssize+bodysize, 0);
#ifdef WIN32
shutdown(fd, SD_SEND);
#else
shutdown(fd, SHUT_WR); /*SD_SEND*/
#endif
free(p);
return n;
}
/* self explanatory */
int soapPostSubmit(int fd,
const char * url,
const char * host,
unsigned short port,
const char * action,
const char * body)
{
int bodysize;
char headerbuf[1024];
int headerssize;
bodysize = (int)strlen(body);
headerssize = snprintf(headerbuf, sizeof(headerbuf),
"POST %s HTTP/1.1\r\n"
"HOST: %s:%d\r\n"
"Content-length: %d\r\n"
"Content-Type: text/xml\r\n"
"SOAPAction: \"%s\"\r\n"
"Connection: Close\r\n"
"\r\n",
url, host, port, bodysize, action);
return httpWrite(fd, body, bodysize, headerbuf, headerssize);
}

15
third-party/miniupnp/minisoap.h vendored Normal file
View File

@@ -0,0 +1,15 @@
/* $Id: minisoap.h,v 1.3 2006/11/19 22:32:34 nanard Exp $ */
/* Project : miniupnp
* Author : Thomas Bernard
* Copyright (c) 2005 Thomas Bernard
* This software is subject to the conditions detailed in the
* LICENCE file provided in this distribution. */
#ifndef __MINISOAP_H__
#define __MINISOAP_H__
/*int httpWrite(int, const char *, int, const char *);*/
int soapPostSubmit(int, const char *, const char *, unsigned short,
const char *, const char *);
#endif

84
third-party/miniupnp/minissdpc.c vendored Normal file
View File

@@ -0,0 +1,84 @@
/* $Id: minissdpc.c,v 1.3 2007/09/01 23:34:12 nanard Exp $ */
/* Project : miniupnp
* Author : Thomas BERNARD
* copyright (c) 2005-2007 Thomas Bernard
* This software is subjet to the conditions detailed in the
* provided LICENCE file. */
/*#include <syslog.h>*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include "minissdpc.h"
#include "miniupnpc.h"
struct UPNPDev *
getDevicesFromMiniSSDPD(const char * devtype, const char * socketpath)
{
struct UPNPDev * tmp;
struct UPNPDev * devlist = NULL;
unsigned char buffer[512];
ssize_t n;
unsigned char * p;
unsigned int i;
unsigned int urlsize, stsize;
int s;
struct sockaddr_un addr;
s = socket(AF_UNIX, SOCK_STREAM, 0);
if(s < 0)
{
/*syslog(LOG_ERR, "socket(unix): %m");*/
perror("socket(unix)");
return NULL;
}
addr.sun_family = AF_UNIX;
strncpy(addr.sun_path, socketpath, sizeof(addr.sun_path));
if(connect(s, (struct sockaddr *)&addr, sizeof(struct sockaddr_un)) < 0)
{
/*syslog(LOG_WARNING, "connect(\"%s\"): %m", socketpath);*/
close(s);
return NULL;
}
stsize = strlen(devtype);
buffer[0] = 1;
buffer[1] = stsize;
memcpy(buffer + 2, devtype, (int)buffer[1]);
if(write(s, buffer, (int)buffer[1] + 2) < 0)
{
/*syslog(LOG_ERR, "write(): %m");*/
perror("write()");
close(s);
return NULL;
}
n = read(s, buffer, sizeof(buffer));
if(n<=0)
{
close(s);
return NULL;
}
p = buffer + 1;
for(i = 0; i < buffer[0]; i++)
{
urlsize = *(p++);
stsize = p[urlsize];
tmp = (struct UPNPDev *)malloc(sizeof(struct UPNPDev)+urlsize+stsize);
tmp->pNext = devlist;
tmp->descURL = tmp->buffer;
tmp->st = tmp->buffer + 1 + urlsize;
memcpy(tmp->buffer, p, urlsize);
tmp->buffer[urlsize] = '\0';
p += urlsize;
p++;
memcpy(tmp->buffer + urlsize + 1, p, stsize);
tmp->buffer[urlsize+1+stsize] = '\0';
devlist = tmp;
}
close(s);
return devlist;
}

15
third-party/miniupnp/minissdpc.h vendored Normal file
View File

@@ -0,0 +1,15 @@
/* $Id: minissdpc.h,v 1.1 2007/08/31 15:15:33 nanard Exp $ */
/* Project: miniupnp
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
* Author: Thomas Bernard
* Copyright (c) 2005-2007 Thomas Bernard
* This software is subjects to the conditions detailed
* in the LICENCE file provided within this distribution */
#ifndef __MINISSDPC_H__
#define __MINISSDPC_H__
struct UPNPDev *
getDevicesFromMiniSSDPD(const char * devtype, const char * socketpath);
#endif

711
third-party/miniupnp/miniupnpc.c vendored Normal file
View File

@@ -0,0 +1,711 @@
/* $Id: miniupnpc.c,v 1.45 2007/10/16 15:23:44 nanard Exp $ */
/* Project : miniupnp
* Author : Thomas BERNARD
* copyright (c) 2005-2007 Thomas Bernard
* This software is subjet to the conditions detailed in the
* provided LICENCE file. */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef WIN32
#include <winsock2.h>
#include <Ws2tcpip.h>
#include <io.h>
#define snprintf _snprintf
#define strncasecmp memicmp
#define MAXHOSTNAMELEN 64
#else
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/param.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <poll.h>
#include <netdb.h>
#define closesocket close
#endif
#include "miniupnpc.h"
#include "minissdpc.h"
#include "miniwget.h"
#include "minisoap.h"
#include "minixml.h"
#include "upnpcommands.h"
/* Uncomment the following to transmit the msearch from the same port
* as the UPnP multicast port. With WinXP this seems to result in the
* responses to the msearch being lost, thus if things dont work then
* comment this out. */
/* #define TX_FROM_UPNP_PORT */
#ifdef WIN32
#define PRINT_SOCKET_ERROR(x) printf("Socket error: %s, %d\n", x, WSAGetLastError());
#else
#define PRINT_SOCKET_ERROR(x) perror(x)
#endif
/* root description parsing */
void parserootdesc(const char * buffer, int bufsize, struct IGDdatas * data)
{
struct xmlparser parser;
/* xmlparser object */
parser.xmlstart = buffer;
parser.xmlsize = bufsize;
parser.data = data;
parser.starteltfunc = IGDstartelt;
parser.endeltfunc = IGDendelt;
parser.datafunc = IGDdata;
parser.attfunc = 0;
parsexml(&parser);
#ifndef NDEBUG
printIGD(data);
#endif
}
/* Content-length: nnn */
static int getcontentlenfromline(const char * p, int n)
{
static const char contlenstr[] = "content-length";
const char * p2 = contlenstr;
int a = 0;
while(*p2)
{
if(n==0)
return -1;
if(*p2 != *p && *p2 != (*p + 32))
return -1;
p++; p2++; n--;
}
if(n==0)
return -1;
if(*p != ':')
return -1;
p++; n--;
while(*p == ' ')
{
if(n==0)
return -1;
p++; n--;
}
while(*p >= '0' && *p <= '9')
{
if(n==0)
return -1;
a = (a * 10) + (*p - '0');
p++; n--;
}
return a;
}
static void
getContentLengthAndHeaderLength(char * p, int n,
int * contentlen, int * headerlen)
{
char * line;
int linelen;
int r;
line = p;
while(line < p + n)
{
linelen = 0;
while(line[linelen] != '\r' && line[linelen] != '\r')
{
if(line+linelen >= p+n)
return;
linelen++;
}
r = getcontentlenfromline(line, linelen);
if(r>0)
*contentlen = r;
line = line + linelen + 2;
if(line[0] == '\r' && line[1] == '\n')
{
*headerlen = (line - p) + 2;
return;
}
}
}
/* simpleUPnPcommand :
* not so simple !
* */
int simpleUPnPcommand(int s, const char * url, const char * service,
const char * action, struct UPNParg * args,
char * buffer, int * bufsize)
{
struct sockaddr_in dest;
char hostname[MAXHOSTNAMELEN+1];
unsigned short port = 0;
char * path;
char soapact[128];
char soapbody[2048];
int soapbodylen;
char * buf;
int buffree;
int n;
int contentlen, headerlen; /* for the response */
snprintf(soapact, sizeof(soapact), "%s#%s", service, action);
if(args==NULL)
{
soapbodylen = snprintf(soapbody, sizeof(soapbody),
"<?xml version=\"1.0\"?>\r\n"
"<SOAP-ENV:Envelope "
"xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" "
"SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">"
"<SOAP-ENV:Body>"
"<m:%s xmlns:m=\"%s\"/>"
"</SOAP-ENV:Body></SOAP-ENV:Envelope>"
"\r\n", action, service);
}
else
{
char * p;
const char * pe, * pv;
soapbodylen = snprintf(soapbody, sizeof(soapbody),
"<?xml version=\"1.0\"?>\r\n"
"<SOAP-ENV:Envelope "
"xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" "
"SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">"
"<SOAP-ENV:Body>"
"<m:%s xmlns:m=\"%s\">",
action, service);
p = soapbody + soapbodylen;
while(args->elt)
{
/* check that we are never overflowing the string... */
if(soapbody + sizeof(soapbody) <= p + 100)
{
/* we keep a margin of at least 100 bytes */
*bufsize = 0;
return -1;
}
*(p++) = '<';
pe = args->elt;
while(*pe)
*(p++) = *(pe++);
*(p++) = '>';
if((pv = args->val))
{
while(*pv)
*(p++) = *(pv++);
}
*(p++) = '<';
*(p++) = '/';
pe = args->elt;
while(*pe)
*(p++) = *(pe++);
*(p++) = '>';
args++;
}
*(p++) = '<';
*(p++) = '/';
*(p++) = 'm';
*(p++) = ':';
pe = action;
while(*pe)
*(p++) = *(pe++);
strncpy(p, "></SOAP-ENV:Body></SOAP-ENV:Envelope>\r\n",
soapbody + sizeof(soapbody) - p);
}
if(!parseURL(url, hostname, &port, &path)) return -1;
if(s<0)
{
s = socket(PF_INET, SOCK_STREAM, 0);
dest.sin_family = AF_INET;
dest.sin_port = htons(port);
dest.sin_addr.s_addr = inet_addr(hostname);
if(connect(s, (struct sockaddr *)&dest, sizeof(struct sockaddr))<0)
{
PRINT_SOCKET_ERROR("connect");
*bufsize = 0;
return -1;
}
}
n = soapPostSubmit(s, path, hostname, port, soapact, soapbody);
contentlen = -1;
headerlen = -1;
buf = buffer;
buffree = *bufsize;
*bufsize = 0;
while ((n = ReceiveData(s, buf, buffree, 5000)) > 0) {
buffree -= n;
buf += n;
*bufsize += n;
getContentLengthAndHeaderLength(buffer, *bufsize,
&contentlen, &headerlen);
#ifdef DEBUG
printf("n=%d bufsize=%d ContLen=%d HeadLen=%d\n",
n, *bufsize, contentlen, headerlen);
#endif
if(contentlen > 0 && headerlen > 0 && *bufsize >= contentlen+headerlen)
break;
}
closesocket(s);
return -1;
}
/* parseMSEARCHReply()
* the last 4 arguments are filled during the parsing :
* - location/locationsize : "location:" field of the SSDP reply packet
* - st/stsize : "st:" field of the SSDP reply packet.
* The strings are NOT null terminated */
static void
parseMSEARCHReply(const char * reply, int size,
const char * * location, int * locationsize,
const char * * st, int * stsize)
{
int a, b, i;
i = 0;
a = i; /* start of the line */
b = 0;
while(i<size)
{
switch(reply[i])
{
case ':':
if(b==0)
{
b = i; /* end of the "header" */
/*for(j=a; j<b; j++)
{
putchar(reply[j]);
}
*/
}
break;
case '\x0a':
case '\x0d':
if(b!=0)
{
/*for(j=b+1; j<i; j++)
{
putchar(reply[j]);
}
putchar('\n');*/
do { b++; } while(reply[b]==' ');
if(0==strncasecmp(reply+a, "location", 8))
{
*location = reply+b;
*locationsize = i-b;
}
else if(0==strncasecmp(reply+a, "st", 2))
{
*st = reply+b;
*stsize = i-b;
}
b = 0;
}
a = i+1;
break;
default:
break;
}
i++;
}
}
/* port upnp discover : SSDP protocol */
#define PORT (1900)
#define UPNP_MCAST_ADDR "239.255.255.250"
/* upnpDiscover() :
* return a chained list of all devices found or NULL if
* no devices was found.
* It is up to the caller to free the chained list
* delay is in millisecond (poll) */
struct UPNPDev * upnpDiscover(int delay, const char * multicastif)
{
struct UPNPDev * tmp;
struct UPNPDev * devlist = 0;
int opt = 1;
static const char MSearchMsgFmt[] =
"M-SEARCH * HTTP/1.1\r\n"
"HOST: " UPNP_MCAST_ADDR ":" "1900" "\r\n"
"ST: %s\r\n"
"MAN: \"ssdp:discover\"\r\n"
"MX: 3\r\n"
"\r\n";
static const char * const deviceList[] = {
"urn:schemas-upnp-org:device:InternetGatewayDevice:1",
"urn:schemas-upnp-org:service:WANIPConnection:1",
"urn:schemas-upnp-org:service:WANPPPConnection:1",
"upnp:rootdevice",
0
};
int deviceIndex = 0;
char bufr[1536]; /* reception and emission buffer */
int sudp;
int n;
struct sockaddr_in sockudp_r, sockudp_w;
#ifndef WIN32
/* first try to get infos from minissdpd ! */
devlist = getDevicesFromMiniSSDPD(deviceList[0], "/var/run/minissdpd.sock");
if(devlist)
return devlist;
#endif
/* fallback to direct discovery */
#ifdef WIN32
sudp = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
#else
sudp = socket(PF_INET, SOCK_DGRAM, 0);
#endif
if(sudp < 0)
{
PRINT_SOCKET_ERROR("socket");
return NULL;
}
/* reception */
memset(&sockudp_r, 0, sizeof(struct sockaddr_in));
sockudp_r.sin_family = AF_INET;
#ifdef TX_FROM_UPNP_PORT
sockudp_r.sin_port = htons(PORT);
#endif
sockudp_r.sin_addr.s_addr = INADDR_ANY;
/* emission */
memset(&sockudp_w, 0, sizeof(struct sockaddr_in));
sockudp_w.sin_family = AF_INET;
sockudp_w.sin_port = htons(PORT);
sockudp_w.sin_addr.s_addr = inet_addr(UPNP_MCAST_ADDR);
#ifdef WIN32
if (setsockopt(sudp, SOL_SOCKET, SO_REUSEADDR, (const char *)&opt, sizeof (opt)) < 0)
#else
if (setsockopt(sudp, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof (opt)) < 0)
#endif
{
PRINT_SOCKET_ERROR("setsockopt");
return NULL;
}
if(multicastif)
{
struct in_addr mc_if;
mc_if.s_addr = inet_addr(multicastif);
sockudp_r.sin_addr.s_addr = mc_if.s_addr;
if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&mc_if, sizeof(mc_if)) < 0)
{
PRINT_SOCKET_ERROR("setsockopt");
}
}
/* Avant d'envoyer le paquet on bind pour recevoir la reponse */
if (bind(sudp, (struct sockaddr *)&sockudp_r, sizeof(struct sockaddr_in)) != 0)
{
PRINT_SOCKET_ERROR("bind");
closesocket(sudp);
return NULL;
}
/* receiving SSDP response packet */
for(n = 0;;)
{
if(n == 0)
{
/* sending the SSDP M-SEARCH packet */
n = snprintf(bufr, sizeof(bufr),
MSearchMsgFmt, deviceList[deviceIndex++]);
/*printf("Sending %s", bufr);*/
n = sendto(sudp, bufr, n, 0,
(struct sockaddr *)&sockudp_w, sizeof(struct sockaddr_in));
if (n < 0) {
PRINT_SOCKET_ERROR("sendto");
closesocket(sudp);
return devlist;
}
}
/* Waiting for SSDP REPLY packet to M-SEARCH */
n = ReceiveData(sudp, bufr, sizeof(bufr), delay);
if (n < 0) {
/* error */
closesocket(sudp);
return devlist;
} else if (n == 0) {
/* no data or Time Out */
if (devlist || (deviceList[deviceIndex] == 0)) {
/* no more device type to look for... */
closesocket(sudp);
return devlist;
}
} else {
const char * descURL=NULL;
int urlsize=0;
const char * st=NULL;
int stsize=0;
/*printf("%d byte(s) :\n%s\n", n, bufr);*/ /* affichage du message */
parseMSEARCHReply(bufr, n, &descURL, &urlsize, &st, &stsize);
if(st&&descURL)
{
/*printf("M-SEARCH Reply:\nST: %.*s\nLocation: %.*s\n",
stsize, st, urlsize, descURL); */
tmp = (struct UPNPDev *)malloc(sizeof(struct UPNPDev)+urlsize+stsize);
tmp->pNext = devlist;
tmp->descURL = tmp->buffer;
tmp->st = tmp->buffer + 1 + urlsize;
memcpy(tmp->buffer, descURL, urlsize);
tmp->buffer[urlsize] = '\0';
memcpy(tmp->buffer + urlsize + 1, st, stsize);
tmp->buffer[urlsize+1+stsize] = '\0';
devlist = tmp;
}
}
}
}
/* freeUPNPDevlist() should be used to
* free the chained list returned by upnpDiscover() */
void freeUPNPDevlist(struct UPNPDev * devlist)
{
struct UPNPDev * next;
while(devlist)
{
next = devlist->pNext;
free(devlist);
devlist = next;
}
}
static void
url_cpy_or_cat(char * dst, const char * src, int n)
{
if( (src[0] == 'h')
&&(src[1] == 't')
&&(src[2] == 't')
&&(src[3] == 'p')
&&(src[4] == ':')
&&(src[5] == '/')
&&(src[6] == '/'))
{
strncpy(dst, src, n);
}
else
{
int l = strlen(dst);
if(src[0] != '/')
dst[l++] = '/';
if(l<=n)
strncpy(dst + l, src, n - l);
}
}
/* Prepare the Urls for usage...
*/
void GetUPNPUrls(struct UPNPUrls * urls, struct IGDdatas * data,
const char * descURL)
{
char * p;
int n1, n2, n3;
n1 = strlen(data->urlbase);
if(n1==0)
n1 = strlen(descURL);
n1 += 2; /* 1 byte more for Null terminator, 1 byte for '/' if needed */
n2 = n1; n3 = n1;
n1 += strlen(data->scpdurl);
n2 += strlen(data->controlurl);
n3 += strlen(data->controlurl_CIF);
urls->ipcondescURL = (char *)malloc(n1);
urls->controlURL = (char *)malloc(n2);
urls->controlURL_CIF = (char *)malloc(n3);
/* maintenant on chope la desc du WANIPConnection */
if(data->urlbase[0] != '\0')
strncpy(urls->ipcondescURL, data->urlbase, n1);
else
strncpy(urls->ipcondescURL, descURL, n1);
p = strchr(urls->ipcondescURL+7, '/');
if(p) p[0] = '\0';
strncpy(urls->controlURL, urls->ipcondescURL, n2);
strncpy(urls->controlURL_CIF, urls->ipcondescURL, n3);
url_cpy_or_cat(urls->ipcondescURL, data->scpdurl, n1);
url_cpy_or_cat(urls->controlURL, data->controlurl, n2);
url_cpy_or_cat(urls->controlURL_CIF, data->controlurl_CIF, n3);
#ifdef DEBUG
printf("urls->ipcondescURL='%s' %d n1=%d\n", urls->ipcondescURL,
strlen(urls->ipcondescURL), n1);
printf("urls->controlURL='%s' %d n2=%d\n", urls->controlURL,
strlen(urls->controlURL), n2);
printf("urls->controlURL_CIF='%s' %d n3=%d\n", urls->controlURL_CIF,
strlen(urls->controlURL_CIF), n3);
#endif
}
void
FreeUPNPUrls(struct UPNPUrls * urls)
{
if(!urls)
return;
free(urls->controlURL);
urls->controlURL = 0;
free(urls->ipcondescURL);
urls->ipcondescURL = 0;
free(urls->controlURL_CIF);
urls->controlURL_CIF = 0;
}
int ReceiveData(int socket, char * data, int length, int timeout)
{
int n;
#ifndef WIN32
struct pollfd fds[1]; /* for the poll */
fds[0].fd = socket;
fds[0].events = POLLIN;
n = poll(fds, 1, timeout);
if(n < 0)
{
PRINT_SOCKET_ERROR("poll");
return -1;
}
else if(n == 0)
{
return 0;
}
#else
fd_set socketSet;
TIMEVAL timeval;
FD_ZERO(&socketSet);
FD_SET(socket, &socketSet);
timeval.tv_sec = timeout / 1000;
timeval.tv_usec = (timeout % 1000) * 1000;
n = select(0, &socketSet, NULL, NULL, &timeval);
if(n < 0)
{
PRINT_SOCKET_ERROR("select");
return -1;
}
else if(n == 0)
{
return 0;
}
#endif
n = recv(socket, data, length, 0);
if(n<0)
{
PRINT_SOCKET_ERROR("recv");
}
return n;
}
int
UPNPIGD_IsConnected(struct UPNPUrls * urls, struct IGDdatas * data)
{
char status[64];
unsigned int uptime;
status[0] = '\0';
UPNP_GetStatusInfo(urls->controlURL, data->servicetype, status, &uptime);
if(0 == strcmp("Connected", status))
{
return 1;
}
else
return 0;
}
/* UPNP_GetValidIGD() :
* return values :
* 0 = NO IGD found
* 1 = A valid connected IGD has been found
* 2 = A valid IGD has been found but it reported as
* not connected
* 3 = an UPnP device has been found but was not recognized as an IGD
*
* In any non zero return case, the urls and data structures
* passed as parameters are set. Donc forget to call FreeUPNPUrls(urls) to
* free allocated memory.
*/
int
UPNP_GetValidIGD(struct UPNPDev * devlist,
struct UPNPUrls * urls,
struct IGDdatas * data,
char * lanaddr, int lanaddrlen)
{
char * descXML;
int descXMLsize = 0;
struct UPNPDev * dev;
int ndev = 0;
int state; /* state 1 : IGD connected. State 2 : IGD. State 3 : anything */
if(!devlist)
{
#ifdef DEBUG
printf("Empty devlist\n");
#endif
return 0;
}
for(state = 1; state <= 3; state++)
{
for(dev = devlist; dev; dev = dev->pNext)
{
/* we should choose an internet gateway device.
* with st == urn:schemas-upnp-org:device:InternetGatewayDevice:1 */
if((state >= 3) || strstr(dev->st, "InternetGatewayDevice"))
{
descXML = miniwget_getaddr(dev->descURL, &descXMLsize,
lanaddr, lanaddrlen);
if(descXML)
{
ndev++;
memset(data, 0, sizeof(struct IGDdatas));
memset(urls, 0, sizeof(struct UPNPUrls));
parserootdesc(descXML, descXMLsize, data);
free(descXML);
descXML = NULL;
GetUPNPUrls(urls, data, dev->descURL);
#ifdef DEBUG
printf("UPNPIGD_IsConnected(%s) = %d\n",
urls->controlURL,
UPNPIGD_IsConnected(urls, data));
#endif
if((state >= 2) || UPNPIGD_IsConnected(urls, data))
return state;
FreeUPNPUrls(urls);
memset(data, 0, sizeof(struct IGDdatas));
}
#ifdef DEBUG
else
{
printf("error getting XML description %s\n", dev->descURL);
}
#endif
}
}
}
return 0;
}
/* UPNP_GetIGDFromUrl()
* Used when skipping the discovery process.
* return value :
* 0 - Not ok
* 1 - OK */
int
UPNP_GetIGDFromUrl(const char * rootdescurl,
struct UPNPUrls * urls,
struct IGDdatas * data,
char * lanaddr, int lanaddrlen)
{
char * descXML;
int descXMLsize = 0;
descXML = miniwget_getaddr(rootdescurl, &descXMLsize,
lanaddr, lanaddrlen);
if(descXML) {
memset(data, 0, sizeof(struct IGDdatas));
memset(urls, 0, sizeof(struct UPNPUrls));
parserootdesc(descXML, descXMLsize, data);
free(descXML);
descXML = NULL;
GetUPNPUrls(urls, data, rootdescurl);
return 1;
} else {
return 0;
}
}

92
third-party/miniupnp/miniupnpc.h vendored Normal file
View File

@@ -0,0 +1,92 @@
/* $Id: miniupnpc.h,v 1.15 2007/10/16 15:07:32 nanard Exp $ */
/* Project: miniupnp
* http://miniupnp.free.fr/
* Author: Thomas Bernard
* Copyright (c) 2005-2006 Thomas Bernard
* This software is subjects to the conditions detailed
* in the LICENCE file provided within this distribution */
#ifndef __MINIUPNPC_H__
#define __MINIUPNPC_H__
#include "declspec.h"
#include "igd_desc_parse.h"
#ifdef __cplusplus
extern "C" {
#endif
struct UPNParg { const char * elt; const char * val; };
int simpleUPnPcommand(int, const char *, const char *,
const char *, struct UPNParg *,
char *, int *);
struct UPNPDev {
struct UPNPDev * pNext;
char * descURL;
char * st;
char buffer[2];
};
/* discover UPnP devices on the network */
LIBSPEC struct UPNPDev * upnpDiscover(int delay, const char * multicastif);
/* free returned list from above function */
LIBSPEC void freeUPNPDevlist(struct UPNPDev * devlist);
LIBSPEC void parserootdesc(const char *, int, struct IGDdatas *);
/* structure used to get fast access to urls
* controlURL: controlURL of the WANIPConnection
* ipcondescURL: url of the description of the WANIPConnection
* controlURL_CIF: controlURL of the WANCOmmonInterfaceConfig
*/
struct UPNPUrls {
char * controlURL;
char * ipcondescURL;
char * controlURL_CIF;
};
/* UPNP_GetValidIGD() :
* return values :
* 0 = NO IGD found
* 1 = A valid connected IGD has been found
* 2 = A valid IGD has been found but it reported as
* not connected
* 3 = an UPnP device has been found but was not recognized as an IGD
*
* In any non zero return case, the urls and data structures
* passed as parameters are set. Donc forget to call FreeUPNPUrls(urls) to
* free allocated memory.
*/
LIBSPEC int
UPNP_GetValidIGD(struct UPNPDev * devlist,
struct UPNPUrls * urls,
struct IGDdatas * data,
char * lanaddr, int lanaddrlen);
/* UPNP_GetIGDFromUrl()
* Used when skipping the discovery process.
* return value :
* 0 - Not ok
* 1 - OK */
LIBSPEC int
UPNP_GetIGDFromUrl(const char * rootdescurl,
struct UPNPUrls * urls,
struct IGDdatas * data,
char * lanaddr, int lanaddrlen);
LIBSPEC void GetUPNPUrls(struct UPNPUrls *, struct IGDdatas *, const char *);
LIBSPEC void FreeUPNPUrls(struct UPNPUrls *);
/* Reads data from the specified socket.
* Returns the number of bytes read if successful, zero if no bytes were
* read or if we timed out. Returns negative if there was an error. */
int ReceiveData(int socket, char * data, int length, int timeout);
#ifdef __cplusplus
}
#endif
#endif

219
third-party/miniupnp/miniwget.c vendored Normal file
View File

@@ -0,0 +1,219 @@
/* $Id: miniwget.c,v 1.19 2007/11/02 14:16:19 nanard Exp $ */
/* Project : miniupnp
* Author : Thomas Bernard
* Copyright (c) 2005 Thomas Bernard
* This software is subject to the conditions detailed in the
* LICENCE file provided in this distribution.
* */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "miniupnpc.h"
#ifdef WIN32
#include <winsock2.h>
#include <io.h>
#define MAXHOSTNAMELEN 64
#define MIN(x,y) (((x)<(y))?(x):(y))
#define snprintf _snprintf
#define herror
#define socklen_t int
#else
#include <unistd.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define closesocket close
#endif
/* for MIN() macro : */
#if defined(__sun) || defined(sun)
#include <utility.h>
#endif
/* miniwget2() :
* */
static void *
miniwget2(const char * url, const char * host,
unsigned short port, const char * path,
int * size, char * addr_str, int addr_str_len)
{
char buf[2048];
int s;
struct sockaddr_in dest;
struct hostent *hp;
*size = 0;
hp = gethostbyname(host);
if(hp==NULL)
{
herror(host);
return NULL;
}
/* memcpy((char *)&dest.sin_addr, hp->h_addr, hp->h_length); */
memcpy(&dest.sin_addr, hp->h_addr, sizeof(dest.sin_addr));
memset(dest.sin_zero, 0, sizeof(dest.sin_zero));
s = socket(PF_INET, SOCK_STREAM, 0);
if(s < 0)
{
perror("socket");
return NULL;
}
dest.sin_family = AF_INET;
dest.sin_port = htons(port);
if(connect(s, (struct sockaddr *)&dest, sizeof(struct sockaddr_in))<0)
{
perror("connect");
closesocket(s);
return NULL;
}
/* get address for caller ! */
if(addr_str)
{
struct sockaddr_in saddr;
socklen_t len;
len = sizeof(saddr);
getsockname(s, (struct sockaddr *)&saddr, &len);
#ifndef WIN32
inet_ntop(AF_INET, &saddr.sin_addr, addr_str, addr_str_len);
#else
/* using INT WINAPI WSAAddressToStringA(LPSOCKADDR, DWORD, LPWSAPROTOCOL_INFOA, LPSTR, LPDWORD);
* But his function make a string with the port : nn.nn.nn.nn:port */
/* if(WSAAddressToStringA((SOCKADDR *)&saddr, sizeof(saddr),
NULL, addr_str, (DWORD *)&addr_str_len))
{
printf("WSAAddressToStringA() failed : %d\n", WSAGetLastError());
}*/
strncpy(addr_str, inet_ntoa(saddr.sin_addr), addr_str_len);
#endif
#ifdef DEBUG
printf("address miniwget : %s\n", addr_str);
#endif
}
snprintf(buf, sizeof(buf),
"GET %s HTTP/1.1\r\n"
"Host: %s:%d\r\n"
"Connection: Close\r\n"
"\r\n",
path, host, port);
/*write(s, buf, strlen(buf));*/
send(s, buf, strlen(buf), 0);
{
int n, headers=1;
char * respbuffer = NULL;
int allreadyread = 0;
/*while((n = recv(s, buf, 2048, 0)) > 0)*/
while((n = ReceiveData(s, buf, 2048, 5000)) > 0)
{
if(headers)
{
int i=0;
while(i<n-3)
{
if(buf[i]=='\r' && buf[i+1]=='\n'
&& buf[i+2]=='\r' && buf[i+3]=='\n')
{
headers = 0; /* end */
if(i<n-4)
{
respbuffer = (char *)realloc((void *)respbuffer,
allreadyread+(n-i-4));
memcpy(respbuffer+allreadyread, buf + i + 4, n-i-4);
allreadyread += (n-i-4);
}
break;
}
i++;
}
}
else
{
respbuffer = (char *)realloc((void *)respbuffer,
allreadyread+n);
memcpy(respbuffer+allreadyread, buf, n);
allreadyread += n;
}
}
*size = allreadyread;
#ifndef NDEBUG
printf("%d bytes read\n", *size);
#endif
closesocket(s);
return respbuffer;
}
}
/* parseURL()
* arguments :
* url : source string not modified
* hostname : hostname destination string (size of MAXHOSTNAMELEN+1)
* port : port (destination)
* path : pointer to the path part of the URL
*
* Return values :
* 0 - Failure
* 1 - Success */
int parseURL(const char * url, char * hostname, unsigned short * port, char * * path)
{
char * p1, *p2, *p3;
p1 = strstr(url, "://");
if(!p1)
return 0;
p1 += 3;
if( (url[0]!='h') || (url[1]!='t')
||(url[2]!='t') || (url[3]!='p'))
return 0;
p2 = strchr(p1, ':');
p3 = strchr(p1, '/');
if(!p3)
return 0;
memset(hostname, 0, MAXHOSTNAMELEN + 1);
if(!p2 || (p2>p3))
{
strncpy(hostname, p1, MIN(MAXHOSTNAMELEN, (int)(p3-p1)));
*port = 80;
}
else
{
strncpy(hostname, p1, MIN(MAXHOSTNAMELEN, (int)(p2-p1)));
*port = 0;
p2++;
while( (*p2 >= '0') && (*p2 <= '9'))
{
*port *= 10;
*port += (unsigned short)(*p2 - '0');
p2++;
}
}
*path = p3;
return 1;
}
void * miniwget(const char * url, int * size)
{
unsigned short port;
char * path;
/* protocol://host:port/chemin */
char hostname[MAXHOSTNAMELEN+1];
*size = 0;
if(!parseURL(url, hostname, &port, &path))
return NULL;
return miniwget2(url, hostname, port, path, size, 0, 0);
}
void * miniwget_getaddr(const char * url, int * size, char * addr, int addrlen)
{
unsigned short port;
char * path;
/* protocol://host:port/chemin */
char hostname[MAXHOSTNAMELEN+1];
*size = 0;
if(addr)
addr[0] = '\0';
if(!parseURL(url, hostname, &port, &path))
return NULL;
return miniwget2(url, hostname, port, path, size, addr, addrlen);
}

28
third-party/miniupnp/miniwget.h vendored Normal file
View File

@@ -0,0 +1,28 @@
/* $Id: miniwget.h,v 1.5 2007/01/29 20:27:23 nanard Exp $ */
/* Project : miniupnp
* Author : Thomas Bernard
* Copyright (c) 2005 Thomas Bernard
* This software is subject to the conditions detailed in the
* LICENCE file provided in this distribution.
* */
#ifndef __MINIWGET_H__
#define __MINIWGET_H__
#include "declspec.h"
#ifdef __cplusplus
extern "C" {
#endif
LIBSPEC void * miniwget(const char *, int *);
LIBSPEC void * miniwget_getaddr(const char *, int *, char *, int);
int parseURL(const char *, char *, unsigned short *, char * *);
#ifdef __cplusplus
}
#endif
#endif

191
third-party/miniupnp/minixml.c vendored Normal file
View File

@@ -0,0 +1,191 @@
/* $Id: minixml.c,v 1.6 2007/05/15 18:14:08 nanard Exp $ */
/* minixml.c : the minimum size a xml parser can be ! */
/* Project : miniupnp
* webpage: http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
* Author : Thomas Bernard
Copyright (c) 2005-2007, Thomas BERNARD
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
#include "minixml.h"
/* parseatt : used to parse the argument list
* return 0 (false) in case of success and -1 (true) if the end
* of the xmlbuffer is reached. */
int parseatt(struct xmlparser * p)
{
const char * attname;
int attnamelen;
const char * attvalue;
int attvaluelen;
while(p->xml < p->xmlend)
{
if(*p->xml=='/' || *p->xml=='>')
return 0;
if( !IS_WHITE_SPACE(*p->xml) )
{
char sep;
attname = p->xml;
attnamelen = 0;
while(*p->xml!='=' && !IS_WHITE_SPACE(*p->xml) )
{
attnamelen++; p->xml++;
if(p->xml >= p->xmlend)
return -1;
}
while(*(p->xml++) != '=')
{
if(p->xml >= p->xmlend)
return -1;
}
while(IS_WHITE_SPACE(*p->xml))
{
p->xml++;
if(p->xml >= p->xmlend)
return -1;
}
sep = *p->xml;
if(sep=='\'' || sep=='\"')
{
p->xml++;
if(p->xml >= p->xmlend)
return -1;
attvalue = p->xml;
attvaluelen = 0;
while(*p->xml != sep)
{
attvaluelen++; p->xml++;
if(p->xml >= p->xmlend)
return -1;
}
}
else
{
attvalue = p->xml;
attvaluelen = 0;
while( !IS_WHITE_SPACE(*p->xml)
&& *p->xml != '>' && *p->xml != '/')
{
attvaluelen++; p->xml++;
if(p->xml >= p->xmlend)
return -1;
}
}
/*printf("%.*s='%.*s'\n",
attnamelen, attname, attvaluelen, attvalue);*/
if(p->attfunc)
p->attfunc(p->data, attname, attnamelen, attvalue, attvaluelen);
}
p->xml++;
}
return -1;
}
/* parseelt parse the xml stream and
* call the callback functions when needed... */
void parseelt(struct xmlparser * p)
{
int i;
const char * elementname;
while(p->xml < (p->xmlend - 1))
{
if((p->xml)[0]=='<' && (p->xml)[1]!='?')
{
i = 0; elementname = ++p->xml;
while( !IS_WHITE_SPACE(*p->xml)
&& (*p->xml!='>') && (*p->xml!='/')
)
{
i++; p->xml++;
if (p->xml >= p->xmlend)
return;
/* to ignore namespace : */
if(*p->xml==':')
{
i = 0;
elementname = ++p->xml;
}
}
if(i>0)
{
if(p->starteltfunc)
p->starteltfunc(p->data, elementname, i);
if(parseatt(p))
return;
if(*p->xml!='/')
{
const char * data;
i = 0; data = ++p->xml;
if (p->xml >= p->xmlend)
return;
while( IS_WHITE_SPACE(*p->xml) )
{
p->xml++;
if (p->xml >= p->xmlend)
return;
}
while(*p->xml!='<')
{
i++; p->xml++;
if (p->xml >= p->xmlend)
return;
}
if(i>0 && p->datafunc)
p->datafunc(p->data, data, i);
}
}
else if(*p->xml == '/')
{
i = 0; elementname = ++p->xml;
if (p->xml >= p->xmlend)
return;
while((*p->xml != '>'))
{
i++; p->xml++;
if (p->xml >= p->xmlend)
return;
}
if(p->endeltfunc)
p->endeltfunc(p->data, elementname, i);
p->xml++;
}
}
else
{
p->xml++;
}
}
}
/* the parser must be initialized before calling this function */
void parsexml(struct xmlparser * parser)
{
parser->xml = parser->xmlstart;
parser->xmlend = parser->xmlstart + parser->xmlsize;
parseelt(parser);
}

37
third-party/miniupnp/minixml.h vendored Normal file
View File

@@ -0,0 +1,37 @@
/* $Id: minixml.h,v 1.6 2006/11/30 11:47:21 nanard Exp $ */
/* minimal xml parser
*
* Project : miniupnp
* Website : http://miniupnp.free.fr/
* Author : Thomas Bernard
* Copyright (c) 2005 Thomas Bernard
* This software is subject to the conditions detailed in the
* LICENCE file provided in this distribution.
* */
#ifndef __MINIXML_H__
#define __MINIXML_H__
#define IS_WHITE_SPACE(c) ((c==' ') || (c=='\t') || (c=='\r') || (c=='\n'))
/* if a callback function pointer is set to NULL,
* the function is not called */
struct xmlparser {
const char *xmlstart;
const char *xmlend;
const char *xml; /* pointer to current character */
int xmlsize;
void * data;
void (*starteltfunc) (void *, const char *, int);
void (*endeltfunc) (void *, const char *, int);
void (*datafunc) (void *, const char *, int);
void (*attfunc) (void *, const char *, int, const char *, int);
};
/* parsexml()
* the xmlparser structure must be initialized before the call
* the following structure members have to be initialized :
* xmlstart, xmlsize, data, *func
* xml is for internal usage, xmlend is computed automatically */
void parsexml(struct xmlparser *);
#endif

486
third-party/miniupnp/upnpcommands.c vendored Normal file
View File

@@ -0,0 +1,486 @@
/* $Id: upnpcommands.c,v 1.16 2007/08/03 14:11:42 nanard Exp $ */
/* Project : miniupnp
* Author : Thomas Bernard
* Copyright (c) 2005 Thomas Bernard
* This software is subject to the conditions detailed in the
* LICENCE file provided in this distribution.
* */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "upnpcommands.h"
#include "miniupnpc.h"
static unsigned int
my_atoui(const char * s)
{
return (unsigned int)strtoul(s, NULL, 0);
}
/*
* */
unsigned int
UPNP_GetTotalBytesSent(const char * controlURL,
const char * servicetype)
{
struct NameValueParserData pdata;
char buffer[4096];
int bufsize = 4096;
unsigned int r = 0;
char * p;
simpleUPnPcommand(-1, controlURL, servicetype, "GetTotalBytesSent", 0, buffer, &bufsize);
ParseNameValue(buffer, bufsize, &pdata);
/*DisplayNameValueList(buffer, bufsize);*/
p = GetValueFromNameValueList(&pdata, "NewTotalBytesSent");
if(p)
r = my_atoui(p);
ClearNameValueList(&pdata);
return r;
}
/*
* */
unsigned int
UPNP_GetTotalBytesReceived(const char * controlURL,
const char * servicetype)
{
struct NameValueParserData pdata;
char buffer[4096];
int bufsize = 4096;
unsigned int r = 0;
char * p;
simpleUPnPcommand(-1, controlURL, servicetype, "GetTotalBytesReceived", 0, buffer, &bufsize);
ParseNameValue(buffer, bufsize, &pdata);
/*DisplayNameValueList(buffer, bufsize);*/
p = GetValueFromNameValueList(&pdata, "NewTotalBytesReceived");
if(p)
r = my_atoui(p);
ClearNameValueList(&pdata);
return r;
}
/*
* */
unsigned int
UPNP_GetTotalPacketsSent(const char * controlURL,
const char * servicetype)
{
struct NameValueParserData pdata;
char buffer[4096];
int bufsize = 4096;
unsigned int r = 0;
char * p;
simpleUPnPcommand(-1, controlURL, servicetype, "GetTotalPacketsSent", 0, buffer, &bufsize);
ParseNameValue(buffer, bufsize, &pdata);
/*DisplayNameValueList(buffer, bufsize);*/
p = GetValueFromNameValueList(&pdata, "NewTotalPacketsSent");
if(p)
r = my_atoui(p);
ClearNameValueList(&pdata);
return r;
}
/*
* */
unsigned int
UPNP_GetTotalPacketsReceived(const char * controlURL,
const char * servicetype)
{
struct NameValueParserData pdata;
char buffer[4096];
int bufsize = 4096;
unsigned int r = 0;
char * p;
simpleUPnPcommand(-1, controlURL, servicetype, "GetTotalPacketsReceived", 0, buffer, &bufsize);
ParseNameValue(buffer, bufsize, &pdata);
/*DisplayNameValueList(buffer, bufsize);*/
p = GetValueFromNameValueList(&pdata, "NewTotalPacketsReceived");
if(p)
r = my_atoui(p);
ClearNameValueList(&pdata);
return r;
}
/* UPNP_GetStatusInfo() call the corresponding UPNP method
* returns the current status and uptime */
void UPNP_GetStatusInfo(const char * controlURL,
const char * servicetype,
char * status,
unsigned int * uptime)
{
struct NameValueParserData pdata;
char buffer[4096];
int bufsize = 4096;
char * p;
char* up;
if(!status && !uptime)
return;
simpleUPnPcommand(-1, controlURL, servicetype, "GetStatusInfo", 0, buffer, &bufsize);
ParseNameValue(buffer, bufsize, &pdata);
/*DisplayNameValueList(buffer, bufsize);*/
up = GetValueFromNameValueList(&pdata, "NewUptime");
p = GetValueFromNameValueList(&pdata, "NewConnectionStatus");
if(status)
{
if(p){
strncpy(status, p, 64 );
status[63] = '\0';
}else
status[0]= '\0';
}
if(uptime){
if(up)
sscanf(up,"%u",uptime);
else
uptime = 0;
}
ClearNameValueList(&pdata);
}
/* UPNP_GetConnectionTypeInfo() call the corresponding UPNP method
* returns the connection type */
void UPNP_GetConnectionTypeInfo(const char * controlURL,
const char * servicetype,
char * connectionType)
{
struct NameValueParserData pdata;
char buffer[4096];
int bufsize = 4096;
char * p;
if(!connectionType)
return;
simpleUPnPcommand(-1, controlURL, servicetype,
"GetConnectionTypeInfo", 0, buffer, &bufsize);
ParseNameValue(buffer, bufsize, &pdata);
p = GetValueFromNameValueList(&pdata, "NewConnectionType");
/*p = GetValueFromNameValueList(&pdata, "NewPossibleConnectionTypes");*/
/* PossibleConnectionTypes will have several values.... */
if(connectionType)
{
if(p){
strncpy(connectionType, p, 64 );
connectionType[63] = '\0';
} else
connectionType[0] = '\0';
}
ClearNameValueList(&pdata);
}
/* UPNP_GetLinkLayerMaxBitRate() call the corresponding UPNP method.
* Returns 2 values: Downloadlink bandwidth and Uplink bandwidth.
* One of the values can be null
* Note : GetLinkLayerMaxBitRates belongs to WANPPPConnection:1 only
* We can use the GetCommonLinkProperties from WANCommonInterfaceConfig:1 */
void UPNP_GetLinkLayerMaxBitRates(const char * controlURL, const char * servicetype, unsigned int * bitrateDown, unsigned int* bitrateUp)
{
struct NameValueParserData pdata;
char buffer[4096];
int bufsize = 4096;
char * down;
char* up;
if(!bitrateDown && !bitrateUp)
return;
/* shouldn't we use GetCommonLinkProperties ? */
simpleUPnPcommand(-1, controlURL, servicetype,
"GetCommonLinkProperties", 0, buffer, &bufsize);
/*"GetLinkLayerMaxBitRates", 0, buffer, &bufsize);*/
/*DisplayNameValueList(buffer, bufsize);*/
ParseNameValue(buffer, bufsize, &pdata);
/*down = GetValueFromNameValueList(&pdata, "NewDownstreamMaxBitRate");*/
/*up = GetValueFromNameValueList(&pdata, "NewUpstreamMaxBitRate");*/
down = GetValueFromNameValueList(&pdata, "NewLayer1DownstreamMaxBitRate");
up = GetValueFromNameValueList(&pdata, "NewLayer1UpstreamMaxBitRate");
/*GetValueFromNameValueList(&pdata, "NewWANAccessType");*/
/*GetValueFromNameValueList(&pdata, "NewPhysicalLinkSatus");*/
if(bitrateDown)
{
if(down)
sscanf(down,"%u",bitrateDown);
else
*bitrateDown = 0;
}
if(bitrateUp)
{
if(up)
sscanf(up,"%u",bitrateUp);
else
*bitrateUp = 0;
}
ClearNameValueList(&pdata);
}
/* UPNP_GetExternalIPAddress() call the corresponding UPNP method.
* if the third arg is not null the value is copied to it.
* at least 16 bytes must be available */
void UPNP_GetExternalIPAddress(const char * controlURL, const char * servicetype, char * extIpAdd)
{
struct NameValueParserData pdata;
char buffer[4096];
int bufsize = 4096;
char * p;
if(!extIpAdd)
return;
simpleUPnPcommand(-1, controlURL, servicetype, "GetExternalIPAddress", 0, buffer, &bufsize);
/*fd = simpleUPnPcommand(fd, controlURL, data.servicetype, "GetExternalIPAddress", 0, buffer, &bufsize);*/
/*DisplayNameValueList(buffer, bufsize);*/
ParseNameValue(buffer, bufsize, &pdata);
/*printf("external ip = %s\n", GetValueFromNameValueList(&pdata, "NewExternalIPAddress") );*/
p = GetValueFromNameValueList(&pdata, "NewExternalIPAddress");
if(p){
strncpy(extIpAdd, p, 16 );
extIpAdd[15] = '\0';
}else
extIpAdd[0] = '\0';
ClearNameValueList(&pdata);
}
int
UPNP_AddPortMapping(const char * controlURL, const char * servicetype,
const char * extPort,
const char * inPort,
const char * inClient,
const char * desc,
const char * proto)
{
struct UPNParg * AddPortMappingArgs;
char buffer[4096];
int bufsize = 4096;
struct NameValueParserData pdata;
const char * resVal;
int ret;
if(!inPort || !inClient)
return 0;
AddPortMappingArgs = calloc(9, sizeof(struct UPNParg));
AddPortMappingArgs[0].elt = "NewRemoteHost";
AddPortMappingArgs[1].elt = "NewExternalPort";
AddPortMappingArgs[1].val = extPort;
AddPortMappingArgs[2].elt = "NewProtocol";
AddPortMappingArgs[2].val = proto;
AddPortMappingArgs[3].elt = "NewInternalPort";
AddPortMappingArgs[3].val = inPort;
AddPortMappingArgs[4].elt = "NewInternalClient";
AddPortMappingArgs[4].val = inClient;
AddPortMappingArgs[5].elt = "NewEnabled";
AddPortMappingArgs[5].val = "1";
AddPortMappingArgs[6].elt = "NewPortMappingDescription";
AddPortMappingArgs[6].val = desc?desc:"libminiupnpc";
AddPortMappingArgs[7].elt = "NewLeaseDuration";
AddPortMappingArgs[7].val = "0";
simpleUPnPcommand(-1, controlURL, servicetype, "AddPortMapping", AddPortMappingArgs, buffer, &bufsize);
/*fd = simpleUPnPcommand(fd, controlURL, data.servicetype, "AddPortMapping", AddPortMappingArgs, buffer, &bufsize);*/
/*DisplayNameValueList(buffer, bufsize);*/
/*buffer[bufsize] = '\0';*/
/*puts(buffer);*/
ParseNameValue(buffer, bufsize, &pdata);
resVal = GetValueFromNameValueList(&pdata, "errorCode");
ret = resVal?0:1;
/* Do something with resVal if not null ! */
/*printf("AddPortMapping errorCode = '%s'\n", resVal); */
ClearNameValueList(&pdata);
free(AddPortMappingArgs);
return ret;
}
void UPNP_DeletePortMapping(const char * controlURL, const char * servicetype,
const char * extPort, const char * proto)
{
/*struct NameValueParserData pdata;*/
struct UPNParg * DeletePortMappingArgs;
char buffer[4096];
int bufsize = 4096;
if(!extPort)
return;
DeletePortMappingArgs = calloc(4, sizeof(struct UPNParg));
DeletePortMappingArgs[0].elt = "NewRemoteHost";
DeletePortMappingArgs[1].elt = "NewExternalPort";
DeletePortMappingArgs[1].val = extPort;
DeletePortMappingArgs[2].elt = "NewProtocol";
DeletePortMappingArgs[2].val = proto;
simpleUPnPcommand(-1, controlURL, servicetype,
"DeletePortMapping",
DeletePortMappingArgs, buffer, &bufsize);
/*DisplayNameValueList(buffer, bufsize);*/
free(DeletePortMappingArgs);
}
int UPNP_GetGenericPortMappingEntry(const char * controlURL,
const char * servicetype,
const char * index,
char * extPort,
char * intClient,
char * intPort,
char * protocol,
char * desc,
char * enabled,
char * rHost,
char * duration)
{
struct NameValueParserData pdata;
struct UPNParg * GetPortMappingArgs;
char buffer[4096];
int bufsize = 4096;
char * p;
int r = -1;
intClient[0] = '\0';
intPort[0] = '\0';
GetPortMappingArgs = calloc(2, sizeof(struct UPNParg));
GetPortMappingArgs[0].elt = "NewPortMappingIndex";
GetPortMappingArgs[0].val = index;
simpleUPnPcommand(-1, controlURL, servicetype,
"GetGenericPortMappingEntry",
GetPortMappingArgs, buffer, &bufsize);
ParseNameValue(buffer, bufsize, &pdata);
p = GetValueFromNameValueList(&pdata, "NewRemoteHost");
if(p && rHost)
{
strncpy(rHost, p, 64);
rHost[63] = '\0';
}
p = GetValueFromNameValueList(&pdata, "NewExternalPort");
if(p && extPort)
{
strncpy(extPort, p, 6);
extPort[5] = '\0';
r = 0;
}
p = GetValueFromNameValueList(&pdata, "NewProtocol");
if(p && protocol)
{
strncpy(protocol, p, 4);
protocol[3] = '\0';
}
p = GetValueFromNameValueList(&pdata, "NewInternalClient");
if(p && intClient)
{
strncpy(intClient, p, 16);
intClient[15] = '\0';
r = 0;
}
p = GetValueFromNameValueList(&pdata, "NewInternalPort");
if(p && intPort)
{
strncpy(intPort, p, 6);
intPort[5] = '\0';
}
p = GetValueFromNameValueList(&pdata, "NewEnabled");
if(p && enabled)
{
strncpy(enabled, p, 4);
enabled[3] = '\0';
}
p = GetValueFromNameValueList(&pdata, "NewPortMappingDescription");
if(p && desc)
{
strncpy(desc, p, 80);
desc[79] = '\0';
}
p = GetValueFromNameValueList(&pdata, "NewLeaseDuration");
if(p && duration)
{
strncpy(duration, p, 16);
duration[15] = '\0';
}
ClearNameValueList(&pdata);
free(GetPortMappingArgs);
return r;
}
void UPNP_GetPortMappingNumberOfEntries(const char * controlURL, const char * servicetype, unsigned int * numEntries)
{
struct NameValueParserData pdata;
char buffer[4096];
int bufsize = 4096;
char* p;
simpleUPnPcommand(-1, controlURL, servicetype, "GetPortMappingNumberOfEntries", 0, buffer, &bufsize);
#ifndef NDEBUG
DisplayNameValueList(buffer, bufsize);
#endif
ParseNameValue(buffer, bufsize, &pdata);
p = GetValueFromNameValueList(&pdata, "NewPortMappingNumberOfEntries");
if(numEntries && p)
{
sscanf(p,"%u",numEntries);
}
ClearNameValueList(&pdata);
}
/* UPNP_GetSpecificPortMappingEntry retrieves an existing port mapping
* the result is returned in the intClient and intPort strings
* please provide 16 and 6 bytes of data */
void
UPNP_GetSpecificPortMappingEntry(const char * controlURL,
const char * servicetype,
const char * extPort,
const char * proto,
char * intClient,
char * intPort)
{
struct NameValueParserData pdata;
struct UPNParg * GetPortMappingArgs;
char buffer[4096];
int bufsize = 4096;
char * p;
if(!intPort && !intClient && !extPort)
return;
GetPortMappingArgs = calloc(4, sizeof(struct UPNParg));
GetPortMappingArgs[0].elt = "NewRemoteHost";
GetPortMappingArgs[1].elt = "NewExternalPort";
GetPortMappingArgs[1].val = extPort;
GetPortMappingArgs[2].elt = "NewProtocol";
GetPortMappingArgs[2].val = proto;
simpleUPnPcommand(-1, controlURL, servicetype,
"GetSpecificPortMappingEntry",
GetPortMappingArgs, buffer, &bufsize);
/*fd = simpleUPnPcommand(fd, controlURL, data.servicetype, "GetSpecificPortMappingEntry", AddPortMappingArgs, buffer, &bufsize); */
/*DisplayNameValueList(buffer, bufsize);*/
ParseNameValue(buffer, bufsize, &pdata);
p = GetValueFromNameValueList(&pdata, "NewInternalClient");
if(intClient)
{
if(p){
strncpy(intClient, p, 16);
intClient[15] = '\0';
}else
intClient[0] = '\0';
}
p = GetValueFromNameValueList(&pdata, "NewInternalPort");
if(intPort)
{
if(p){
strncpy(intPort, p, 6);
intPort[5] = '\0';
}else
intPort[0] = '\0';
}
ClearNameValueList(&pdata);
free(GetPortMappingArgs);
}

104
third-party/miniupnp/upnpcommands.h vendored Normal file
View File

@@ -0,0 +1,104 @@
/* $Id: upnpcommands.h,v 1.10 2007/01/29 20:27:24 nanard Exp $ */
/* Miniupnp project : http://miniupnp.free.fr/
* Author : Thomas Bernard
* Copyright (c) 2005-2006 Thomas Bernard
* This software is subject to the conditions detailed in the
* LICENCE file provided within this distribution */
#ifndef __UPNPCOMMANDS_H__
#define __UPNPCOMMANDS_H__
#include "upnpreplyparse.h"
#include "declspec.h"
#ifdef __cplusplus
extern "C" {
#endif
LIBSPEC unsigned int
UPNP_GetTotalBytesSent(const char * controlURL,
const char * servicetype);
LIBSPEC unsigned int
UPNP_GetTotalBytesReceived(const char * controlURL,
const char * servicetype);
LIBSPEC unsigned int
UPNP_GetTotalPacketsSent(const char * controlURL,
const char * servicetype);
LIBSPEC unsigned int
UPNP_GetTotalPacketsReceived(const char * controlURL,
const char * servicetype);
LIBSPEC void
UPNP_GetStatusInfo(const char * controlURL,
const char * servicetype,
char * status,
unsigned int * uptime);
LIBSPEC void
UPNP_GetConnectionTypeInfo(const char * controlURL,
const char * servicetype,
char * connectionType);
/* UPNP_GetExternalIPAddress() call the corresponding UPNP method.
* if the third arg is not null the value is copied to it.
* at least 16 bytes must be available */
LIBSPEC void
UPNP_GetExternalIPAddress(const char * controlURL,
const char * servicetype,
char * extIpAdd);
LIBSPEC void
UPNP_GetLinkLayerMaxBitRates(const char* controlURL,
const char* servicetype,
unsigned int * bitrateDown,
unsigned int * bitrateUp);
/* Returns zero if unable to add the port mapping, otherwise non-zero
* to indicate success */
LIBSPEC int
UPNP_AddPortMapping(const char * controlURL, const char * servicetype,
const char * extPort,
const char * inPort,
const char * inClient,
const char * desc,
const char * proto);
LIBSPEC void
UPNP_DeletePortMapping(const char * controlURL, const char * servicetype,
const char * extPort, const char * proto);
LIBSPEC void
UPNP_GetPortMappingNumberOfEntries(const char* controlURL, const char* servicetype, unsigned int * num);
/* UPNP_GetSpecificPortMappingEntry retrieves an existing port mapping
* the result is returned in the intClient and intPort strings
* please provide 16 and 6 bytes of data */
LIBSPEC void
UPNP_GetSpecificPortMappingEntry(const char * controlURL,
const char * servicetype,
const char * extPort,
const char * proto,
char * intClient,
char * intPort);
LIBSPEC int
UPNP_GetGenericPortMappingEntry(const char * controlURL,
const char * servicetype,
const char * index,
char * extPort,
char * intClient,
char * intPort,
char * protocol,
char * desc,
char * enabled,
char * rHost,
char * duration);
#ifdef __cplusplus
}
#endif
#endif

125
third-party/miniupnp/upnpreplyparse.c vendored Normal file
View File

@@ -0,0 +1,125 @@
/* $Id: upnpreplyparse.c,v 1.9 2007/05/15 18:14:08 nanard Exp $ */
/* MiniUPnP project
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
* (c) 2006 Thomas Bernard
* This software is subject to the conditions detailed
* in the LICENCE file provided within the distribution */
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "upnpreplyparse.h"
#include "minixml.h"
static void
NameValueParserStartElt(void * d, const char * name, int l)
{
struct NameValueParserData * data = (struct NameValueParserData *)d;
if(l>63)
l = 63;
memcpy(data->curelt, name, l);
data->curelt[l] = '\0';
}
static void
NameValueParserGetData(void * d, const char * datas, int l)
{
struct NameValueParserData * data = (struct NameValueParserData *)d;
struct NameValue * nv;
nv = malloc(sizeof(struct NameValue));
if(l>63)
l = 63;
strncpy(nv->name, data->curelt, 64);
nv->name[63] = '\0';
memcpy(nv->value, datas, l);
nv->value[l] = '\0';
LIST_INSERT_HEAD( &(data->head), nv, entries);
}
void
ParseNameValue(const char * buffer, int bufsize,
struct NameValueParserData * data)
{
struct xmlparser parser;
LIST_INIT(&(data->head));
/* init xmlparser object */
parser.xmlstart = buffer;
parser.xmlsize = bufsize;
parser.data = data;
parser.starteltfunc = NameValueParserStartElt;
parser.endeltfunc = 0;
parser.datafunc = NameValueParserGetData;
parser.attfunc = 0;
parsexml(&parser);
}
void
ClearNameValueList(struct NameValueParserData * pdata)
{
struct NameValue * nv;
while((nv = pdata->head.lh_first) != NULL)
{
LIST_REMOVE(nv, entries);
free(nv);
}
}
char *
GetValueFromNameValueList(struct NameValueParserData * pdata,
const char * Name)
{
struct NameValue * nv;
char * p = NULL;
for(nv = pdata->head.lh_first;
(nv != NULL) && (p == NULL);
nv = nv->entries.le_next)
{
if(strcmp(nv->name, Name) == 0)
p = nv->value;
}
return p;
}
#if 0
/* useless now that minixml ignores namespaces by itself */
char *
GetValueFromNameValueListIgnoreNS(struct NameValueParserData * pdata,
const char * Name)
{
struct NameValue * nv;
char * p = NULL;
char * pname;
for(nv = pdata->head.lh_first;
(nv != NULL) && (p == NULL);
nv = nv->entries.le_next)
{
pname = strrchr(nv->name, ':');
if(pname)
pname++;
else
pname = nv->name;
if(strcmp(pname, Name)==0)
p = nv->value;
}
return p;
}
#endif
/* debug all-in-one function
* do parsing then display to stdout */
void
DisplayNameValueList(char * buffer, int bufsize)
{
struct NameValueParserData pdata;
struct NameValue * nv;
ParseNameValue(buffer, bufsize, &pdata);
for(nv = pdata.head.lh_first;
nv != NULL;
nv = nv->entries.le_next)
{
printf("%s = %s\n", nv->name, nv->value);
}
ClearNameValueList(&pdata);
}

60
third-party/miniupnp/upnpreplyparse.h vendored Normal file
View File

@@ -0,0 +1,60 @@
/* $Id: upnpreplyparse.h,v 1.7 2007/10/06 10:02:54 nanard Exp $ */
/* MiniUPnP project
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
* (c) 2006 Thomas Bernard
* This software is subject to the conditions detailed
* in the LICENCE file provided within the distribution */
#ifndef __UPNPREPLYPARSE_H__
#define __UPNPREPLYPARSE_H__
#if defined(NO_SYS_QUEUE_H) || defined(WIN32)
#include "bsdqueue.h"
#else
#include <sys/queue.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
struct NameValue {
LIST_ENTRY(NameValue) entries;
char name[64];
char value[64];
};
struct NameValueParserData {
LIST_HEAD(listhead, NameValue) head;
char curelt[64];
};
/* ParseNameValue() */
void
ParseNameValue(const char * buffer, int bufsize,
struct NameValueParserData * data);
/* ClearNameValueList() */
void
ClearNameValueList(struct NameValueParserData * pdata);
/* GetValueFromNameValueList() */
char *
GetValueFromNameValueList(struct NameValueParserData * pdata,
const char * Name);
/* GetValueFromNameValueListIgnoreNS() */
char *
GetValueFromNameValueListIgnoreNS(struct NameValueParserData * pdata,
const char * Name);
/* DisplayNameValueList() */
void
DisplayNameValueList(char * buffer, int bufsize);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -16,4 +16,5 @@ Xmission_SOURCES = \
Xmission_LDADD = \
$(top_builddir)/libtransmission/libtransmission.a \
$(top_builddir)/third-party/libevent/libevent.la \
$(top_builddir)/third-party/miniupnp/libminiupnp.a \
$(WX_LIBS) $(OPENSSL_LIBS) $(PTHREAD_LIBS) -lm