mirror of
https://github.com/transmission/transmission.git
synced 2025-12-27 13:41:17 +00:00
use Thomas Bernard's miniupnp library instead of rolling our own.
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
**********************************************************************/
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
/***********************************************************************
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
***********************************************************************
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
2
third-party/Makefile.am
vendored
2
third-party/Makefile.am
vendored
@@ -1,4 +1,4 @@
|
||||
SUBDIRS = libevent
|
||||
SUBDIRS = libevent miniupnp
|
||||
|
||||
EXTRA_DIST = \
|
||||
macosx-libevent-config.h
|
||||
|
||||
26
third-party/miniupnp/LICENCE
vendored
Normal file
26
third-party/miniupnp/LICENCE
vendored
Normal 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
541
third-party/miniupnp/Makefile
vendored
Normal 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
29
third-party/miniupnp/Makefile.am
vendored
Normal 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
541
third-party/miniupnp/Makefile.in
vendored
Normal 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
3
third-party/miniupnp/README
vendored
Normal 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
531
third-party/miniupnp/bsdqueue.h
vendored
Normal 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
15
third-party/miniupnp/declspec.h
vendored
Normal 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
115
third-party/miniupnp/igd_desc_parse.c
vendored
Normal 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
38
third-party/miniupnp/igd_desc_parse.h
vendored
Normal 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
77
third-party/miniupnp/minisoap.c
vendored
Normal 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
15
third-party/miniupnp/minisoap.h
vendored
Normal 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
84
third-party/miniupnp/minissdpc.c
vendored
Normal 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
15
third-party/miniupnp/minissdpc.h
vendored
Normal 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
711
third-party/miniupnp/miniupnpc.c
vendored
Normal 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
92
third-party/miniupnp/miniupnpc.h
vendored
Normal 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
219
third-party/miniupnp/miniwget.c
vendored
Normal 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
28
third-party/miniupnp/miniwget.h
vendored
Normal 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
191
third-party/miniupnp/minixml.c
vendored
Normal 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
37
third-party/miniupnp/minixml.h
vendored
Normal 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
486
third-party/miniupnp/upnpcommands.c
vendored
Normal 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
104
third-party/miniupnp/upnpcommands.h
vendored
Normal 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
125
third-party/miniupnp/upnpreplyparse.c
vendored
Normal 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
60
third-party/miniupnp/upnpreplyparse.h
vendored
Normal 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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user