From bafdc244a7e2f0e04be6a9fc10dd566cc84393db Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Wed, 27 Oct 2010 03:24:56 +0200 Subject: [PATCH 01/13] * Imported newer version of miniupnp. --- libportfwd/CMakeLists.txt | 5 +- libportfwd/src/portfwd.cpp | 9 +- .../libnatpmp-20100202/Changelog.txt | 61 ++++ .../LICENCE => libnatpmp-20100202/LICENSE} | 2 +- .../third-party/libnatpmp-20100202/README | 7 + .../third-party/libnatpmp-20100202/build.bat | 30 ++ .../declspec.h | 0 .../getgateway.c | 177 +++++++-- .../getgateway.h | 7 +- .../libnatpmp-20100202/libnatpmpmodule.c | 268 ++++++++++++++ .../libnatpmp-20100202/msvc/libnatpmp.sln | 29 ++ .../libnatpmp-20100202/msvc/libnatpmp.vcproj | 195 ++++++++++ .../msvc/natpmpc-static.vcproj | 195 ++++++++++ .../natpmp.c | 31 +- .../third-party/libnatpmp-20100202/natpmp.def | 11 + .../natpmp.h | 9 +- .../third-party/libnatpmp-20100202/natpmpc.c | 210 +++++++++++ .../third-party/libnatpmp-20100202/setup.py | 15 + .../libnatpmp-20100202/setupmingw32.py | 14 + .../libnatpmp-20100202/testgetgateway.c | 42 +++ .../libnatpmp-20100202/wingettimeofday.c | 50 +++ .../libnatpmp-20100202/wingettimeofday.h | 27 ++ .../third-party/libnatpmp/.deps/getgateway.Po | 133 ------- .../third-party/libnatpmp/.deps/natpmp.Po | 134 ------- libportfwd/third-party/libnatpmp/README | 4 - .../Changelog.txt | 102 +++++- .../miniupnpc-1.4.20100609/LICENSE | 26 ++ .../README | 12 +- .../miniupnpc-1.4.20100609/VERSION | 1 + .../bsdqueue.h | 0 .../codelength.h | 0 .../miniupnpc-1.4.20100609/connecthostport.c | 221 +++++++++++ .../miniupnpc-1.4.20100609/connecthostport.h | 17 + .../declspec.h | 0 .../igd_desc_parse.c | 75 ++-- .../igd_desc_parse.h | 32 +- .../java/JavaBridgeTest.java | 89 +++++ .../miniupnpc-1.4.20100609/java/testjava.sh | 8 + .../man3/miniupnpc.3 | 0 .../mingw32make.bat | 1 + .../minisoap.c | 17 +- .../minisoap.h | 4 +- .../minissdpc.c | 27 +- .../minissdpc.h | 0 .../miniupnpc.c | 343 ++++++++++++++---- .../miniupnpc.def | 0 .../miniupnpc.h | 6 +- .../miniupnpcmodule.c | 84 +++-- .../miniupnpc-1.4.20100609/miniupnpcstrings.h | 15 + .../miniupnpcstrings.h.in} | 6 +- .../miniwget.c | 152 +++++--- .../miniwget.h | 0 .../minixml.c | 8 +- .../minixml.h | 0 .../minixmlvalid.c | 0 .../miniupnpc-1.4.20100609/msvc/miniupnpc.sln | 29 ++ .../msvc/miniupnpc.vcproj | 251 +++++++++++++ .../msvc/upnpc-static.vcproj | 195 ++++++++++ .../pymoduletest.py | 0 .../setup.py | 6 +- .../setupmingw32.py | 6 +- .../testigddescparse.c | 11 +- .../miniupnpc-1.4.20100609/testminiwget.c | 45 +++ .../testminixml.c | 0 .../testupnpigd.py | 0 .../testupnpreplyparse.c | 0 .../updateminiupnpcstrings.sh | 21 +- .../upnpc.c | 69 ++-- .../upnpcommands.c | 154 +++++--- .../upnpcommands.h | 5 +- .../upnperrors.c | 0 .../upnperrors.h | 0 .../upnpreplyparse.c | 0 .../upnpreplyparse.h | 6 +- .../wingenminiupnpcstrings.c | 69 ++++ 75 files changed, 3124 insertions(+), 654 deletions(-) create mode 100644 libportfwd/third-party/libnatpmp-20100202/Changelog.txt rename libportfwd/third-party/{miniupnpc-20090605/LICENCE => libnatpmp-20100202/LICENSE} (97%) create mode 100644 libportfwd/third-party/libnatpmp-20100202/README create mode 100644 libportfwd/third-party/libnatpmp-20100202/build.bat rename libportfwd/third-party/{libnatpmp => libnatpmp-20100202}/declspec.h (100%) rename libportfwd/third-party/{libnatpmp => libnatpmp-20100202}/getgateway.c (69%) rename libportfwd/third-party/{libnatpmp => libnatpmp-20100202}/getgateway.h (86%) create mode 100644 libportfwd/third-party/libnatpmp-20100202/libnatpmpmodule.c create mode 100644 libportfwd/third-party/libnatpmp-20100202/msvc/libnatpmp.sln create mode 100644 libportfwd/third-party/libnatpmp-20100202/msvc/libnatpmp.vcproj create mode 100644 libportfwd/third-party/libnatpmp-20100202/msvc/natpmpc-static.vcproj rename libportfwd/third-party/{libnatpmp => libnatpmp-20100202}/natpmp.c (92%) create mode 100644 libportfwd/third-party/libnatpmp-20100202/natpmp.def rename libportfwd/third-party/{libnatpmp => libnatpmp-20100202}/natpmp.h (96%) create mode 100644 libportfwd/third-party/libnatpmp-20100202/natpmpc.c create mode 100644 libportfwd/third-party/libnatpmp-20100202/setup.py create mode 100644 libportfwd/third-party/libnatpmp-20100202/setupmingw32.py create mode 100644 libportfwd/third-party/libnatpmp-20100202/testgetgateway.c create mode 100644 libportfwd/third-party/libnatpmp-20100202/wingettimeofday.c create mode 100644 libportfwd/third-party/libnatpmp-20100202/wingettimeofday.h delete mode 100644 libportfwd/third-party/libnatpmp/.deps/getgateway.Po delete mode 100644 libportfwd/third-party/libnatpmp/.deps/natpmp.Po delete mode 100644 libportfwd/third-party/libnatpmp/README rename libportfwd/third-party/{miniupnpc-20090605 => miniupnpc-1.4.20100609}/Changelog.txt (67%) create mode 100644 libportfwd/third-party/miniupnpc-1.4.20100609/LICENSE rename libportfwd/third-party/{miniupnpc-20090605 => miniupnpc-1.4.20100609}/README (80%) create mode 100644 libportfwd/third-party/miniupnpc-1.4.20100609/VERSION rename libportfwd/third-party/{miniupnpc-20090605 => miniupnpc-1.4.20100609}/bsdqueue.h (100%) rename libportfwd/third-party/{miniupnpc-20090605 => miniupnpc-1.4.20100609}/codelength.h (100%) create mode 100644 libportfwd/third-party/miniupnpc-1.4.20100609/connecthostport.c create mode 100644 libportfwd/third-party/miniupnpc-1.4.20100609/connecthostport.h rename libportfwd/third-party/{miniupnpc-20090605 => miniupnpc-1.4.20100609}/declspec.h (100%) rename libportfwd/third-party/{miniupnpc-20090605 => miniupnpc-1.4.20100609}/igd_desc_parse.c (54%) rename libportfwd/third-party/{miniupnpc-20090605 => miniupnpc-1.4.20100609}/igd_desc_parse.h (65%) create mode 100644 libportfwd/third-party/miniupnpc-1.4.20100609/java/JavaBridgeTest.java create mode 100755 libportfwd/third-party/miniupnpc-1.4.20100609/java/testjava.sh rename libportfwd/third-party/{miniupnpc-20090605 => miniupnpc-1.4.20100609}/man3/miniupnpc.3 (100%) rename libportfwd/third-party/{miniupnpc-20090605 => miniupnpc-1.4.20100609}/mingw32make.bat (81%) rename libportfwd/third-party/{miniupnpc-20090605 => miniupnpc-1.4.20100609}/minisoap.c (85%) rename libportfwd/third-party/{miniupnpc-20090605 => miniupnpc-1.4.20100609}/minisoap.h (77%) rename libportfwd/third-party/{miniupnpc-20090605 => miniupnpc-1.4.20100609}/minissdpc.c (80%) rename libportfwd/third-party/{miniupnpc-20090605 => miniupnpc-1.4.20100609}/minissdpc.h (100%) rename libportfwd/third-party/{miniupnpc-20090605 => miniupnpc-1.4.20100609}/miniupnpc.c (62%) rename libportfwd/third-party/{miniupnpc-20090605 => miniupnpc-1.4.20100609}/miniupnpc.def (100%) rename libportfwd/third-party/{miniupnpc-20090605 => miniupnpc-1.4.20100609}/miniupnpc.h (95%) rename libportfwd/third-party/{miniupnpc-20090605 => miniupnpc-1.4.20100609}/miniupnpcmodule.c (85%) create mode 100644 libportfwd/third-party/miniupnpc-1.4.20100609/miniupnpcstrings.h rename libportfwd/third-party/{miniupnpc-20090605/miniupnpcstrings.h => miniupnpc-1.4.20100609/miniupnpcstrings.h.in} (70%) rename libportfwd/third-party/{miniupnpc-20090605 => miniupnpc-1.4.20100609}/miniwget.c (60%) rename libportfwd/third-party/{miniupnpc-20090605 => miniupnpc-1.4.20100609}/miniwget.h (100%) rename libportfwd/third-party/{miniupnpc-20090605 => miniupnpc-1.4.20100609}/minixml.c (96%) rename libportfwd/third-party/{miniupnpc-20090605 => miniupnpc-1.4.20100609}/minixml.h (100%) rename libportfwd/third-party/{miniupnpc-20090605 => miniupnpc-1.4.20100609}/minixmlvalid.c (100%) create mode 100644 libportfwd/third-party/miniupnpc-1.4.20100609/msvc/miniupnpc.sln create mode 100644 libportfwd/third-party/miniupnpc-1.4.20100609/msvc/miniupnpc.vcproj create mode 100644 libportfwd/third-party/miniupnpc-1.4.20100609/msvc/upnpc-static.vcproj rename libportfwd/third-party/{miniupnpc-20090605 => miniupnpc-1.4.20100609}/pymoduletest.py (100%) rename libportfwd/third-party/{miniupnpc-20090605 => miniupnpc-1.4.20100609}/setup.py (73%) rename libportfwd/third-party/{miniupnpc-20090605 => miniupnpc-1.4.20100609}/setupmingw32.py (70%) mode change 100755 => 100644 rename libportfwd/third-party/{miniupnpc-20090605 => miniupnpc-1.4.20100609}/testigddescparse.c (75%) create mode 100644 libportfwd/third-party/miniupnpc-1.4.20100609/testminiwget.c rename libportfwd/third-party/{miniupnpc-20090605 => miniupnpc-1.4.20100609}/testminixml.c (100%) rename libportfwd/third-party/{miniupnpc-20090605 => miniupnpc-1.4.20100609}/testupnpigd.py (100%) rename libportfwd/third-party/{miniupnpc-20090605 => miniupnpc-1.4.20100609}/testupnpreplyparse.c (100%) rename libportfwd/third-party/{miniupnpc-20090605 => miniupnpc-1.4.20100609}/updateminiupnpcstrings.sh (56%) rename libportfwd/third-party/{miniupnpc-20090605 => miniupnpc-1.4.20100609}/upnpc.c (85%) rename libportfwd/third-party/{miniupnpc-20090605 => miniupnpc-1.4.20100609}/upnpcommands.c (79%) rename libportfwd/third-party/{miniupnpc-20090605 => miniupnpc-1.4.20100609}/upnpcommands.h (97%) rename libportfwd/third-party/{miniupnpc-20090605 => miniupnpc-1.4.20100609}/upnperrors.c (100%) rename libportfwd/third-party/{miniupnpc-20090605 => miniupnpc-1.4.20100609}/upnperrors.h (100%) rename libportfwd/third-party/{miniupnpc-20090605 => miniupnpc-1.4.20100609}/upnpreplyparse.c (100%) rename libportfwd/third-party/{miniupnpc-20090605 => miniupnpc-1.4.20100609}/upnpreplyparse.h (87%) create mode 100644 libportfwd/third-party/miniupnpc-1.4.20100609/wingenminiupnpcstrings.c diff --git a/libportfwd/CMakeLists.txt b/libportfwd/CMakeLists.txt index 9519e1399..88ccaf107 100644 --- a/libportfwd/CMakeLists.txt +++ b/libportfwd/CMakeLists.txt @@ -3,8 +3,8 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6 FATAL_ERROR) SET(CMAKE_VERBOSE_MAKEFILE ON) #SET(CMAKE_INSTALL_PREFIX ".") -SET(MINIUPNP_DIR "third-party/miniupnpc-20090605/") -SET(NATPMP_DIR "third-party/libnatpmp") +SET(MINIUPNP_DIR "third-party/miniupnpc-1.4.20100609/") +SET(NATPMP_DIR "third-party/libnatpmp-20100202") SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}") SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}") @@ -20,6 +20,7 @@ INCLUDE_DIRECTORIES(${MINIUPNP_DIR} include) ADD_LIBRARY(portfwd STATIC # the needed bits of miniupnpc (no python module, no tests, no cli) + ${MINIUPNP_DIR}/connecthostport.c ${MINIUPNP_DIR}/igd_desc_parse.c ${MINIUPNP_DIR}/minisoap.c ${MINIUPNP_DIR}/minissdpc.c diff --git a/libportfwd/src/portfwd.cpp b/libportfwd/src/portfwd.cpp index c74b156d1..e64024621 100644 --- a/libportfwd/src/portfwd.cpp +++ b/libportfwd/src/portfwd.cpp @@ -6,6 +6,7 @@ #ifdef WIN32 #include +#include "../include/portfwd/portfwd.h" #endif Portfwd::Portfwd() @@ -82,12 +83,12 @@ Portfwd::get_status() { // get connection speed UPNP_GetLinkLayerMaxBitRates( - urls->controlURL_CIF, data->servicetype_CIF, &m_downbps, &m_upbps); + urls->controlURL_CIF, data->CIF.servicetype, &m_downbps, &m_upbps); // get external IP adress char ip[16]; if( 0 != UPNP_GetExternalIPAddress( urls->controlURL, - data->servicetype, + data->CIF.servicetype, (char*)&ip ) ) { m_externalip = ""; //failed @@ -110,7 +111,7 @@ Portfwd::add( unsigned short port, unsigned short internal_port ) sprintf(port_str, "%d", port); sprintf(port_str_internal, "%d", internal_port); - r = UPNP_AddPortMapping(urls->controlURL, data->servicetype, + r = UPNP_AddPortMapping(urls->controlURL, data->CIF.servicetype, port_str, port_str_internal, m_lanip.c_str(), "tomahawk", "TCP", NULL); if(r!=0) { @@ -131,7 +132,7 @@ Portfwd::remove( unsigned short port ) return false; } sprintf(port_str, "%d", port); - int r = UPNP_DeletePortMapping(urls->controlURL, data->servicetype, port_str, "TCP", NULL); + int r = UPNP_DeletePortMapping(urls->controlURL, data->CIF.servicetype, port_str, "TCP", NULL); return r == 0; } diff --git a/libportfwd/third-party/libnatpmp-20100202/Changelog.txt b/libportfwd/third-party/libnatpmp-20100202/Changelog.txt new file mode 100644 index 000000000..9359f72b7 --- /dev/null +++ b/libportfwd/third-party/libnatpmp-20100202/Changelog.txt @@ -0,0 +1,61 @@ +$Id: Changelog.txt,v 1.21 2010/02/02 18:24:43 nanard Exp $ + +2010/02/02: + Fixed compilation under Mac OS X + +2009/12/19: + improve and fix building under Windows. + Project files for MS Visual Studio 2008 + More simple (and working) code for Win32. + More checks in the /proc/net/route parsing. Add some comments. + +2009/08/04: + improving getgateway.c for windows + +2009/07/13: + Adding Haiku code in getgateway.c + +2009/06/04: + Adding Python module thanks to David Wu + +2009/03/10: + Trying to have windows get gateway working if not using DHCP + +2009/02/27: + dont include declspec.h if not under WIN32. + +2009/01/23: + Prefixed the libraries name with lib + +2008/10/06: + Fixed a memory leak in getdefaultgateway() (USE_SYSCTL_NET_ROUTE) + +2008/07/03: + Adding WIN32 code from Robbie Hanson + +2008/06/30: + added a Solaris implementation for getgateway(). + added a LICENCE file to the distribution + +2008/05/29: + Anonymous unions are forbidden in ANSI C. That was causing problems with + non-GCC compilers. + +2008/04/28: + introduced strnatpmperr() + improved natpmpc.c sample + make install now install the binary + +2007/12/13: + Fixed getgateway.c for working under OS X ;) + Fixed values for NATPMP_PROTOCOL_TCP and NATPMP_PROTOCOL_UDP + +2007/12/11: + Fixed getgateway.c for compilation under Mac OS X + +2007/12/01: + added some comments in .h + +2007/11/30: + implemented almost everything + diff --git a/libportfwd/third-party/miniupnpc-20090605/LICENCE b/libportfwd/third-party/libnatpmp-20100202/LICENSE similarity index 97% rename from libportfwd/third-party/miniupnpc-20090605/LICENCE rename to libportfwd/third-party/libnatpmp-20100202/LICENSE index a8cfb5ef3..14db2feb9 100644 --- a/libportfwd/third-party/miniupnpc-20090605/LICENCE +++ b/libportfwd/third-party/libnatpmp-20100202/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2005-2008, Thomas BERNARD +Copyright (c) 2007-2009, Thomas BERNARD All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/libportfwd/third-party/libnatpmp-20100202/README b/libportfwd/third-party/libnatpmp-20100202/README new file mode 100644 index 000000000..269392d2a --- /dev/null +++ b/libportfwd/third-party/libnatpmp-20100202/README @@ -0,0 +1,7 @@ +libnatpmp (c) 2007-2009 Thomas Bernard +contact : miniupnp@free.fr + +see http://miniupnp.free.fr/libnatpmp.html +or http://miniupnp.tuxfamily.org/libnatpmp.html +for some documentation and code samples. + diff --git a/libportfwd/third-party/libnatpmp-20100202/build.bat b/libportfwd/third-party/libnatpmp-20100202/build.bat new file mode 100644 index 000000000..2d2f27cd7 --- /dev/null +++ b/libportfwd/third-party/libnatpmp-20100202/build.bat @@ -0,0 +1,30 @@ +@echo Compiling with MinGW +@SET LIBS=-lws2_32 -liphlpapi + +@echo Compile getgateway +gcc -c -Wall -Os -DWIN32 -DSTATICLIB -DENABLE_STRNATPMPERR getgateway.c +gcc -c -Wall -Os -DWIN32 -DSTATICLIB -DENABLE_STRNATPMPERR testgetgateway.c +gcc -o testgetgateway getgateway.o testgetgateway.o %LIBS% +del testgetgateway.o + +@echo Compile natpmp-static: +gcc -c -Wall -Os -DWIN32 -DSTATICLIB -DENABLE_STRNATPMPERR getgateway.c +gcc -c -Wall -Os -DWIN32 -DSTATICLIB -DENABLE_STRNATPMPERR natpmp.c +gcc -c -Wall -Os -DWIN32 wingettimeofday.c +ar cr natpmp.a getgateway.o natpmp.o wingettimeofday.o +del getgateway.o natpmp.o +gcc -c -Wall -Os -DWIN32 -DSTATICLIB -DENABLE_STRNATPMPERR natpmpc.c +gcc -o natpmpc-static natpmpc.o natpmp.a %LIBS% +upx --best natpmpc-static.exe +del natpmpc.o + +@echo Create natpmp.dll: +gcc -c -Wall -Os -DWIN32 -DENABLE_STRNATPMPERR -DNATPMP_EXPORTS getgateway.c +gcc -c -Wall -Os -DWIN32 -DENABLE_STRNATPMPERR -DNATPMP_EXPORTS natpmp.c +dllwrap -k --driver-name gcc --def natpmp.def --output-def natpmp.dll.def --implib natpmp.lib -o natpmp.dll getgateway.o natpmp.o wingettimeofday.o %LIBS% + +@echo Compile natpmp-shared: +gcc -c -Wall -Os -DWIN32 -DENABLE_STRNATPMPERR -DNATPMP_EXPORTS natpmpc.c +gcc -o natpmpc-shared natpmpc.o natpmp.lib -lws2_32 +upx --best natpmpc-shared.exe +del *.o diff --git a/libportfwd/third-party/libnatpmp/declspec.h b/libportfwd/third-party/libnatpmp-20100202/declspec.h similarity index 100% rename from libportfwd/third-party/libnatpmp/declspec.h rename to libportfwd/third-party/libnatpmp-20100202/declspec.h diff --git a/libportfwd/third-party/libnatpmp/getgateway.c b/libportfwd/third-party/libnatpmp-20100202/getgateway.c similarity index 69% rename from libportfwd/third-party/libnatpmp/getgateway.c rename to libportfwd/third-party/libnatpmp-20100202/getgateway.c index 3c84de3a6..bcde3ad33 100644 --- a/libportfwd/third-party/libnatpmp/getgateway.c +++ b/libportfwd/third-party/libnatpmp-20100202/getgateway.c @@ -1,6 +1,6 @@ -/* $Id: getgateway.c,v 1.13 2009/03/10 10:15:31 nanard Exp $ */ +/* $Id: getgateway.c,v 1.19 2009/12/19 15:20:45 nanard Exp $ */ /* libnatpmp - * Copyright (c) 2007-2008, Thomas BERNARD + * Copyright (c) 2007-2009, Thomas BERNARD * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -18,13 +18,17 @@ #ifndef WIN32 #include #endif +#if !defined(_MSC_VER) #include +#endif /* There is no portable method to get the default route gateway. - * So below are three differents functions implementing this. + * So below are four (or five ?) differents functions implementing this. * Parsing /proc/net/route is for linux. * sysctl is the way to access such informations on BSD systems. * Many systems should provide route information through raw PF_ROUTE - * sockets. */ + * sockets. + * In MS Windows, default gateway is found by looking into the registry + * or by using GetBestRoute(). */ #ifdef __linux__ #define USE_PROC_NET_ROUTE #undef USE_SOCKET_ROUTE @@ -53,9 +57,29 @@ #undef USE_PROC_NET_ROUTE #undef USE_SOCKET_ROUTE #undef USE_SYSCTL_NET_ROUTE -#define USE_WIN32_CODE +//#define USE_WIN32_CODE +#define USE_WIN32_CODE_2 #endif +#ifdef __CYGWIN__ +#undef USE_PROC_NET_ROUTE +#undef USE_SOCKET_ROUTE +#undef USE_SYSCTL_NET_ROUTE +#define USE_WIN32_CODE +#include +#include +#include +#include +#endif + +#ifdef __HAIKU__ +#include +#include +#include +#include +#define USE_HAIKU_CODE +#endif + #ifdef USE_SYSCTL_NET_ROUTE #include #include @@ -69,12 +93,19 @@ #include #include #endif -#ifdef WIN32 + +#ifdef USE_WIN32_CODE #include #include #define MAX_KEY_LENGTH 255 #define MAX_VALUE_LENGTH 16383 #endif + +#ifdef USE_WIN32_CODE_2 +#include +#include +#endif + #include "getgateway.h" #ifndef WIN32 @@ -83,9 +114,20 @@ #endif #ifdef USE_PROC_NET_ROUTE +/* + parse /proc/net/route which is as follow : + +Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT +wlan0 0001A8C0 00000000 0001 0 0 0 00FFFFFF 0 0 0 +eth0 0000FEA9 00000000 0001 0 0 0 0000FFFF 0 0 0 +wlan0 00000000 0101A8C0 0003 0 0 0 00000000 0 0 0 +eth0 00000000 00000000 0001 0 0 1000 00000000 0 0 0 + + One header line, and then one line by route by route table entry. +*/ int getdefaultgateway(in_addr_t * addr) { - long d, g; + unsigned long d, g; char buf[256]; int line = 0; FILE * f; @@ -94,14 +136,15 @@ int getdefaultgateway(in_addr_t * addr) if(!f) return FAILED; while(fgets(buf, sizeof(buf), f)) { - if(line > 0) { + if(line > 0) { /* skip the first line */ p = buf; + /* skip the interface name */ while(*p && !isspace(*p)) p++; while(*p && isspace(*p)) p++; if(sscanf(p, "%lx%lx", &d, &g)==2) { - if(d == 0) { /* default */ + if(d == 0 && g != 0) { /* default */ *addr = g; fclose(f); return SUCCESS; @@ -261,7 +304,7 @@ int getdefaultgateway(in_addr_t *addr) #endif /* #ifdef USE_SOCKET_ROUTE */ #ifdef USE_WIN32_CODE -int getdefaultgateway(in_addr_t * addr) +LIBSPEC int getdefaultgateway(in_addr_t * addr) { HKEY networkCardsKey; HKEY networkCardKey; @@ -279,9 +322,21 @@ int getdefaultgateway(in_addr_t * addr) DWORD gatewayValueType = REG_MULTI_SZ; int done = 0; - char networkCardsPath[] = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards"; - char interfacesPath[] = "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces"; - + //const char * networkCardsPath = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards"; + //const char * interfacesPath = "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces"; +#ifdef UNICODE + LPCTSTR networkCardsPath = L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards"; + LPCTSTR interfacesPath = L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces"; +#define STR_SERVICENAME L"ServiceName" +#define STR_DHCPDEFAULTGATEWAY L"DhcpDefaultGateway" +#define STR_DEFAULTGATEWAY L"DefaultGateway" +#else + LPCTSTR networkCardsPath = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards"; + LPCTSTR interfacesPath = "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces"; +#define STR_SERVICENAME "ServiceName" +#define STR_DHCPDEFAULTGATEWAY "DhcpDefaultGateway" +#define STR_DEFAULTGATEWAY "DefaultGateway" +#endif // The windows registry lists its primary network devices in the following location: // HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkCards // @@ -361,40 +416,39 @@ int getdefaultgateway(in_addr_t * addr) { keyValueLength = MAX_VALUE_LENGTH; if(ERROR_SUCCESS == RegQueryValueEx(networkCardKey, // Open registry key - "ServiceName", // Name of key to query + STR_SERVICENAME, // Name of key to query NULL, // Reserved - must be NULL &keyValueType, // Receives value type - keyValue, // Receives value + (LPBYTE)keyValue, // Receives value &keyValueLength)) // Receives value length in bytes { - //printf("keyValue: %s\n", keyValue); - +// printf("keyValue: %s\n", keyValue); if(RegOpenKeyEx(interfacesKey, keyValue, 0, KEY_READ, &interfaceKey) == ERROR_SUCCESS) { gatewayValueLength = MAX_VALUE_LENGTH; if(ERROR_SUCCESS == RegQueryValueEx(interfaceKey, // Open registry key - "DhcpDefaultGateway", // Name of key to query + STR_DHCPDEFAULTGATEWAY, // Name of key to query NULL, // Reserved - must be NULL &gatewayValueType, // Receives value type - gatewayValue, // Receives value + (LPBYTE)gatewayValue, // Receives value &gatewayValueLength)) // Receives value length in bytes { // Check to make sure it's a string - if(gatewayValueType == REG_MULTI_SZ || gatewayValueType == REG_SZ) + if((gatewayValueType == REG_MULTI_SZ || gatewayValueType == REG_SZ) && (gatewayValueLength > 1)) { //printf("gatewayValue: %s\n", gatewayValue); done = 1; } } else if(ERROR_SUCCESS == RegQueryValueEx(interfaceKey, // Open registry key - "DefaultGateway", // Name of key to query + STR_DEFAULTGATEWAY, // Name of key to query NULL, // Reserved - must be NULL &gatewayValueType, // Receives value type - gatewayValue, // Receives value + (LPBYTE)gatewayValue,// Receives value &gatewayValueLength)) // Receives value length in bytes { // Check to make sure it's a string - if(gatewayValueType == REG_MULTI_SZ || gatewayValueType == REG_SZ) + if((gatewayValueType == REG_MULTI_SZ || gatewayValueType == REG_SZ) && (gatewayValueLength > 1)) { //printf("gatewayValue: %s\n", gatewayValue); done = 1; @@ -413,7 +467,18 @@ int getdefaultgateway(in_addr_t * addr) if(done) { +#if UNICODE + char tmp[32]; + for(i = 0; i < 32; i++) { + tmp[i] = (char)gatewayValue[i]; + if(!tmp[i]) + break; + } + tmp[31] = '\0'; + *addr = inet_addr(tmp); +#else *addr = inet_addr(gatewayValue); +#endif return 0; } @@ -421,3 +486,69 @@ int getdefaultgateway(in_addr_t * addr) } #endif /* #ifdef USE_WIN32_CODE */ +#ifdef USE_WIN32_CODE_2 +int getdefaultgateway(in_addr_t *addr) +{ + MIB_IPFORWARDROW ip_forward; + memset(&ip_forward, 0, sizeof(ip_forward)); + if(GetBestRoute(inet_addr("0.0.0.0"), 0, &ip_forward) != NO_ERROR) + return -1; + *addr = ip_forward.dwForwardNextHop; + return 0; +} +#endif /* #ifdef USE_WIN32_CODE_2 */ + +#ifdef USE_HAIKU_CODE +int getdefaultgateway(in_addr_t *addr) +{ + int fd, ret = -1; + struct ifconf config; + void *buffer = NULL; + struct ifreq *interface; + + if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + return -1; + } + if (ioctl(fd, SIOCGRTSIZE, &config, sizeof(config)) != 0) { + goto fail; + } + if (config.ifc_value < 1) { + goto fail; /* No routes */ + } + if ((buffer = malloc(config.ifc_value)) == NULL) { + goto fail; + } + config.ifc_len = config.ifc_value; + config.ifc_buf = buffer; + if (ioctl(fd, SIOCGRTTABLE, &config, sizeof(config)) != 0) { + goto fail; + } + for (interface = buffer; + (uint8_t *)interface < (uint8_t *)buffer + config.ifc_len; ) { + struct route_entry route = interface->ifr_route; + int intfSize; + if (route.flags & (RTF_GATEWAY | RTF_DEFAULT)) { + *addr = ((struct sockaddr_in *)route.gateway)->sin_addr.s_addr; + ret = 0; + break; + } + intfSize = sizeof(route) + IF_NAMESIZE; + if (route.destination != NULL) { + intfSize += route.destination->sa_len; + } + if (route.mask != NULL) { + intfSize += route.mask->sa_len; + } + if (route.gateway != NULL) { + intfSize += route.gateway->sa_len; + } + interface = (struct ifreq *)((uint8_t *)interface + intfSize); + } +fail: + free(buffer); + close(fd); + return ret; +} +#endif /* #ifdef USE_HAIKU_CODE */ + + diff --git a/libportfwd/third-party/libnatpmp/getgateway.h b/libportfwd/third-party/libnatpmp-20100202/getgateway.h similarity index 86% rename from libportfwd/third-party/libnatpmp/getgateway.h rename to libportfwd/third-party/libnatpmp-20100202/getgateway.h index cf7794600..9432528b8 100644 --- a/libportfwd/third-party/libnatpmp/getgateway.h +++ b/libportfwd/third-party/libnatpmp-20100202/getgateway.h @@ -1,4 +1,4 @@ -/* $Id: getgateway.h,v 1.3 2008/07/02 22:33:06 nanard Exp $ */ +/* $Id: getgateway.h,v 1.4 2009/12/19 12:00:00 nanard Exp $ */ /* libnatpmp * Copyright (c) 2007, Thomas BERNARD * @@ -17,7 +17,12 @@ #define __GETGATEWAY_H__ #ifdef WIN32 +#if !defined(_MSC_VER) #include +#else +typedef unsigned long uint32_t; +typedef unsigned short uint16_t; +#endif #define in_addr_t uint32_t #endif #include "declspec.h" diff --git a/libportfwd/third-party/libnatpmp-20100202/libnatpmpmodule.c b/libportfwd/third-party/libnatpmp-20100202/libnatpmpmodule.c new file mode 100644 index 000000000..b08384e0a --- /dev/null +++ b/libportfwd/third-party/libnatpmp-20100202/libnatpmpmodule.c @@ -0,0 +1,268 @@ +/* $Id: libnatpmpmodule.c,v 1.3 2009/12/19 12:00:00 nanard Exp $ */ +/* libnatpmp + * Copyright (c) 2007-2008, Thomas BERNARD + * http://miniupnp.free.fr/libnatpmp.html + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include +#ifdef WIN32 +#include +#else +#include +#include +#endif + +#define STATICLIB +#include "structmember.h" +#include "natpmp.h" + +/* for compatibility with Python < 2.4 */ +#ifndef Py_RETURN_NONE +#define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None +#endif + +#ifndef Py_RETURN_TRUE +#define Py_RETURN_TRUE return Py_INCREF(Py_True), Py_True +#endif + +#ifndef Py_RETURN_FALSE +#define Py_RETURN_FALSE return Py_INCREF(Py_False), Py_False +#endif + +typedef struct { + PyObject_HEAD + + /* Type-specific fields go here. */ + unsigned int discoverdelay; + + natpmp_t natpmp; +} NATPMPObject; + +static PyMemberDef NATPMP_members[] = { + {"discoverdelay", T_UINT, offsetof(NATPMPObject, discoverdelay), + 0/*READWRITE*/, "value in ms used to wait for NATPMP responses" + }, + {NULL} +}; + +static PyObject * +NATPMPObject_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + NATPMPObject *self; + + self = (NATPMPObject *)type->tp_alloc(type, 0); + if (self) { + initnatpmp(&self->natpmp); + } + + return (PyObject *)self; +} + +static void +NATPMPObject_dealloc(NATPMPObject *self) +{ + closenatpmp(&self->natpmp); + self->ob_type->tp_free((PyObject*)self); +} + +static PyObject * +NATPMP_externalipaddress(NATPMPObject *self) +{ + int r; + struct timeval timeout; + fd_set fds; + natpmpresp_t response; + + r = sendpublicaddressrequest(&self->natpmp); + + if (r < 0) { +#ifdef ENABLE_STRNATPMPERR + PyErr_SetString(PyExc_Exception, strnatpmperr(r)); +#endif + return NULL; + } + + do { + FD_ZERO(&fds); + FD_SET(self->natpmp.s, &fds); + getnatpmprequesttimeout(&self->natpmp, &timeout); + select(FD_SETSIZE, &fds, NULL, NULL, &timeout); + r = readnatpmpresponseorretry(&self->natpmp, &response); + if (r < 0 && r != NATPMP_TRYAGAIN) { +#ifdef ENABLE_STRNATPMPERR + PyErr_SetString(PyExc_Exception, strnatpmperr(r)); +#endif + return NULL; + } + } while (r == NATPMP_TRYAGAIN); + + return Py_BuildValue("s", inet_ntoa(response.pnu.publicaddress.addr)); +} + +static PyObject * +NATPMP_domapping(natpmp_t *n, unsigned short eport, unsigned short iport, + const char *protocol, unsigned int lifetime) +{ + int proto; + struct timeval timeout; + fd_set fds; + natpmpresp_t response; + int r; + + if (!strncasecmp("tcp", protocol, 3)) { + proto = NATPMP_PROTOCOL_TCP; + } else if (!strncasecmp("udp", protocol, 3)) { + proto = NATPMP_PROTOCOL_UDP; + } else { + PyErr_SetString(PyExc_Exception, "Unknown protocol"); + return NULL; + } + + r = sendnewportmappingrequest(n, proto, iport, eport, + lifetime); + + if (r < 0) { +#ifdef ENABLE_STRNATPMPERR + PyErr_SetString(PyExc_Exception, strnatpmperr(r)); +#endif + return NULL; + } + + do { + FD_ZERO(&fds); + FD_SET(n->s, &fds); + getnatpmprequesttimeout(n, &timeout); + select(FD_SETSIZE, &fds, NULL, NULL, &timeout); + r = readnatpmpresponseorretry(n, &response); + if (r < 0 && r != NATPMP_TRYAGAIN) { +#ifdef ENABLE_STRNATPMPERR + PyErr_SetString(PyExc_Exception, strnatpmperr(r)); +#endif + return NULL; + } + } while (r == NATPMP_TRYAGAIN); + + return Py_BuildValue("H", response.pnu.newportmapping.mappedpublicport); +} + + +/* AddPortMapping(externalPort, protocol, internalPort, lifetime) + * protocol is 'UDP' or 'TCP' */ +static PyObject * +NATPMP_addportmapping(NATPMPObject *self, PyObject *args) +{ + unsigned short eport; + unsigned short iport; + unsigned int lifetime; + const char *protocol; + + if (!PyArg_ParseTuple(args, "HsHI", &eport, &protocol, &iport, &lifetime)) + return NULL; + + return NATPMP_domapping(&self->natpmp, eport, iport, protocol, lifetime); +} + +/* DeletePortMapping(externalPort, protocol, internalPort) + * protocol is 'UDP' or 'TCP' */ +static PyObject * +NATPMP_deleteportmapping(NATPMPObject *self, PyObject *args) +{ + unsigned short eport; + unsigned short iport; + const char *protocol; + + if (!PyArg_ParseTuple(args, "HsHI", &eport, &protocol, &iport)) + return NULL; + + return NATPMP_domapping(&self->natpmp, eport, iport, protocol, 0); +} + +/* natpmp.NATPMP object Method Table */ +static PyMethodDef NATPMP_methods[] = { + {"externalipaddress", (PyCFunction)NATPMP_externalipaddress, METH_NOARGS, + "return external IP address" + }, + {"addportmapping", (PyCFunction)NATPMP_addportmapping, METH_VARARGS, + "add a port mapping" + }, + {"deleteportmapping", (PyCFunction)NATPMP_deleteportmapping, METH_VARARGS, + "delete a port mapping" + }, + {NULL} /* Sentinel */ +}; + +static PyTypeObject NATPMPType = { + PyObject_HEAD_INIT(NULL) + 0, /*ob_size*/ + "libnatpmp.NATPMP", /*tp_name*/ + sizeof(NATPMPObject), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + (destructor)NATPMPObject_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash */ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + "NATPMP objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + NATPMP_methods, /* tp_methods */ + NATPMP_members, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + NATPMPObject_new, /* tp_new */ +}; + +/* module methods */ +static PyMethodDef libnatpmp_methods[] = { + {NULL} /* Sentinel */ +}; + +#ifndef PyMODINIT_FUNC /* declarations for DLL import/export */ +#define PyMODINIT_FUNC void +#endif +PyMODINIT_FUNC +initlibnatpmp(void) +{ + PyObject* m; + + if (PyType_Ready(&NATPMPType) < 0) + return; + + m = Py_InitModule3("libnatpmp", libnatpmp_methods, + "libnatpmp module."); + + Py_INCREF(&NATPMPType); + PyModule_AddObject(m, "NATPMP", (PyObject *)&NATPMPType); +} + diff --git a/libportfwd/third-party/libnatpmp-20100202/msvc/libnatpmp.sln b/libportfwd/third-party/libnatpmp-20100202/msvc/libnatpmp.sln new file mode 100644 index 000000000..ac746d415 --- /dev/null +++ b/libportfwd/third-party/libnatpmp-20100202/msvc/libnatpmp.sln @@ -0,0 +1,29 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual C++ Express 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libnatpmp", "libnatpmp.vcproj", "{D59B6527-F3DE-4D26-A08D-52F1EE989301}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "natpmpc-static", "natpmpc-static.vcproj", "{A0B49FA9-98AB-4A74-8B4C-8AB7FA36089B}" + ProjectSection(ProjectDependencies) = postProject + {D59B6527-F3DE-4D26-A08D-52F1EE989301} = {D59B6527-F3DE-4D26-A08D-52F1EE989301} + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D59B6527-F3DE-4D26-A08D-52F1EE989301}.Debug|Win32.ActiveCfg = Debug|Win32 + {D59B6527-F3DE-4D26-A08D-52F1EE989301}.Debug|Win32.Build.0 = Debug|Win32 + {D59B6527-F3DE-4D26-A08D-52F1EE989301}.Release|Win32.ActiveCfg = Release|Win32 + {D59B6527-F3DE-4D26-A08D-52F1EE989301}.Release|Win32.Build.0 = Release|Win32 + {A0B49FA9-98AB-4A74-8B4C-8AB7FA36089B}.Debug|Win32.ActiveCfg = Debug|Win32 + {A0B49FA9-98AB-4A74-8B4C-8AB7FA36089B}.Debug|Win32.Build.0 = Debug|Win32 + {A0B49FA9-98AB-4A74-8B4C-8AB7FA36089B}.Release|Win32.ActiveCfg = Release|Win32 + {A0B49FA9-98AB-4A74-8B4C-8AB7FA36089B}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/libportfwd/third-party/libnatpmp-20100202/msvc/libnatpmp.vcproj b/libportfwd/third-party/libnatpmp-20100202/msvc/libnatpmp.vcproj new file mode 100644 index 000000000..9bae5c185 --- /dev/null +++ b/libportfwd/third-party/libnatpmp-20100202/msvc/libnatpmp.vcproj @@ -0,0 +1,195 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libportfwd/third-party/libnatpmp-20100202/msvc/natpmpc-static.vcproj b/libportfwd/third-party/libnatpmp-20100202/msvc/natpmpc-static.vcproj new file mode 100644 index 000000000..c2052d982 --- /dev/null +++ b/libportfwd/third-party/libnatpmp-20100202/msvc/natpmpc-static.vcproj @@ -0,0 +1,195 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libportfwd/third-party/libnatpmp/natpmp.c b/libportfwd/third-party/libnatpmp-20100202/natpmp.c similarity index 92% rename from libportfwd/third-party/libnatpmp/natpmp.c rename to libportfwd/third-party/libnatpmp-20100202/natpmp.c index f1c95b1ad..055ba4f0a 100644 --- a/libportfwd/third-party/libnatpmp/natpmp.c +++ b/libportfwd/third-party/libnatpmp-20100202/natpmp.c @@ -1,6 +1,6 @@ -/* $Id: natpmp.c,v 1.8 2008/07/02 22:33:06 nanard Exp $ */ +/* $Id: natpmp.c,v 1.12 2009/12/19 14:10:09 nanard Exp $ */ /* libnatpmp - * Copyright (c) 2007-2008, Thomas BERNARD + * Copyright (c) 2007-2009, Thomas BERNARD * http://miniupnp.free.fr/libnatpmp.html * * Permission to use, copy, modify, and/or distribute this software for any @@ -14,15 +14,22 @@ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#ifdef __linux__ +#define _BSD_SOURCE 1 +#endif #include #include +#if !defined(_MSC_VER) #include +#endif #ifdef WIN32 +#include #include -#include +#include #include #define EWOULDBLOCK WSAEWOULDBLOCK #define ECONNREFUSED WSAECONNREFUSED +#include "wingettimeofday.h" #else #include #include @@ -34,7 +41,7 @@ #include "natpmp.h" #include "getgateway.h" -int initnatpmp(natpmp_t * p) +LIBSPEC int initnatpmp(natpmp_t * p) { #ifdef WIN32 u_long ioctlArg = 1; @@ -70,7 +77,7 @@ int initnatpmp(natpmp_t * p) return 0; } -int closenatpmp(natpmp_t * p) +LIBSPEC int closenatpmp(natpmp_t * p) { if(!p) return NATPMP_ERR_INVALIDARGS; @@ -79,7 +86,7 @@ int closenatpmp(natpmp_t * p) return 0; } -static int sendpendingrequest(natpmp_t * p) +int sendpendingrequest(natpmp_t * p) { int r; /* struct sockaddr_in addr;*/ @@ -95,7 +102,7 @@ static int sendpendingrequest(natpmp_t * p) return (r<0) ? NATPMP_ERR_SENDERR : r; } -static int sendnatpmprequest(natpmp_t * p) +int sendnatpmprequest(natpmp_t * p) { int n; if(!p) @@ -113,7 +120,7 @@ static int sendnatpmprequest(natpmp_t * p) return n; } -int getnatpmprequesttimeout(natpmp_t * p, struct timeval * timeout) +LIBSPEC int getnatpmprequesttimeout(natpmp_t * p, struct timeval * timeout) { struct timeval now; if(!p || !timeout) @@ -131,7 +138,7 @@ int getnatpmprequesttimeout(natpmp_t * p, struct timeval * timeout) return 0; } -int sendpublicaddressrequest(natpmp_t * p) +LIBSPEC int sendpublicaddressrequest(natpmp_t * p) { if(!p) return NATPMP_ERR_INVALIDARGS; @@ -143,7 +150,7 @@ int sendpublicaddressrequest(natpmp_t * p) return sendnatpmprequest(p); } -int sendnewportmappingrequest(natpmp_t * p, int protocol, +LIBSPEC int sendnewportmappingrequest(natpmp_t * p, int protocol, uint16_t privateport, uint16_t publicport, uint32_t lifetime) { @@ -160,7 +167,7 @@ int sendnewportmappingrequest(natpmp_t * p, int protocol, return sendnatpmprequest(p); } -static int readnatpmpresponse(natpmp_t * p, natpmpresp_t * response) +LIBSPEC int readnatpmpresponse(natpmp_t * p, natpmpresp_t * response) { unsigned char buf[16]; struct sockaddr_in addr; @@ -268,7 +275,7 @@ int readnatpmpresponseorretry(natpmp_t * p, natpmpresp_t * response) } #ifdef ENABLE_STRNATPMPERR -const char * strnatpmperr(int r) +LIBSPEC const char * strnatpmperr(int r) { const char * s; switch(r) { diff --git a/libportfwd/third-party/libnatpmp-20100202/natpmp.def b/libportfwd/third-party/libnatpmp-20100202/natpmp.def new file mode 100644 index 000000000..cd110033f --- /dev/null +++ b/libportfwd/third-party/libnatpmp-20100202/natpmp.def @@ -0,0 +1,11 @@ +LIBRARY +; libnatpmp library + +EXPORTS + initnatpmp + closenatpmp + sendpublicaddressrequest + sendnewportmappingrequest + getnatpmprequesttimeout + readnatpmpresponseorretry + strnatpmperr diff --git a/libportfwd/third-party/libnatpmp/natpmp.h b/libportfwd/third-party/libnatpmp-20100202/natpmp.h similarity index 96% rename from libportfwd/third-party/libnatpmp/natpmp.h rename to libportfwd/third-party/libnatpmp-20100202/natpmp.h index d1f09c26a..d4c513ee5 100644 --- a/libportfwd/third-party/libnatpmp/natpmp.h +++ b/libportfwd/third-party/libnatpmp-20100202/natpmp.h @@ -1,4 +1,4 @@ -/* $Id: natpmp.h,v 1.11 2009/02/27 22:38:05 nanard Exp $ */ +/* $Id: natpmp.h,v 1.12 2009/12/19 12:00:00 nanard Exp $ */ /* libnatpmp * Copyright (c) 2007-2008, Thomas BERNARD * http://miniupnp.free.fr/libnatpmp.html @@ -21,10 +21,17 @@ #define NATPMP_PORT (5351) #include +#if !defined(_MSC_VER) #include +#endif #ifdef WIN32 #include +#if !defined(_MSC_VER) #include +#else +typedef unsigned long uint32_t; +typedef unsigned short uint16_t; +#endif #define in_addr_t uint32_t #include "declspec.h" #else diff --git a/libportfwd/third-party/libnatpmp-20100202/natpmpc.c b/libportfwd/third-party/libnatpmp-20100202/natpmpc.c new file mode 100644 index 000000000..3cc852baa --- /dev/null +++ b/libportfwd/third-party/libnatpmp-20100202/natpmpc.c @@ -0,0 +1,210 @@ +/* $Id: natpmpc.c,v 1.7 2009/12/19 12:00:00 nanard Exp $ */ +/* libnatpmp + * Copyright (c) 2007-2008, Thomas BERNARD + * http://miniupnp.free.fr/libnatpmp.html + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include +#include +#include +#if defined(_MSC_VER) +#if _MSC_VER >= 1400 +#define strcasecmp _stricmp +#else +#define strcasecmp stricmp +#endif +#else +#include +#endif +#ifdef WIN32 +#include +#else +#include +#include +#endif +#include "natpmp.h" + +void usage(FILE * out, const char * argv0) +{ + fprintf(out, "Usage :\n"); + fprintf(out, " %s\n", argv0); + fprintf(out, "\tdisplay the public IP address.\n"); + fprintf(out, " %s -h\n", argv0); + fprintf(out, "\tdisplay this help screen.\n"); + fprintf(out, " %s -a [lifetime]\n", argv0); + fprintf(out, "\tadd a port mapping.\n"); + fprintf(out, "\n In order to remove a mapping, set it with a lifetime of 0 seconds.\n"); + fprintf(out, " To remove all mappings for your machine, use 0 as private port and lifetime.\n"); +} + +/* sample code for using libnatpmp */ +int main(int argc, char * * argv) +{ + natpmp_t natpmp; + natpmpresp_t response; + int r; + int sav_errno; + struct timeval timeout; + fd_set fds; + int i; + int protocol = 0; + uint16_t privateport = 0; + uint16_t publicport = 0; + uint32_t lifetime = 3600; + int command = 0; + +#ifdef WIN32 + WSADATA wsaData; + int nResult = WSAStartup(MAKEWORD(2,2), &wsaData); + if(nResult != NO_ERROR) + { + fprintf(stderr, "WSAStartup() failed.\n"); + return -1; + } +#endif + + /* argument parsing */ + for(i=1; i= i) { + i++; + if(1 != sscanf(argv[i], "%u", &lifetime)) { + fprintf(stderr, "%s is not a correct 32bits unsigned integer\n", argv[i]); + } + } + break; + default: + fprintf(stderr, "Unknown option %s\n", argv[i]); + usage(stderr, argv[0]); + return 1; + } + } else { + fprintf(stderr, "Unknown option %s\n", argv[i]); + usage(stderr, argv[0]); + return 1; + } + } + + /* initnatpmp() */ + r = initnatpmp(&natpmp); + printf("initnatpmp() returned %d (%s)\n", r, r?"FAILED":"SUCCESS"); + if(r<0) + return 1; + + /* sendpublicaddressrequest() */ + r = sendpublicaddressrequest(&natpmp); + printf("sendpublicaddressrequest returned %d (%s)\n", + r, r==2?"SUCCESS":"FAILED"); + if(r<0) + return 1; + + do { + FD_ZERO(&fds); + FD_SET(natpmp.s, &fds); + getnatpmprequesttimeout(&natpmp, &timeout); + select(FD_SETSIZE, &fds, NULL, NULL, &timeout); + r = readnatpmpresponseorretry(&natpmp, &response); + sav_errno = errno; + printf("readnatpmpresponseorretry returned %d (%s)\n", + r, r==0?"OK":(r==NATPMP_TRYAGAIN?"TRY AGAIN":"FAILED")); + if(r<0 && r!=NATPMP_TRYAGAIN) { +#ifdef ENABLE_STRNATPMPERR + fprintf(stderr, "readnatpmpresponseorretry() failed : %s\n", + strnatpmperr(r)); +#endif + fprintf(stderr, " errno=%d '%s'\n", + sav_errno, strerror(sav_errno)); + } + } while(r==NATPMP_TRYAGAIN); + if(r<0) + return 1; + + /* TODO : check that response.type == 0 */ + printf("Public IP address : %s\n", inet_ntoa(response.pnu.publicaddress.addr)); + printf("epoch = %u\n", response.epoch); + + if(command == 'a') { + /* sendnewportmappingrequest() */ + r = sendnewportmappingrequest(&natpmp, protocol, + privateport, publicport, + lifetime); + printf("sendnewportmappingrequest returned %d (%s)\n", + r, r==12?"SUCCESS":"FAILED"); + if(r < 0) + return 1; + + do { + FD_ZERO(&fds); + FD_SET(natpmp.s, &fds); + getnatpmprequesttimeout(&natpmp, &timeout); + select(FD_SETSIZE, &fds, NULL, NULL, &timeout); + r = readnatpmpresponseorretry(&natpmp, &response); + printf("readnatpmpresponseorretry returned %d (%s)\n", + r, r==0?"OK":(r==NATPMP_TRYAGAIN?"TRY AGAIN":"FAILED")); + } while(r==NATPMP_TRYAGAIN); + if(r<0) { +#ifdef ENABLE_STRNATPMPERR + fprintf(stderr, "readnatpmpresponseorretry() failed : %s\n", + strnatpmperr(r)); +#endif + return 1; + } + + printf("Mapped public port %hu protocol %s to local port %hu " + "liftime %u\n", + response.pnu.newportmapping.mappedpublicport, + response.type == NATPMP_RESPTYPE_UDPPORTMAPPING ? "UDP" : + (response.type == NATPMP_RESPTYPE_TCPPORTMAPPING ? "TCP" : + "UNKNOWN"), + response.pnu.newportmapping.privateport, + response.pnu.newportmapping.lifetime); + printf("epoch = %u\n", response.epoch); + } + + r = closenatpmp(&natpmp); + printf("closenatpmp() returned %d (%s)\n", r, r==0?"SUCCESS":"FAILED"); + if(r<0) + return 1; + + return 0; +} + diff --git a/libportfwd/third-party/libnatpmp-20100202/setup.py b/libportfwd/third-party/libnatpmp-20100202/setup.py new file mode 100644 index 000000000..1386bf216 --- /dev/null +++ b/libportfwd/third-party/libnatpmp-20100202/setup.py @@ -0,0 +1,15 @@ +#! /usr/bin/python +# $Id: setup.py,v 1.2 2009/06/04 21:37:06 nanard Exp $ +# +# python script to build the libnatpmp module under unix +# +# replace libnatpmp.a by libnatpmp.so for shared library usage +from distutils.core import setup, Extension +setup(name="libnatpmp", version="1.0", + ext_modules=[ + Extension(name="libnatpmp", sources=["libnatpmpmodule.c"], + extra_objects=["libnatpmp.a"], + define_macros=[('ENABLE_STRNATPMPERR', None)] + )] + ) + diff --git a/libportfwd/third-party/libnatpmp-20100202/setupmingw32.py b/libportfwd/third-party/libnatpmp-20100202/setupmingw32.py new file mode 100644 index 000000000..87491b6b9 --- /dev/null +++ b/libportfwd/third-party/libnatpmp-20100202/setupmingw32.py @@ -0,0 +1,14 @@ +#! /usr/bin/python +# $Id: setupmingw32.py,v 1.2 2009/06/04 21:37:06 nanard Exp $ +# python script to build the miniupnpc module under windows +# +from distutils.core import setup, Extension +setup(name="libnatpmp", version="1.0", + ext_modules=[ + Extension(name="libnatpmp", sources=["libnatpmpmodule.c"], + libraries=["ws2_32"], + extra_objects=["libnatpmp.a"], + define_macros=[('ENABLE_STRNATPMPERR', None)] + )] + ) + diff --git a/libportfwd/third-party/libnatpmp-20100202/testgetgateway.c b/libportfwd/third-party/libnatpmp-20100202/testgetgateway.c new file mode 100644 index 000000000..d559683a6 --- /dev/null +++ b/libportfwd/third-party/libnatpmp-20100202/testgetgateway.c @@ -0,0 +1,42 @@ +/* $Id: testgetgateway.c,v 1.4 2008/07/02 22:33:06 nanard Exp $ */ +/* libnatpmp + * Copyright (c) 2007, Thomas BERNARD + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include +#ifdef WIN32 +#include +#else +#include +#include +#endif +#include "getgateway.h" + +int main(int argc, char * * argv) +{ + struct in_addr gatewayaddr; + int r; +#ifdef WIN32 + uint32_t temp = 0; + r = getdefaultgateway(&temp); + gatewayaddr.S_un.S_addr = temp; +#else + r = getdefaultgateway(&(gatewayaddr.s_addr)); +#endif + if(r>=0) + printf("default gateway : %s\n", inet_ntoa(gatewayaddr)); + else + fprintf(stderr, "getdefaultgateway() failed\n"); + return 0; +} + diff --git a/libportfwd/third-party/libnatpmp-20100202/wingettimeofday.c b/libportfwd/third-party/libnatpmp-20100202/wingettimeofday.c new file mode 100644 index 000000000..5b1b8a63a --- /dev/null +++ b/libportfwd/third-party/libnatpmp-20100202/wingettimeofday.c @@ -0,0 +1,50 @@ +/* $Id: wingettimeofday.c,v 1.3 2009/12/19 12:00:00 nanard Exp $ */ +/* libnatpmp + * Copyright (c) 2007-2008, Thomas BERNARD + * http://miniupnp.free.fr/libnatpmp.html + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#ifdef WIN32 +#if defined(_MSC_VER) +struct timeval { + long tv_sec; + long tv_usec; +}; +#else +#include +#endif + +typedef struct _FILETIME { + unsigned long dwLowDateTime; + unsigned long dwHighDateTime; +} FILETIME; + +void __stdcall GetSystemTimeAsFileTime(FILETIME*); + +//int gettimeofday(struct timeval* p, void* tz /* IGNORED */); + +int gettimeofday(struct timeval* p, void* tz /* IGNORED */) { + union { + long long ns100; /*time since 1 Jan 1601 in 100ns units */ + FILETIME ft; + } _now; + + if(!p) + return -1; + GetSystemTimeAsFileTime( &(_now.ft) ); + p->tv_usec =(long)((_now.ns100 / 10LL) % 1000000LL ); + p->tv_sec = (long)((_now.ns100-(116444736000000000LL))/10000000LL); + return 0; +} +#endif + diff --git a/libportfwd/third-party/libnatpmp-20100202/wingettimeofday.h b/libportfwd/third-party/libnatpmp-20100202/wingettimeofday.h new file mode 100644 index 000000000..ed6c599ee --- /dev/null +++ b/libportfwd/third-party/libnatpmp-20100202/wingettimeofday.h @@ -0,0 +1,27 @@ +/* $Id: wingettimeofday.h,v 1.1 2009/12/19 12:02:42 nanard Exp $ */ +/* libnatpmp + * Copyright (c) 2007-2008, Thomas BERNARD + * http://miniupnp.free.fr/libnatpmp.html + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#ifndef __WINGETTIMEOFDAY_H__ +#define __WINGETTIMEOFDAY_H__ +#ifdef WIN32 +#if defined(_MSC_VER) +#include +#else +#include +#endif +int gettimeofday(struct timeval* p, void* tz /* IGNORED */); +#endif +#endif diff --git a/libportfwd/third-party/libnatpmp/.deps/getgateway.Po b/libportfwd/third-party/libnatpmp/.deps/getgateway.Po deleted file mode 100644 index afb5e4801..000000000 --- a/libportfwd/third-party/libnatpmp/.deps/getgateway.Po +++ /dev/null @@ -1,133 +0,0 @@ -getgateway.o: getgateway.c /usr/include/stdio.h /usr/include/features.h \ - /usr/include/sys/cdefs.h /usr/include/bits/wordsize.h \ - /usr/include/gnu/stubs.h /usr/include/gnu/stubs-64.h \ - /usr/lib/gcc/x86_64-linux-gnu/4.3.3/include/stddef.h \ - /usr/include/bits/types.h /usr/include/bits/typesizes.h \ - /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \ - /usr/lib/gcc/x86_64-linux-gnu/4.3.3/include/stdarg.h \ - /usr/include/bits/stdio_lim.h /usr/include/bits/sys_errlist.h \ - /usr/include/bits/stdio.h /usr/include/bits/stdio2.h \ - /usr/include/ctype.h /usr/include/endian.h /usr/include/bits/endian.h \ - /usr/include/bits/byteswap.h /usr/include/netinet/in.h \ - /usr/include/stdint.h /usr/include/bits/wchar.h \ - /usr/include/sys/socket.h /usr/include/sys/uio.h \ - /usr/include/sys/types.h /usr/include/time.h /usr/include/sys/select.h \ - /usr/include/bits/select.h /usr/include/bits/sigset.h \ - /usr/include/bits/time.h /usr/include/sys/sysmacros.h \ - /usr/include/bits/pthreadtypes.h /usr/include/bits/uio.h \ - /usr/include/bits/socket.h /usr/include/bits/sockaddr.h \ - /usr/include/asm/socket.h /usr/include/asm/sockios.h \ - /usr/include/bits/socket2.h /usr/include/bits/in.h \ - /usr/include/sys/param.h \ - /usr/lib/gcc/x86_64-linux-gnu/4.3.3/include-fixed/limits.h \ - /usr/lib/gcc/x86_64-linux-gnu/4.3.3/include-fixed/syslimits.h \ - /usr/include/limits.h /usr/include/bits/posix1_lim.h \ - /usr/include/bits/local_lim.h /usr/include/linux/limits.h \ - /usr/include/bits/posix2_lim.h /usr/include/linux/param.h \ - /usr/include/asm/param.h getgateway.h declspec.h - -/usr/include/stdio.h: - -/usr/include/features.h: - -/usr/include/sys/cdefs.h: - -/usr/include/bits/wordsize.h: - -/usr/include/gnu/stubs.h: - -/usr/include/gnu/stubs-64.h: - -/usr/lib/gcc/x86_64-linux-gnu/4.3.3/include/stddef.h: - -/usr/include/bits/types.h: - -/usr/include/bits/typesizes.h: - -/usr/include/libio.h: - -/usr/include/_G_config.h: - -/usr/include/wchar.h: - -/usr/lib/gcc/x86_64-linux-gnu/4.3.3/include/stdarg.h: - -/usr/include/bits/stdio_lim.h: - -/usr/include/bits/sys_errlist.h: - -/usr/include/bits/stdio.h: - -/usr/include/bits/stdio2.h: - -/usr/include/ctype.h: - -/usr/include/endian.h: - -/usr/include/bits/endian.h: - -/usr/include/bits/byteswap.h: - -/usr/include/netinet/in.h: - -/usr/include/stdint.h: - -/usr/include/bits/wchar.h: - -/usr/include/sys/socket.h: - -/usr/include/sys/uio.h: - -/usr/include/sys/types.h: - -/usr/include/time.h: - -/usr/include/sys/select.h: - -/usr/include/bits/select.h: - -/usr/include/bits/sigset.h: - -/usr/include/bits/time.h: - -/usr/include/sys/sysmacros.h: - -/usr/include/bits/pthreadtypes.h: - -/usr/include/bits/uio.h: - -/usr/include/bits/socket.h: - -/usr/include/bits/sockaddr.h: - -/usr/include/asm/socket.h: - -/usr/include/asm/sockios.h: - -/usr/include/bits/socket2.h: - -/usr/include/bits/in.h: - -/usr/include/sys/param.h: - -/usr/lib/gcc/x86_64-linux-gnu/4.3.3/include-fixed/limits.h: - -/usr/lib/gcc/x86_64-linux-gnu/4.3.3/include-fixed/syslimits.h: - -/usr/include/limits.h: - -/usr/include/bits/posix1_lim.h: - -/usr/include/bits/local_lim.h: - -/usr/include/linux/limits.h: - -/usr/include/bits/posix2_lim.h: - -/usr/include/linux/param.h: - -/usr/include/asm/param.h: - -getgateway.h: - -declspec.h: diff --git a/libportfwd/third-party/libnatpmp/.deps/natpmp.Po b/libportfwd/third-party/libnatpmp/.deps/natpmp.Po deleted file mode 100644 index aeefa79c1..000000000 --- a/libportfwd/third-party/libnatpmp/.deps/natpmp.Po +++ /dev/null @@ -1,134 +0,0 @@ -natpmp.o: natpmp.c /usr/include/string.h /usr/include/features.h \ - /usr/include/sys/cdefs.h /usr/include/bits/wordsize.h \ - /usr/include/gnu/stubs.h /usr/include/gnu/stubs-64.h \ - /usr/lib/gcc/x86_64-linux-gnu/4.3.3/include/stddef.h \ - /usr/include/bits/string.h /usr/include/bits/string2.h \ - /usr/include/endian.h /usr/include/bits/endian.h \ - /usr/include/bits/byteswap.h /usr/include/bits/types.h \ - /usr/include/bits/typesizes.h /usr/include/stdlib.h \ - /usr/include/bits/string3.h /usr/include/time.h \ - /usr/include/bits/time.h /usr/include/sys/time.h \ - /usr/include/sys/select.h /usr/include/bits/select.h \ - /usr/include/bits/sigset.h /usr/include/errno.h \ - /usr/include/bits/errno.h /usr/include/linux/errno.h \ - /usr/include/asm/errno.h /usr/include/asm-generic/errno.h \ - /usr/include/asm-generic/errno-base.h /usr/include/unistd.h \ - /usr/include/bits/posix_opt.h /usr/include/bits/confname.h \ - /usr/include/getopt.h /usr/include/bits/unistd.h /usr/include/fcntl.h \ - /usr/include/bits/fcntl.h /usr/include/sys/types.h \ - /usr/include/sys/sysmacros.h /usr/include/bits/pthreadtypes.h \ - /usr/include/bits/fcntl2.h /usr/include/sys/socket.h \ - /usr/include/sys/uio.h /usr/include/bits/uio.h \ - /usr/include/bits/socket.h /usr/include/bits/sockaddr.h \ - /usr/include/asm/socket.h /usr/include/asm/sockios.h \ - /usr/include/bits/socket2.h natpmp.h /usr/include/netinet/in.h \ - /usr/include/stdint.h /usr/include/bits/wchar.h /usr/include/bits/in.h \ - getgateway.h declspec.h - -/usr/include/string.h: - -/usr/include/features.h: - -/usr/include/sys/cdefs.h: - -/usr/include/bits/wordsize.h: - -/usr/include/gnu/stubs.h: - -/usr/include/gnu/stubs-64.h: - -/usr/lib/gcc/x86_64-linux-gnu/4.3.3/include/stddef.h: - -/usr/include/bits/string.h: - -/usr/include/bits/string2.h: - -/usr/include/endian.h: - -/usr/include/bits/endian.h: - -/usr/include/bits/byteswap.h: - -/usr/include/bits/types.h: - -/usr/include/bits/typesizes.h: - -/usr/include/stdlib.h: - -/usr/include/bits/string3.h: - -/usr/include/time.h: - -/usr/include/bits/time.h: - -/usr/include/sys/time.h: - -/usr/include/sys/select.h: - -/usr/include/bits/select.h: - -/usr/include/bits/sigset.h: - -/usr/include/errno.h: - -/usr/include/bits/errno.h: - -/usr/include/linux/errno.h: - -/usr/include/asm/errno.h: - -/usr/include/asm-generic/errno.h: - -/usr/include/asm-generic/errno-base.h: - -/usr/include/unistd.h: - -/usr/include/bits/posix_opt.h: - -/usr/include/bits/confname.h: - -/usr/include/getopt.h: - -/usr/include/bits/unistd.h: - -/usr/include/fcntl.h: - -/usr/include/bits/fcntl.h: - -/usr/include/sys/types.h: - -/usr/include/sys/sysmacros.h: - -/usr/include/bits/pthreadtypes.h: - -/usr/include/bits/fcntl2.h: - -/usr/include/sys/socket.h: - -/usr/include/sys/uio.h: - -/usr/include/bits/uio.h: - -/usr/include/bits/socket.h: - -/usr/include/bits/sockaddr.h: - -/usr/include/asm/socket.h: - -/usr/include/asm/sockios.h: - -/usr/include/bits/socket2.h: - -natpmp.h: - -/usr/include/netinet/in.h: - -/usr/include/stdint.h: - -/usr/include/bits/wchar.h: - -/usr/include/bits/in.h: - -getgateway.h: - -declspec.h: diff --git a/libportfwd/third-party/libnatpmp/README b/libportfwd/third-party/libnatpmp/README deleted file mode 100644 index 50fdd1093..000000000 --- a/libportfwd/third-party/libnatpmp/README +++ /dev/null @@ -1,4 +0,0 @@ -libnatpmp is written by Thomas Bernard. -Its homepage is http://miniupnp.tuxfamily.org/libnatpmp.html -This code is from the libnatpmp-20090310 snapshot - diff --git a/libportfwd/third-party/miniupnpc-20090605/Changelog.txt b/libportfwd/third-party/miniupnpc-1.4.20100609/Changelog.txt similarity index 67% rename from libportfwd/third-party/miniupnpc-20090605/Changelog.txt rename to libportfwd/third-party/miniupnpc-1.4.20100609/Changelog.txt index e34543fec..dc8218b1c 100644 --- a/libportfwd/third-party/miniupnpc-20090605/Changelog.txt +++ b/libportfwd/third-party/miniupnpc-1.4.20100609/Changelog.txt @@ -1,6 +1,106 @@ -$Id: Changelog.txt,v 1.80 2009/04/17 21:21:19 nanard Exp $ +$Id: Changelog.txt,v 1.117 2010/06/09 10:59:08 nanard Exp $ miniUPnP client Changelog. +2010/06/09: + update to python module to match modification made on 2010/04/05 + update to Java test code to match modification made on 2010/04/05 + all UPNP_* function now return an error if the SOAP request failed + at HTTP level. + +2010/04/17: + Using GetBestRoute() under win32 in order to find the + right interface to use. + +2010/04/12: + Retrying with HTTP/1.1 if HTTP/1.0 failed. see + http://miniupnp.tuxfamily.org/forum/viewtopic.php?p=1703 + +2010/04/07: + avoid returning duplicates in upnpDiscover() + +2010/04/05: + Create a connecthostport.h/.c with connecthostport() function + and use it in miniwget and miniupnpc. + Use getnameinfo() instead of inet_ntop or inet_ntoa + Work to make miniupnpc IPV6 compatible... + Add java test code. + Big changes in order to support device having both WANIPConnection + and WANPPPConnection. + +2010/04/04: + Use getaddrinfo() instead of gethostbyname() in miniwget. + +2010/01/06: + #define _DARWIN_C_SOURCE for Mac OS X + +2009/12/19: + Improve MinGW32 build + +2009/12/11: + adding a MSVC9 project to build the static library and executable + +2009/12/10: + Fixing some compilation stuff for Windows/MinGW + +2009/12/07: + adaptations in Makefile and updateminiupnpcstring.sh for AmigaOS + some fixes for Windows when using virtual ethernet adapters (it is the + case with VMWare installed). + +2009/12/04: + some fixes for AmigaOS compilation + Changed HTTP version to HTTP/1.0 for Soap too (to prevent chunked + transfer encoding) + +2009/12/03: + updating printIDG and testigddescparse.c for debug. + modifications to compile under AmigaOS + adding a testminiwget program + Changed miniwget to advertise itself as HTTP/1.0 to prevent chunked + transfer encoding + +2009/11/26: + fixing updateminiupnpcstrings.sh to take into account + which command that does not return an error code. + +VERSION 1.4 : released 2009/10/30 + +2009/10/16: + using Py_BEGIN_ALLOW_THREADS and Py_END_ALLOW_THREADS in python module. + +2009/10/10: + Some fixes for compilation under Solaris + compilation fixes : http://miniupnp.tuxfamily.org/forum/viewtopic.php?p=1464 + +2009/09/21: + fixing the code to ignore EINTR during connect() calls. + +2009/08/07: + Set socket timeout for connect() + Some cleanup in miniwget.c + +2009/08/04: + remove multiple redirections with -d in upnpc.c + Print textual error code in upnpc.c + Ignore EINTR during the connect() and poll() calls. + +2009/07/29: + fix in updateminiupnpcstrings.sh if OS name contains "/" + Sending a correct value for MX: field in SSDP request + +2009/07/20: + Change the Makefile to compile under Mac OS X + Fixed a stackoverflow in getDevicesFromMiniSSDPD() + +2009/07/09: + Compile under Haiku + generate miniupnpcstrings.h.in from miniupnpcstrings.h + +2009/06/04: + patching to compile under CygWin and cross compile for minGW + +VERSION 1.3 : + 2009/04/17: updating python module Use strtoull() when using C99 diff --git a/libportfwd/third-party/miniupnpc-1.4.20100609/LICENSE b/libportfwd/third-party/miniupnpc-1.4.20100609/LICENSE new file mode 100644 index 000000000..2b561fb4f --- /dev/null +++ b/libportfwd/third-party/miniupnpc-1.4.20100609/LICENSE @@ -0,0 +1,26 @@ +Copyright (c) 2005-2009, 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. + diff --git a/libportfwd/third-party/miniupnpc-20090605/README b/libportfwd/third-party/miniupnpc-1.4.20100609/README similarity index 80% rename from libportfwd/third-party/miniupnpc-20090605/README rename to libportfwd/third-party/miniupnpc-1.4.20100609/README index 3aa2a361b..429507062 100644 --- a/libportfwd/third-party/miniupnpc-20090605/README +++ b/libportfwd/third-party/miniupnpc-1.4.20100609/README @@ -1,9 +1,9 @@ Project: miniupnp Project web page: http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ Author: Thomas Bernard -Copyright (c) 2005-2008 Thomas Bernard +Copyright (c) 2005-2009 Thomas Bernard This software is subject to the conditions detailed in the -LICENCE file provided within this distribution. +LICENSE file provided within this distribution. For the comfort of Win32 users, bsdqueue.h is included in the distribution. Its licence is included in the header of the file. @@ -11,10 +11,12 @@ bsdqueue.h is a copy of the sys/queue.h of an OpenBSD system. * miniupnp Client * -To compile, simply run 'gmake' (could be 'make'). +To compile, simply run 'gmake' (could be 'make' on your system). Under win32, to compile with MinGW, type "mingw32make.bat". The compilation is known to work under linux, FreeBSD, -OpenBSD, MacOS X and cygwin. +OpenBSD, MacOS X, AmigaOS and cygwin. +The official AmigaOS4.1 SDK was used for AmigaOS4 and GeekGadgets for AmigaOS3. + To install the library and headers on the system use : > su > make install @@ -25,7 +27,7 @@ alternatively, to install in a specific location, use : upnpc.c is a sample client using the libminiupnpc. To use the libminiupnpc in your application, link it with -libminiupnpc.a and use the following functions found in miniupnpc.h, +libminiupnpc.a (or .so) and use the following functions found in miniupnpc.h, upnpcommands.h and miniwget.h : - upnpDiscover() - miniwget() diff --git a/libportfwd/third-party/miniupnpc-1.4.20100609/VERSION b/libportfwd/third-party/miniupnpc-1.4.20100609/VERSION new file mode 100644 index 000000000..c068b2447 --- /dev/null +++ b/libportfwd/third-party/miniupnpc-1.4.20100609/VERSION @@ -0,0 +1 @@ +1.4 diff --git a/libportfwd/third-party/miniupnpc-20090605/bsdqueue.h b/libportfwd/third-party/miniupnpc-1.4.20100609/bsdqueue.h similarity index 100% rename from libportfwd/third-party/miniupnpc-20090605/bsdqueue.h rename to libportfwd/third-party/miniupnpc-1.4.20100609/bsdqueue.h diff --git a/libportfwd/third-party/miniupnpc-20090605/codelength.h b/libportfwd/third-party/miniupnpc-1.4.20100609/codelength.h similarity index 100% rename from libportfwd/third-party/miniupnpc-20090605/codelength.h rename to libportfwd/third-party/miniupnpc-1.4.20100609/codelength.h diff --git a/libportfwd/third-party/miniupnpc-1.4.20100609/connecthostport.c b/libportfwd/third-party/miniupnpc-1.4.20100609/connecthostport.c new file mode 100644 index 000000000..e52eed09c --- /dev/null +++ b/libportfwd/third-party/miniupnpc-1.4.20100609/connecthostport.c @@ -0,0 +1,221 @@ +/* $Id: connecthostport.c,v 1.2 2010/04/05 00:08:15 nanard Exp $ */ +/* Project : miniupnp + * Author : Thomas Bernard + * Copyright (c) 2010 Thomas Bernard + * This software is subject to the conditions detailed in the + * LICENCE file provided in this distribution. */ + +/* use getaddrinfo() or gethostbyname() + * uncomment the following line in order to use gethostbyname() */ +/* #define USE_GETHOSTBYNAME */ + +#include +#include +#ifdef WIN32 +#include +#include +#include +#define snprintf _snprintf +#define herror +#define socklen_t int +#else /* #ifdef WIN32 */ +#include +#include +#define closesocket close +#include +/* defining MINIUPNPC_IGNORE_EINTR enable the ignore of interruptions + * during the connect() call */ +#define MINIUPNPC_IGNORE_EINTR +#ifndef USE_GETHOSTBYNAME +#include +#include +#endif /* #ifndef USE_GETHOSTBYNAME */ +#endif /* #else WIN32 */ + +/* definition of PRINT_SOCKET_ERROR */ +#ifdef WIN32 +#define PRINT_SOCKET_ERROR(x) printf("Socket error: %s, %d\n", x, WSAGetLastError()); +#else +#define PRINT_SOCKET_ERROR(x) perror(x) +#endif + +#if defined(__amigaos__) || defined(__amigaos4__) +#define herror(A) printf("%s\n", A) +#endif + +#include "connecthostport.h" + +/* connecthostport() + * return a socket connected (TCP) to the host and port + * or -1 in case of error */ +int connecthostport(const char * host, unsigned short port) +{ + int s, n; +#ifdef USE_GETHOSTBYNAME + struct sockaddr_in dest; + struct hostent *hp; +#else /* #ifdef USE_GETHOSTBYNAME */ + char port_str[8]; + struct addrinfo *ai, *p; + struct addrinfo hints; +#endif /* #ifdef USE_GETHOSTBYNAME */ +#ifdef MINIUPNPC_SET_SOCKET_TIMEOUT + struct timeval timeout; +#endif /* #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT */ + +#ifdef USE_GETHOSTBYNAME + hp = gethostbyname(host); + if(hp == NULL) + { + herror(host); + return -1; + } + 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) + { + PRINT_SOCKET_ERROR("socket"); + return -1; + } +#ifdef MINIUPNPC_SET_SOCKET_TIMEOUT + /* setting a 3 seconds timeout for the connect() call */ + timeout.tv_sec = 3; + timeout.tv_usec = 0; + if(setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(struct timeval)) < 0) + { + PRINT_SOCKET_ERROR("setsockopt"); + } + timeout.tv_sec = 3; + timeout.tv_usec = 0; + if(setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(struct timeval)) < 0) + { + PRINT_SOCKET_ERROR("setsockopt"); + } +#endif /* #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT */ + dest.sin_family = AF_INET; + dest.sin_port = htons(port); + n = connect(s, (struct sockaddr *)&dest, sizeof(struct sockaddr_in)); +#ifdef MINIUPNPC_IGNORE_EINTR + while(n < 0 && errno == EINTR) + { + socklen_t len; + fd_set wset; + int err; + FD_ZERO(&wset); + FD_SET(s, &wset); + if((n = select(s + 1, NULL, &wset, NULL, NULL)) == -1 && errno == EINTR) + continue; + /*len = 0;*/ + /*n = getpeername(s, NULL, &len);*/ + len = sizeof(err); + if(getsockopt(s, SOL_SOCKET, SO_ERROR, &err, &len) < 0) { + PRINT_SOCKET_ERROR("getsockopt"); + closesocket(s); + return -1; + } + if(err != 0) { + errno = err; + n = -1; + } + } +#endif /* #ifdef MINIUPNPC_IGNORE_EINTR */ + if(n<0) + { + PRINT_SOCKET_ERROR("connect"); + closesocket(s); + return -1; + } +#else /* #ifdef USE_GETHOSTBYNAME */ + /* use getaddrinfo() instead of gethostbyname() */ + memset(&hints, 0, sizeof(hints)); + /* hints.ai_flags = AI_ADDRCONFIG; */ +#ifdef AI_NUMERICSERV + hints.ai_flags = AI_NUMERICSERV; +#endif + hints.ai_socktype = SOCK_STREAM; + hints.ai_family = AF_UNSPEC; /* AF_INET, AF_INET6 or AF_UNSPEC */ + /* hints.ai_protocol = IPPROTO_TCP; */ + snprintf(port_str, sizeof(port_str), "%hu", port); + n = getaddrinfo(host, port_str, &hints, &ai); + if(n != 0) + { +#ifdef WIN32 + fprintf(stderr, "getaddrinfo() error : %d\n", n); +#else + fprintf(stderr, "getaddrinfo() error : %s\n", gai_strerror(n)); +#endif + return -1; + } + s = -1; + for(p = ai; p; p = p->ai_next) + { + s = socket(p->ai_family, p->ai_socktype, p->ai_protocol); + if(s < 0) + continue; +#ifdef MINIUPNPC_SET_SOCKET_TIMEOUT + /* setting a 3 seconds timeout for the connect() call */ + timeout.tv_sec = 3; + timeout.tv_usec = 0; + if(setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(struct timeval)) < 0) + { + PRINT_SOCKET_ERROR("setsockopt"); + } + timeout.tv_sec = 3; + timeout.tv_usec = 0; + if(setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(struct timeval)) < 0) + { + PRINT_SOCKET_ERROR("setsockopt"); + } +#endif /* #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT */ + n = connect(s, p->ai_addr, p->ai_addrlen); +#ifdef MINIUPNPC_IGNORE_EINTR + while(n < 0 && errno == EINTR) + { + socklen_t len; + fd_set wset; + int err; + FD_ZERO(&wset); + FD_SET(s, &wset); + if((n = select(s + 1, NULL, &wset, NULL, NULL)) == -1 && errno == EINTR) + continue; + /*len = 0;*/ + /*n = getpeername(s, NULL, &len);*/ + len = sizeof(err); + if(getsockopt(s, SOL_SOCKET, SO_ERROR, &err, &len) < 0) { + PRINT_SOCKET_ERROR("getsockopt"); + closesocket(s); + freeaddrinfo(ai); + return -1; + } + if(err != 0) { + errno = err; + n = -1; + } + } +#endif /* #ifdef MINIUPNPC_IGNORE_EINTR */ + if(n < 0) + { + closesocket(s); + continue; + } + else + { + break; + } + } + freeaddrinfo(ai); + if(s < 0) + { + PRINT_SOCKET_ERROR("socket"); + return -1; + } + if(n < 0) + { + PRINT_SOCKET_ERROR("connect"); + return -1; + } +#endif /* #ifdef USE_GETHOSTBYNAME */ + return s; +} + diff --git a/libportfwd/third-party/miniupnpc-1.4.20100609/connecthostport.h b/libportfwd/third-party/miniupnpc-1.4.20100609/connecthostport.h new file mode 100644 index 000000000..57e24eb27 --- /dev/null +++ b/libportfwd/third-party/miniupnpc-1.4.20100609/connecthostport.h @@ -0,0 +1,17 @@ +/* $Id: connecthostport.h,v 1.1 2010/04/04 23:21:03 nanard Exp $ */ +/* Project: miniupnp + * http://miniupnp.free.fr/ + * Author: Thomas Bernard + * Copyright (c) 2010 Thomas Bernard + * This software is subjects to the conditions detailed + * in the LICENCE file provided within this distribution */ +#ifndef __CONNECTHOSTPORT_H__ +#define __CONNECTHOSTPORT_H__ + +/* connecthostport() + * return a socket connected (TCP) to the host and port + * or -1 in case of error */ +int connecthostport(const char * host, unsigned short port); + +#endif + diff --git a/libportfwd/third-party/miniupnpc-20090605/declspec.h b/libportfwd/third-party/miniupnpc-1.4.20100609/declspec.h similarity index 100% rename from libportfwd/third-party/miniupnpc-20090605/declspec.h rename to libportfwd/third-party/miniupnpc-1.4.20100609/declspec.h diff --git a/libportfwd/third-party/miniupnpc-20090605/igd_desc_parse.c b/libportfwd/third-party/miniupnpc-1.4.20100609/igd_desc_parse.c similarity index 54% rename from libportfwd/third-party/miniupnpc-20090605/igd_desc_parse.c rename to libportfwd/third-party/miniupnpc-1.4.20100609/igd_desc_parse.c index e839ff4c1..7440e9f5b 100644 --- a/libportfwd/third-party/miniupnpc-20090605/igd_desc_parse.c +++ b/libportfwd/third-party/miniupnpc-1.4.20100609/igd_desc_parse.c @@ -1,18 +1,15 @@ -/* $Id: igd_desc_parse.c,v 1.8 2008/04/23 11:51:06 nanard Exp $ */ +/* $Id: igd_desc_parse.c,v 1.10 2010/04/05 20:36:59 nanard Exp $ */ /* Project : miniupnp * http://miniupnp.free.fr/ * Author : Thomas Bernard - * Copyright (c) 2005-2008 Thomas Bernard + * Copyright (c) 2005-2010 Thomas Bernard * This software is subject to the conditions detailed in the - * LICENCE file provided in this distribution. - * */ + * LICENCE file provided in this distribution. */ + #include "igd_desc_parse.h" #include #include -/* TODO : rewrite this code so it correctly handle descriptions with - * both WANIPConnection and/or WANPPPConnection */ - /* Start element handler : * update nesting level counter and copy element name */ void IGDstartelt(void * d, const char * name, int l) @@ -22,10 +19,10 @@ void IGDstartelt(void * d, const char * name, int l) datas->cureltname[l] = '\0'; datas->level++; if( (l==7) && !memcmp(name, "service", l) ) { - datas->controlurl_tmp[0] = '\0'; - datas->eventsuburl_tmp[0] = '\0'; - datas->scpdurl_tmp[0] = '\0'; - datas->servicetype_tmp[0] = '\0'; + datas->tmp.controlurl[0] = '\0'; + datas->tmp.eventsuburl[0] = '\0'; + datas->tmp.scpdurl[0] = '\0'; + datas->tmp.servicetype[0] = '\0'; } } @@ -46,20 +43,18 @@ void IGDendelt(void * d, const char * name, int l) "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1")) datas->state ++; */ - if(0==strcmp(datas->servicetype_tmp, + if(0==strcmp(datas->tmp.servicetype, "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1")) { - memcpy(datas->controlurl_CIF, datas->controlurl_tmp, MINIUPNPC_URL_MAXSIZE); - memcpy(datas->eventsuburl_CIF, datas->eventsuburl_tmp, MINIUPNPC_URL_MAXSIZE); - memcpy(datas->scpdurl_CIF, datas->scpdurl_tmp, MINIUPNPC_URL_MAXSIZE); - memcpy(datas->servicetype_CIF, datas->servicetype_tmp, MINIUPNPC_URL_MAXSIZE); - } else if(0==strcmp(datas->servicetype_tmp, + memcpy(&datas->CIF, &datas->tmp, sizeof(struct IGDdatas_service)); + } else if(0==strcmp(datas->tmp.servicetype, "urn:schemas-upnp-org:service:WANIPConnection:1") - || 0==strcmp(datas->servicetype_tmp, + || 0==strcmp(datas->tmp.servicetype, "urn:schemas-upnp-org:service:WANPPPConnection:1") ) { - memcpy(datas->controlurl, datas->controlurl_tmp, MINIUPNPC_URL_MAXSIZE); - memcpy(datas->eventsuburl, datas->eventsuburl_tmp, MINIUPNPC_URL_MAXSIZE); - memcpy(datas->scpdurl, datas->scpdurl_tmp, MINIUPNPC_URL_MAXSIZE); - memcpy(datas->servicetype, datas->servicetype_tmp, MINIUPNPC_URL_MAXSIZE); + if(datas->first.servicetype[0] == '\0') { + memcpy(&datas->first, &datas->tmp, sizeof(struct IGDdatas_service)); + } else { + memcpy(&datas->second, &datas->tmp, sizeof(struct IGDdatas_service)); + } } } } @@ -75,13 +70,13 @@ void IGDdata(void * d, const char * data, int l) if( !strcmp(datas->cureltname, "URLBase") ) dstmember = datas->urlbase; else if( !strcmp(datas->cureltname, "serviceType") ) - dstmember = datas->servicetype_tmp; + dstmember = datas->tmp.servicetype; else if( !strcmp(datas->cureltname, "controlURL") ) - dstmember = datas->controlurl_tmp; + dstmember = datas->tmp.controlurl; else if( !strcmp(datas->cureltname, "eventSubURL") ) - dstmember = datas->eventsuburl_tmp; + dstmember = datas->tmp.eventsuburl; else if( !strcmp(datas->cureltname, "SCPDURL") ) - dstmember = datas->scpdurl_tmp; + dstmember = datas->tmp.scpdurl; /* else if( !strcmp(datas->cureltname, "deviceType") ) dstmember = datas->devicetype_tmp;*/ if(dstmember) @@ -95,19 +90,25 @@ void IGDdata(void * d, const char * data, int l) void printIGD(struct IGDdatas * d) { - printf("urlbase = %s\n", d->urlbase); + 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(" deviceType = '%s'\n", d->CIF.devicetype);*/ + printf(" serviceType = '%s'\n", d->CIF.servicetype); + printf(" controlURL = '%s'\n", d->CIF.controlurl); + printf(" eventSubURL = '%s'\n", d->CIF.eventsuburl); + printf(" SCPDURL = '%s'\n", d->CIF.scpdurl); printf("WAN Connection Device (IP or PPP Connection):\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); + /*printf(" deviceType = '%s'\n", d->first.devicetype);*/ + printf(" servicetype = '%s'\n", d->first.servicetype); + printf(" controlURL = '%s'\n", d->first.controlurl); + printf(" eventSubURL = '%s'\n", d->first.eventsuburl); + printf(" SCPDURL = '%s'\n", d->first.scpdurl); + printf("secondary WAN Connection Device (IP or PPP Connection):\n"); + /*printf(" deviceType = '%s'\n", d->second.devicetype);*/ + printf(" servicetype = '%s'\n", d->second.servicetype); + printf(" controlURL = '%s'\n", d->second.controlurl); + printf(" eventSubURL = '%s'\n", d->second.eventsuburl); + printf(" SCPDURL = '%s'\n", d->second.scpdurl); } diff --git a/libportfwd/third-party/miniupnpc-20090605/igd_desc_parse.h b/libportfwd/third-party/miniupnpc-1.4.20100609/igd_desc_parse.h similarity index 65% rename from libportfwd/third-party/miniupnpc-20090605/igd_desc_parse.h rename to libportfwd/third-party/miniupnpc-1.4.20100609/igd_desc_parse.h index aabcb087d..40cca60b2 100644 --- a/libportfwd/third-party/miniupnpc-20090605/igd_desc_parse.h +++ b/libportfwd/third-party/miniupnpc-1.4.20100609/igd_desc_parse.h @@ -1,8 +1,8 @@ -/* $Id: igd_desc_parse.h,v 1.6 2008/04/23 11:51:07 nanard Exp $ */ +/* $Id: igd_desc_parse.h,v 1.7 2010/04/05 20:36:59 nanard Exp $ */ /* Project : miniupnp * http://miniupnp.free.fr/ * Author : Thomas Bernard - * Copyright (c) 2005-2008 Thomas Bernard + * Copyright (c) 2005-2010 Thomas Bernard * This software is subject to the conditions detailed in the * LICENCE file provided in this distribution. * */ @@ -12,30 +12,28 @@ /* Structure to store the result of the parsing of UPnP * descriptions of Internet Gateway Devices */ #define MINIUPNPC_URL_MAXSIZE (128) +struct IGDdatas_service { + 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];*/ +}; + struct IGDdatas { char cureltname[MINIUPNPC_URL_MAXSIZE]; char urlbase[MINIUPNPC_URL_MAXSIZE]; int level; /*int state;*/ /* "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1" */ - 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];*/ + struct IGDdatas_service CIF; /* "urn:schemas-upnp-org:service:WANIPConnection:1" * "urn:schemas-upnp-org:service:WANPPPConnection:1" */ - 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];*/ + struct IGDdatas_service first; + /* if both WANIPConnection and WANPPPConnection are present */ + struct IGDdatas_service second; /* tmp */ - char controlurl_tmp[MINIUPNPC_URL_MAXSIZE]; - char eventsuburl_tmp[MINIUPNPC_URL_MAXSIZE]; - char scpdurl_tmp[MINIUPNPC_URL_MAXSIZE]; - char servicetype_tmp[MINIUPNPC_URL_MAXSIZE]; - /*char devicetype_tmp[MINIUPNPC_URL_MAXSIZE];*/ + struct IGDdatas_service tmp; }; void IGDstartelt(void *, const char *, int); diff --git a/libportfwd/third-party/miniupnpc-1.4.20100609/java/JavaBridgeTest.java b/libportfwd/third-party/miniupnpc-1.4.20100609/java/JavaBridgeTest.java new file mode 100644 index 000000000..999001001 --- /dev/null +++ b/libportfwd/third-party/miniupnpc-1.4.20100609/java/JavaBridgeTest.java @@ -0,0 +1,89 @@ +import java.nio.ByteBuffer; +import fr.free.miniupnp.*; + +/** + * + * @author syuu + */ +public class JavaBridgeTest { + public static void main(String[] args) { + int UPNP_DELAY = 2000; + MiniupnpcLibrary miniupnpc = MiniupnpcLibrary.INSTANCE; + UPNPDev devlist = null; + UPNPUrls urls = new UPNPUrls(); + IGDdatas data = new IGDdatas(); + ByteBuffer lanaddr = ByteBuffer.allocate(16); + ByteBuffer intClient = ByteBuffer.allocate(16); + ByteBuffer intPort = ByteBuffer.allocate(6); + int ret; + int i; + + if(args.length < 2) { + System.err.println("Usage : java [...] JavaBridgeTest port protocol"); + System.out.println(" port is numeric, protocol is TCP or UDP"); + return; + } + + devlist = miniupnpc.upnpDiscover(UPNP_DELAY, (String) null, (String) null, 0); + if (devlist != null) { + System.out.println("List of UPNP devices found on the network :"); + for (UPNPDev device = devlist; device != null; device = device.pNext) { + System.out.println("desc: " + device.descURL.getString(0) + " st: " + device.st.getString(0)); + } + if ((i = miniupnpc.UPNP_GetValidIGD(devlist, urls, data, lanaddr, 16)) != 0) { + switch (i) { + case 1: + System.out.println("Found valid IGD : " + urls.controlURL.getString(0)); + break; + case 2: + System.out.println("Found a (not connected?) IGD : " + urls.controlURL.getString(0)); + System.out.println("Trying to continue anyway"); + break; + case 3: + System.out.println("UPnP device found. Is it an IGD ? : " + urls.controlURL.getString(0)); + System.out.println("Trying to continue anyway"); + break; + default: + System.out.println("Found device (igd ?) : " + urls.controlURL.getString(0)); + System.out.println("Trying to continue anyway"); + + } + System.out.println("Local LAN ip address : " + new String(lanaddr.array())); + ByteBuffer externalAddress = ByteBuffer.allocate(16); + miniupnpc.UPNP_GetExternalIPAddress(urls.controlURL.getString(0), + new String(data.first.servicetype), externalAddress); + System.out.println("ExternalIPAddress = " + new String(externalAddress.array())); + ret = miniupnpc.UPNP_AddPortMapping( + urls.controlURL.getString(0), // controlURL + new String(data.first.servicetype), // servicetype + args[0], // external Port + args[0], // internal Port + new String(lanaddr.array()), // internal client + "added via miniupnpc/JAVA !", // description + args[1], // protocol UDP or TCP + null); // remote host (useless) + if (ret != MiniupnpcLibrary.UPNPCOMMAND_SUCCESS) + System.out.println("AddPortMapping() failed with code " + ret); + ret = miniupnpc.UPNP_GetSpecificPortMappingEntry( + urls.controlURL.getString(0), new String(data.first.servicetype), + args[0], args[1], intClient, intPort); + if (ret != MiniupnpcLibrary.UPNPCOMMAND_SUCCESS) + System.out.println("GetSpecificPortMappingEntry() failed with code " + ret); + System.out.println("InternalIP:Port = " + + new String(intClient.array()) + ":" + new String(intPort.array())); + ret = miniupnpc.UPNP_DeletePortMapping( + urls.controlURL.getString(0), + new String(data.first.servicetype), + args[0], args[1], null); + if (ret != MiniupnpcLibrary.UPNPCOMMAND_SUCCESS) + System.out.println("DelPortMapping() failed with code " + ret); + miniupnpc.FreeUPNPUrls(urls); + } else { + System.out.println("No valid UPNP Internet Gateway Device found."); + } + miniupnpc.freeUPNPDevlist(devlist); + } else { + System.out.println("No IGD UPnP Device found on the network !\n"); + } + } +} diff --git a/libportfwd/third-party/miniupnpc-1.4.20100609/java/testjava.sh b/libportfwd/third-party/miniupnpc-1.4.20100609/java/testjava.sh new file mode 100755 index 000000000..c997baf9e --- /dev/null +++ b/libportfwd/third-party/miniupnpc-1.4.20100609/java/testjava.sh @@ -0,0 +1,8 @@ +#! /bin/sh + +JAVA=java +JAVAC=javac + +$JAVAC -cp miniupnpc_Linux.jar JavaBridgeTest.java +$JAVA -cp miniupnpc_Linux.jar:. JavaBridgeTest 12345 UDP + diff --git a/libportfwd/third-party/miniupnpc-20090605/man3/miniupnpc.3 b/libportfwd/third-party/miniupnpc-1.4.20100609/man3/miniupnpc.3 similarity index 100% rename from libportfwd/third-party/miniupnpc-20090605/man3/miniupnpc.3 rename to libportfwd/third-party/miniupnpc-1.4.20100609/man3/miniupnpc.3 diff --git a/libportfwd/third-party/miniupnpc-20090605/mingw32make.bat b/libportfwd/third-party/miniupnpc-1.4.20100609/mingw32make.bat similarity index 81% rename from libportfwd/third-party/miniupnpc-20090605/mingw32make.bat rename to libportfwd/third-party/miniupnpc-1.4.20100609/mingw32make.bat index 3e59be59b..c5d3cc4ff 100644 --- a/libportfwd/third-party/miniupnpc-20090605/mingw32make.bat +++ b/libportfwd/third-party/miniupnpc-1.4.20100609/mingw32make.bat @@ -1,5 +1,6 @@ @mingw32-make -f Makefile.mingw %1 @if errorlevel 1 goto end +@if not exist upnpc-static.exe goto end @strip upnpc-static.exe @upx --best upnpc-static.exe @strip upnpc-shared.exe diff --git a/libportfwd/third-party/miniupnpc-20090605/minisoap.c b/libportfwd/third-party/miniupnpc-1.4.20100609/minisoap.c similarity index 85% rename from libportfwd/third-party/miniupnpc-20090605/minisoap.c rename to libportfwd/third-party/miniupnpc-1.4.20100609/minisoap.c index 04b1a92b8..9afacb787 100644 --- a/libportfwd/third-party/miniupnpc-20090605/minisoap.c +++ b/libportfwd/third-party/miniupnpc-1.4.20100609/minisoap.c @@ -1,7 +1,7 @@ -/* $Id: minisoap.c,v 1.16 2008/10/11 16:39:29 nanard Exp $ */ +/* $Id: minisoap.c,v 1.19 2010/04/12 20:39:41 nanard Exp $ */ /* Project : miniupnp * Author : Thomas Bernard - * Copyright (c) 2005 Thomas Bernard + * Copyright (c) 2005-2009 Thomas Bernard * This software is subject to the conditions detailed in the * LICENCE file provided in this distribution. * @@ -75,7 +75,8 @@ int soapPostSubmit(int fd, const char * host, unsigned short port, const char * action, - const char * body) + const char * body, + const char * httpversion) { int bodysize; char headerbuf[512]; @@ -84,14 +85,16 @@ int soapPostSubmit(int fd, bodysize = (int)strlen(body); /* We are not using keep-alive HTTP connections. * HTTP/1.1 needs the header Connection: close to do that. - * This is the default with HTTP/1.0 */ + * This is the default with HTTP/1.0 + * Using HTTP/1.1 means we need to support chunked transfer-encoding : + * When using HTTP/1.1, the router "BiPAC 7404VNOX" always use chunked + * transfer encoding. */ /* Connection: Close is normally there only in HTTP/1.1 but who knows */ portstr[0] = '\0'; if(port != 80) snprintf(portstr, sizeof(portstr), ":%hu", port); headerssize = snprintf(headerbuf, sizeof(headerbuf), - "POST %s HTTP/1.1\r\n" -/* "POST %s HTTP/1.0\r\n"*/ + "POST %s HTTP/%s\r\n" "Host: %s%s\r\n" "User-Agent: " OS_STRING ", UPnP/1.0, MiniUPnPc/" MINIUPNPC_VERSION_STRING "\r\n" "Content-Length: %d\r\n" @@ -101,7 +104,7 @@ int soapPostSubmit(int fd, "Cache-Control: no-cache\r\n" /* ??? */ "Pragma: no-cache\r\n" "\r\n", - url, host, portstr, bodysize, action); + url, httpversion, host, portstr, bodysize, action); #ifdef DEBUG printf("SOAP request : headersize=%d bodysize=%d\n", headerssize, bodysize); diff --git a/libportfwd/third-party/miniupnpc-20090605/minisoap.h b/libportfwd/third-party/miniupnpc-1.4.20100609/minisoap.h similarity index 77% rename from libportfwd/third-party/miniupnpc-20090605/minisoap.h rename to libportfwd/third-party/miniupnpc-1.4.20100609/minisoap.h index 9fa297fd3..696725f62 100644 --- a/libportfwd/third-party/miniupnpc-20090605/minisoap.h +++ b/libportfwd/third-party/miniupnpc-1.4.20100609/minisoap.h @@ -1,4 +1,4 @@ -/* $Id: minisoap.h,v 1.3 2006/11/19 22:32:34 nanard Exp $ */ +/* $Id: minisoap.h,v 1.4 2010/04/12 20:39:41 nanard Exp $ */ /* Project : miniupnp * Author : Thomas Bernard * Copyright (c) 2005 Thomas Bernard @@ -9,7 +9,7 @@ /*int httpWrite(int, const char *, int, const char *);*/ int soapPostSubmit(int, const char *, const char *, unsigned short, - const char *, const char *); + const char *, const char *, const char *); #endif diff --git a/libportfwd/third-party/miniupnpc-20090605/minissdpc.c b/libportfwd/third-party/miniupnpc-1.4.20100609/minissdpc.c similarity index 80% rename from libportfwd/third-party/miniupnpc-20090605/minissdpc.c rename to libportfwd/third-party/miniupnpc-1.4.20100609/minissdpc.c index 557b65acf..33ffa3ab5 100644 --- a/libportfwd/third-party/miniupnpc-20090605/minissdpc.c +++ b/libportfwd/third-party/miniupnpc-1.4.20100609/minissdpc.c @@ -1,7 +1,7 @@ -/* $Id: minissdpc.c,v 1.7 2008/12/18 17:45:48 nanard Exp $ */ +/* $Id: minissdpc.c,v 1.13 2009/12/04 16:57:29 nanard Exp $ */ /* Project : miniupnp * Author : Thomas BERNARD - * copyright (c) 2005-2008 Thomas Bernard + * copyright (c) 2005-2009 Thomas Bernard * This software is subjet to the conditions detailed in the * provided LICENCE file. */ /*#include */ @@ -10,15 +10,23 @@ #include #include #include +#if defined(WIN32) || defined(__amigaos__) || defined(__amigaos4__) #ifdef WIN32 #include -#include +#include #include +#endif +#if defined(__amigaos__) || defined(__amigaos4__) +#include +#endif +#if defined(__amigaos__) +#define uint16_t unsigned short +#endif /* Hack */ -#define UNIX_PATH_LEN 108 +#define UNIX_PATH_LEN 108 struct sockaddr_un { - uint16_t sun_family; - char sun_path[UNIX_PATH_LEN]; + uint16_t sun_family; + char sun_path[UNIX_PATH_LEN]; }; #else #include @@ -53,6 +61,7 @@ getDevicesFromMiniSSDPD(const char * devtype, const char * socketpath) } addr.sun_family = AF_UNIX; strncpy(addr.sun_path, socketpath, sizeof(addr.sun_path)); + /* TODO : check if we need to handle the EINTR */ if(connect(s, (struct sockaddr *)&addr, sizeof(struct sockaddr_un)) < 0) { /*syslog(LOG_WARNING, "connect(\"%s\"): %m", socketpath);*/ @@ -63,6 +72,12 @@ getDevicesFromMiniSSDPD(const char * devtype, const char * socketpath) buffer[0] = 1; /* request type 1 : request devices/services by type */ p = buffer + 1; l = stsize; CODELENGTH(l, p); + if(p + stsize > buffer + sizeof(buffer)) + { + /* devtype is too long ! */ + close(s); + return NULL; + } memcpy(p, devtype, stsize); p += stsize; if(write(s, buffer, p - buffer) < 0) diff --git a/libportfwd/third-party/miniupnpc-20090605/minissdpc.h b/libportfwd/third-party/miniupnpc-1.4.20100609/minissdpc.h similarity index 100% rename from libportfwd/third-party/miniupnpc-20090605/minissdpc.h rename to libportfwd/third-party/miniupnpc-1.4.20100609/minissdpc.h diff --git a/libportfwd/third-party/miniupnpc-20090605/miniupnpc.c b/libportfwd/third-party/miniupnpc-1.4.20100609/miniupnpc.c similarity index 62% rename from libportfwd/third-party/miniupnpc-20090605/miniupnpc.c rename to libportfwd/third-party/miniupnpc-1.4.20100609/miniupnpc.c index 3794d2b07..484a17e77 100644 --- a/libportfwd/third-party/miniupnpc-20090605/miniupnpc.c +++ b/libportfwd/third-party/miniupnpc-1.4.20100609/miniupnpc.c @@ -1,42 +1,75 @@ -/* $Id: miniupnpc.c,v 1.57 2008/12/18 17:46:36 nanard Exp $ */ +/* $Id: miniupnpc.c,v 1.81 2010/04/17 22:07:59 nanard Exp $ */ /* Project : miniupnp * Author : Thomas BERNARD - * copyright (c) 2005-2007 Thomas Bernard + * copyright (c) 2005-2010 Thomas Bernard * This software is subjet to the conditions detailed in the - * provided LICENCE file. */ -#include + * provided LICENSE file. */ +#define __EXTENSIONS__ 1 +#if !defined(MACOSX) && !defined(__sun) +#if !defined(_XOPEN_SOURCE) && !defined(__OpenBSD__) && !defined(__NetBSD__) +#ifndef __cplusplus +#define _XOPEN_SOURCE 600 +#endif +#endif +#ifndef __BSD_VISIBLE +#define __BSD_VISIBLE 1 +#endif +#endif + #include +#include #include #ifdef WIN32 /* Win32 Specific includes and defines */ #include -#include +#include #include +#include #define snprintf _snprintf #if defined(_MSC_VER) && (_MSC_VER >= 1400) #define strncasecmp _memicmp -#else +#else /* defined(_MSC_VER) && (_MSC_VER >= 1400) */ #define strncasecmp memicmp -#endif +#endif /* defined(_MSC_VER) && (_MSC_VER >= 1400) */ #define MAXHOSTNAMELEN 64 -#else +#else /* #ifdef WIN32 */ /* Standard POSIX includes */ #include +#if defined(__amigaos__) && !defined(__amigaos4__) +/* Amiga OS 3 specific stuff */ +#define socklen_t int +#else +#include +#endif #include #include #include #include #include -#include #include -#define closesocket close +#if !defined(__amigaos__) && !defined(__amigaos4__) +#include #endif +#include +#include +#define closesocket close +#define MINIUPNPC_IGNORE_EINTR +#endif /* #else WIN32 */ +#ifdef MINIUPNPC_SET_SOCKET_TIMEOUT +#include +#endif +#if defined(__amigaos__) || defined(__amigaos4__) +/* Amiga OS specific stuff */ +#define TIMEVAL struct timeval +#endif + #include "miniupnpc.h" #include "minissdpc.h" #include "miniwget.h" #include "minisoap.h" #include "minixml.h" #include "upnpcommands.h" +#include "connecthostport.h" #ifdef WIN32 #define PRINT_SOCKET_ERROR(x) printf("Socket error: %s, %d\n", x, WSAGetLastError()); @@ -49,7 +82,7 @@ #define SERVICEPREFIX2 'u' /* root description parsing */ -void parserootdesc(const char * buffer, int bufsize, struct IGDdatas * data) +LIBSPEC void parserootdesc(const char * buffer, int bufsize, struct IGDdatas * data) { struct xmlparser parser; /* xmlparser object */ @@ -66,7 +99,8 @@ void parserootdesc(const char * buffer, int bufsize, struct IGDdatas * data) #endif } -/* Content-length: nnn */ +/* getcontentlenfromline() : parse the Content-Length HTTP header line. + * Content-length: nnn */ static int getcontentlenfromline(const char * p, int n) { static const char contlenstr[] = "content-length"; @@ -101,6 +135,10 @@ static int getcontentlenfromline(const char * p, int n) return a; } +/* getContentLengthAndHeaderLength() + * retrieve header length and content length from an HTTP response + * TODO : retrieve Transfer-Encoding: header value, in order to support + * HTTP/1.1, chunked transfer encoding must be supported. */ static void getContentLengthAndHeaderLength(char * p, int n, int * contentlen, int * headerlen) @@ -130,17 +168,15 @@ getContentLengthAndHeaderLength(char * p, int n, } } -/* simpleUPnPcommand : +/* simpleUPnPcommand2 : * not so simple ! * return values : * 0 - OK * -1 - error */ -int simpleUPnPcommand(int s, const char * url, const char * service, - const char * action, struct UPNParg * args, - char * buffer, int * bufsize) +static int simpleUPnPcommand2(int s, const char * url, const char * service, + const char * action, struct UPNParg * args, + char * buffer, int * bufsize, const char * httpversion) { - if(!url) return -1; - struct sockaddr_in dest; char hostname[MAXHOSTNAMELEN+1]; unsigned short port = 0; char * path; @@ -150,6 +186,7 @@ int simpleUPnPcommand(int s, const char * url, const char * service, int buffree; int n; int contentlen, headerlen; /* for the response */ + snprintf(soapact, sizeof(soapact), "%s#%s", service, action); if(args==NULL) { @@ -218,26 +255,15 @@ int simpleUPnPcommand(int s, const char * url, const char * service, if(!parseURL(url, hostname, &port, &path)) return -1; if(s<0) { - s = socket(PF_INET, SOCK_STREAM, 0); - if(s<0) + s = connecthostport(hostname, port); + if(s < 0) { - PRINT_SOCKET_ERROR("socket"); - *bufsize = 0; - return -1; - } - 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"); - closesocket(s); *bufsize = 0; return -1; } } - n = soapPostSubmit(s, path, hostname, port, soapact, soapbody); + n = soapPostSubmit(s, path, hostname, port, soapact, soapbody, httpversion); if(n<=0) { #ifdef DEBUG printf("Error sending SOAP request\n"); @@ -270,6 +296,30 @@ int simpleUPnPcommand(int s, const char * url, const char * service, return 0; } +/* simpleUPnPcommand : + * not so simple ! + * return values : + * 0 - OK + * -1 - error */ +int simpleUPnPcommand(int s, const char * url, const char * service, + const char * action, struct UPNParg * args, + char * buffer, int * bufsize) +{ + int result; + int origbufsize = *bufsize; + + result = simpleUPnPcommand2(s, url, service, action, args, buffer, bufsize, "1.0"); + if (result < 0 || *bufsize == 0) + { +#if DEBUG + printf("Error or no result from SOAP request; retrying with HTTP/1.1\n"); +#endif + *bufsize = origbufsize; + result = simpleUPnPcommand2(s, url, service, action, args, buffer, bufsize, "1.1"); + } + return result; +} + /* parseMSEARCHReply() * the last 4 arguments are filled during the parsing : * - location/locationsize : "location:" field of the SSDP reply packet @@ -341,7 +391,7 @@ parseMSEARCHReply(const char * reply, int size, * 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, +LIBSPEC struct UPNPDev * upnpDiscover(int delay, const char * multicastif, const char * minissdpdsock, int sameport) { struct UPNPDev * tmp; @@ -352,7 +402,7 @@ struct UPNPDev * upnpDiscover(int delay, const char * multicastif, "HOST: " UPNP_MCAST_ADDR ":" XSTR(PORT) "\r\n" "ST: %s\r\n" "MAN: \"ssdp:discover\"\r\n" - "MX: 3\r\n" + "MX: %u\r\n" "\r\n"; static const char * const deviceList[] = { "urn:schemas-upnp-org:device:InternetGatewayDevice:1", @@ -365,9 +415,15 @@ struct UPNPDev * upnpDiscover(int delay, const char * multicastif, char bufr[1536]; /* reception and emission buffer */ int sudp; int n; - struct sockaddr_in sockudp_r, sockudp_w; + struct sockaddr sockudp_r; + unsigned int mx; + int rv; + struct addrinfo hints, *servinfo, *p; +#ifdef WIN32 + MIB_IPFORWARDROW ip_forward; +#endif -#ifndef WIN32 +#if !defined(WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) /* first try to get infos from minissdpd ! */ if(!minissdpdsock) minissdpdsock = "/var/run/minissdpd.sock"; @@ -392,17 +448,86 @@ struct UPNPDev * upnpDiscover(int delay, const char * multicastif, PRINT_SOCKET_ERROR("socket"); return NULL; } - /* reception */ - memset(&sockudp_r, 0, sizeof(struct sockaddr_in)); - sockudp_r.sin_family = AF_INET; - if(sameport) - sockudp_r.sin_port = htons(PORT); - 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); + /* reception */ + memset(&sockudp_r, 0, sizeof(struct sockaddr)); + if(0/*ipv6*/) { + struct sockaddr_in6 * p = (struct sockaddr_in6 *)&sockudp_r; + p->sin6_family = AF_INET6; + if(sameport) + p->sin6_port = htons(PORT); + p->sin6_addr = in6addr_any;//IN6ADDR_ANY_INIT;/*INADDR_ANY;*/ + } else { + struct sockaddr_in * p = (struct sockaddr_in *)&sockudp_r; + p->sin_family = AF_INET; + if(sameport) + p->sin_port = htons(PORT); + p->sin_addr.s_addr = INADDR_ANY; + } +#if 0 + /* 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); +#endif +#ifdef WIN32 +/* This code could help us to use the right Network interface for + * SSDP multicast traffic */ +/* Get IP associated with the index given in the ip_forward struct + * in order to give this ip to setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF) */ + if(GetBestRoute(inet_addr("223.255.255.255"), 0, &ip_forward) == NO_ERROR) { + DWORD dwRetVal = 0; + PMIB_IPADDRTABLE pIPAddrTable; + DWORD dwSize = 0; +#ifdef DEBUG + IN_ADDR IPAddr; +#endif + int i; +#ifdef DEBUG + printf("ifIndex=%lu nextHop=%lx \n", ip_forward.dwForwardIfIndex, ip_forward.dwForwardNextHop); +#endif + pIPAddrTable = (MIB_IPADDRTABLE *) malloc(sizeof (MIB_IPADDRTABLE)); + if (GetIpAddrTable(pIPAddrTable, &dwSize, 0) == ERROR_INSUFFICIENT_BUFFER) { + free(pIPAddrTable); + pIPAddrTable = (MIB_IPADDRTABLE *) malloc(dwSize); + } + if(pIPAddrTable) { + dwRetVal = GetIpAddrTable( pIPAddrTable, &dwSize, 0 ); +#ifdef DEBUG + printf("\tNum Entries: %ld\n", pIPAddrTable->dwNumEntries); +#endif + for (i=0; i < (int) pIPAddrTable->dwNumEntries; i++) { +#ifdef DEBUG + printf("\n\tInterface Index[%d]:\t%ld\n", i, pIPAddrTable->table[i].dwIndex); + IPAddr.S_un.S_addr = (u_long) pIPAddrTable->table[i].dwAddr; + printf("\tIP Address[%d]: \t%s\n", i, inet_ntoa(IPAddr) ); + IPAddr.S_un.S_addr = (u_long) pIPAddrTable->table[i].dwMask; + printf("\tSubnet Mask[%d]: \t%s\n", i, inet_ntoa(IPAddr) ); + IPAddr.S_un.S_addr = (u_long) pIPAddrTable->table[i].dwBCastAddr; + printf("\tBroadCast[%d]: \t%s (%ld)\n", i, inet_ntoa(IPAddr), pIPAddrTable->table[i].dwBCastAddr); + printf("\tReassembly size[%d]:\t%ld\n", i, pIPAddrTable->table[i].dwReasmSize); + printf("\tType and State[%d]:", i); + printf("\n"); +#endif + if (pIPAddrTable->table[i].dwIndex == ip_forward.dwForwardIfIndex) { + /* Set the address of this interface to be used */ + struct in_addr mc_if; + memset(&mc_if, 0, sizeof(mc_if)); + mc_if.s_addr = pIPAddrTable->table[i].dwAddr; + if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&mc_if, sizeof(mc_if)) < 0) { + PRINT_SOCKET_ERROR("setsockopt"); + } + ((struct sockaddr_in *)&sockudp_r)->sin_addr.s_addr = pIPAddrTable->table[i].dwAddr; +#ifndef DEBUG + break; +#endif + } + } + free(pIPAddrTable); + pIPAddrTable = NULL; + } + } +#endif #ifdef WIN32 if (setsockopt(sudp, SOL_SOCKET, SO_REUSEADDR, (const char *)&opt, sizeof (opt)) < 0) @@ -418,7 +543,10 @@ struct UPNPDev * upnpDiscover(int delay, const char * multicastif, { struct in_addr mc_if; mc_if.s_addr = inet_addr(multicastif); - sockudp_r.sin_addr.s_addr = mc_if.s_addr; + if(0/*ipv6*/) { + } else { + ((struct sockaddr_in *)&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"); @@ -426,13 +554,15 @@ struct UPNPDev * upnpDiscover(int delay, const char * multicastif, } /* Avant d'envoyer le paquet on bind pour recevoir la reponse */ - if (bind(sudp, (struct sockaddr *)&sockudp_r, sizeof(struct sockaddr_in)) != 0) + if (bind(sudp, &sockudp_r, 0/*ipv6*/?sizeof(struct sockaddr_in6):sizeof(struct sockaddr_in)) != 0) { PRINT_SOCKET_ERROR("bind"); closesocket(sudp); return NULL; } + /* Calculating maximum response time in seconds */ + mx = ((unsigned int)delay) / 1000u; /* receiving SSDP response packet */ for(n = 0;;) { @@ -440,8 +570,9 @@ struct UPNPDev * upnpDiscover(int delay, const char * multicastif, { /* sending the SSDP M-SEARCH packet */ n = snprintf(bufr, sizeof(bufr), - MSearchMsgFmt, deviceList[deviceIndex++]); + MSearchMsgFmt, deviceList[deviceIndex++], mx); /*printf("Sending %s", bufr);*/ +#if 0 n = sendto(sudp, bufr, n, 0, (struct sockaddr *)&sockudp_w, sizeof(struct sockaddr_in)); if (n < 0) { @@ -449,6 +580,31 @@ struct UPNPDev * upnpDiscover(int delay, const char * multicastif, closesocket(sudp); return devlist; } +#endif + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; // AF_INET6 or AF_INET + hints.ai_socktype = SOCK_DGRAM; + /*hints.ai_flags = */ + if ((rv = getaddrinfo(UPNP_MCAST_ADDR, XSTR(PORT), &hints, &servinfo)) != 0) { +#ifdef WIN32 + fprintf(stderr, "getaddrinfo() failed: %d\n", rv); +#else + fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); +#endif + return devlist; + } + for(p = servinfo; p; p = p->ai_next) { + n = sendto(sudp, bufr, n, 0, p->ai_addr, p->ai_addrlen); + if (n < 0) { + PRINT_SOCKET_ERROR("sendto"); + continue; + } + } + freeaddrinfo(servinfo); + if(n < 0) { + closesocket(sudp); + return devlist; + } } /* Waiting for SSDP REPLY packet to M-SEARCH */ n = ReceiveData(sudp, bufr, sizeof(bufr), delay); @@ -472,8 +628,21 @@ struct UPNPDev * upnpDiscover(int delay, const char * multicastif, parseMSEARCHReply(bufr, n, &descURL, &urlsize, &st, &stsize); if(st&&descURL) { - /*printf("M-SEARCH Reply:\nST: %.*s\nLocation: %.*s\n", - stsize, st, urlsize, descURL); */ +#ifdef DEBUG + printf("M-SEARCH Reply:\nST: %.*s\nLocation: %.*s\n", + stsize, st, urlsize, descURL); +#endif + for(tmp=devlist; tmp; tmp = tmp->pNext) { + if(memcmp(tmp->descURL, descURL, urlsize) == 0 && + tmp->descURL[urlsize] == '\0' && + memcmp(tmp->st, st, stsize) == 0 && + tmp->st[stsize] == '\0') + break; + } + /* at the exit of the loop above, tmp is null if + * no duplicate device was found */ + if(tmp) + continue; tmp = (struct UPNPDev *)malloc(sizeof(struct UPNPDev)+urlsize+stsize); tmp->pNext = devlist; tmp->descURL = tmp->buffer; @@ -490,7 +659,7 @@ struct UPNPDev * upnpDiscover(int delay, const char * multicastif, /* freeUPNPDevlist() should be used to * free the chained list returned by upnpDiscover() */ -void freeUPNPDevlist(struct UPNPDev * devlist) +LIBSPEC void freeUPNPDevlist(struct UPNPDev * devlist) { struct UPNPDev * next; while(devlist) @@ -526,7 +695,7 @@ url_cpy_or_cat(char * dst, const char * src, int n) /* Prepare the Urls for usage... */ -void GetUPNPUrls(struct UPNPUrls * urls, struct IGDdatas * data, +LIBSPEC void GetUPNPUrls(struct UPNPUrls * urls, struct IGDdatas * data, const char * descURL) { char * p; @@ -536,9 +705,9 @@ void GetUPNPUrls(struct UPNPUrls * urls, struct IGDdatas * data, 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); + n1 += strlen(data->first.scpdurl); + n2 += strlen(data->first.controlurl); + n3 += strlen(data->CIF.controlurl); urls->ipcondescURL = (char *)malloc(n1); urls->controlURL = (char *)malloc(n2); @@ -553,23 +722,23 @@ void GetUPNPUrls(struct UPNPUrls * urls, struct IGDdatas * data, 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->ipcondescURL, data->first.scpdurl, n1); - url_cpy_or_cat(urls->controlURL, data->controlurl, n2); + url_cpy_or_cat(urls->controlURL, data->first.controlurl, n2); - url_cpy_or_cat(urls->controlURL_CIF, data->controlurl_CIF, n3); + url_cpy_or_cat(urls->controlURL_CIF, data->CIF.controlurl, 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); + printf("urls->ipcondescURL='%s' %u n1=%d\n", urls->ipcondescURL, + (unsigned)strlen(urls->ipcondescURL), n1); + printf("urls->controlURL='%s' %u n2=%d\n", urls->controlURL, + (unsigned)strlen(urls->controlURL), n2); + printf("urls->controlURL_CIF='%s' %u n3=%d\n", urls->controlURL_CIF, + (unsigned)strlen(urls->controlURL_CIF), n3); #endif } -void +LIBSPEC void FreeUPNPUrls(struct UPNPUrls * urls) { if(!urls) @@ -586,11 +755,17 @@ FreeUPNPUrls(struct UPNPUrls * urls) int ReceiveData(int socket, char * data, int length, int timeout) { int n; -#ifndef WIN32 +#if !defined(WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) struct pollfd fds[1]; /* for the poll */ - fds[0].fd = socket; - fds[0].events = POLLIN; - n = poll(fds, 1, timeout); +#ifdef MINIUPNPC_IGNORE_EINTR + do { +#endif + fds[0].fd = socket; + fds[0].events = POLLIN; + n = poll(fds, 1, timeout); +#ifdef MINIUPNPC_IGNORE_EINTR + } while(n < 0 && errno == EINTR); +#endif if(n < 0) { PRINT_SOCKET_ERROR("poll"); @@ -607,7 +782,6 @@ int ReceiveData(int socket, char * data, int length, int timeout) FD_SET(socket, &socketSet); timeval.tv_sec = timeout / 1000; timeval.tv_usec = (timeout % 1000) * 1000; - /*n = select(0, &socketSet, NULL, NULL, &timeval);*/ n = select(FD_SETSIZE, &socketSet, NULL, NULL, &timeval); if(n < 0) { @@ -633,7 +807,7 @@ UPNPIGD_IsConnected(struct UPNPUrls * urls, struct IGDdatas * data) char status[64]; unsigned int uptime; status[0] = '\0'; - UPNP_GetStatusInfo(urls->controlURL, data->servicetype, + UPNP_GetStatusInfo(urls->controlURL, data->first.servicetype, status, &uptime, NULL); if(0 == strcmp("Connected", status)) { @@ -656,7 +830,7 @@ UPNPIGD_IsConnected(struct UPNPUrls * urls, struct IGDdatas * data) * passed as parameters are set. Donc forget to call FreeUPNPUrls(urls) to * free allocated memory. */ -int +LIBSPEC int UPNP_GetValidIGD(struct UPNPDev * devlist, struct UPNPUrls * urls, struct IGDdatas * data, @@ -690,7 +864,7 @@ UPNP_GetValidIGD(struct UPNPDev * devlist, parserootdesc(descXML, descXMLsize, data); free(descXML); descXML = NULL; - if(0==strcmp(data->servicetype_CIF, + if(0==strcmp(data->CIF.servicetype, "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1") || state >= 3 ) { @@ -704,6 +878,25 @@ UPNP_GetValidIGD(struct UPNPDev * devlist, if((state >= 2) || UPNPIGD_IsConnected(urls, data)) return state; FreeUPNPUrls(urls); + if(data->second.servicetype[0] != '\0') { +#ifdef DEBUG + printf("We tried %s, now we try %s !\n", + data->first.servicetype, data->second.servicetype); +#endif + /* swaping WANPPPConnection and WANIPConnection ! */ + memcpy(&data->tmp, &data->first, sizeof(struct IGDdatas_service)); + memcpy(&data->first, &data->second, sizeof(struct IGDdatas_service)); + memcpy(&data->second, &data->tmp, sizeof(struct IGDdatas_service)); + 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)); } diff --git a/libportfwd/third-party/miniupnpc-20090605/miniupnpc.def b/libportfwd/third-party/miniupnpc-1.4.20100609/miniupnpc.def similarity index 100% rename from libportfwd/third-party/miniupnpc-20090605/miniupnpc.def rename to libportfwd/third-party/miniupnpc-1.4.20100609/miniupnpc.def diff --git a/libportfwd/third-party/miniupnpc-20090605/miniupnpc.h b/libportfwd/third-party/miniupnpc-1.4.20100609/miniupnpc.h similarity index 95% rename from libportfwd/third-party/miniupnpc-20090605/miniupnpc.h rename to libportfwd/third-party/miniupnpc-1.4.20100609/miniupnpc.h index bce314e82..2379ba14c 100644 --- a/libportfwd/third-party/miniupnpc-20090605/miniupnpc.h +++ b/libportfwd/third-party/miniupnpc-1.4.20100609/miniupnpc.h @@ -1,4 +1,4 @@ -/* $Id: miniupnpc.h,v 1.18 2008/09/25 18:02:50 nanard Exp $ */ +/* $Id: miniupnpc.h,v 1.19 2009/10/10 19:15:35 nanard Exp $ */ /* Project: miniupnp * http://miniupnp.free.fr/ * Author: Thomas Bernard @@ -102,6 +102,10 @@ LIBSPEC void FreeUPNPUrls(struct UPNPUrls *); * read or if we timed out. Returns negative if there was an error. */ int ReceiveData(int socket, char * data, int length, int timeout); +/* return 0 or 1 */ +LIBSPEC int UPNPIGD_IsConnected(struct UPNPUrls *, struct IGDdatas *); + + #ifdef __cplusplus } #endif diff --git a/libportfwd/third-party/miniupnpc-20090605/miniupnpcmodule.c b/libportfwd/third-party/miniupnpc-1.4.20100609/miniupnpcmodule.c similarity index 85% rename from libportfwd/third-party/miniupnpc-20090605/miniupnpcmodule.c rename to libportfwd/third-party/miniupnpc-1.4.20100609/miniupnpcmodule.c index 121ff2052..c09e98261 100644 --- a/libportfwd/third-party/miniupnpc-20090605/miniupnpcmodule.c +++ b/libportfwd/third-party/miniupnpc-1.4.20100609/miniupnpcmodule.c @@ -1,8 +1,8 @@ -/* $Id: miniupnpcmodule.c,v 1.13 2009/04/17 20:59:42 nanard Exp $*/ +/* $Id: miniupnpcmodule.c,v 1.15 2010/06/09 10:23:01 nanard Exp $*/ /* Project : miniupnp * Author : Thomas BERNARD * website : http://miniupnp.tuxfamily.org/ - * copyright (c) 2007 Thomas Bernard + * copyright (c) 2007-2009 Thomas Bernard * This software is subjet to the conditions detailed in the * provided LICENCE file. */ #include @@ -72,11 +72,13 @@ UPnP_discover(UPnPObject *self) { freeUPNPDevlist(self->devlist); self->devlist = 0; - } + } + Py_BEGIN_ALLOW_THREADS self->devlist = upnpDiscover((int)self->discoverdelay/*timeout in ms*/, 0/* multicast if*/, 0/*minissdpd socket*/, 0/*sameport flag*/); + Py_END_ALLOW_THREADS /* Py_RETURN_NONE ??? */ for(dev = self->devlist, i = 0; dev; dev = dev->pNext) i++; @@ -87,8 +89,12 @@ UPnP_discover(UPnPObject *self) static PyObject * UPnP_selectigd(UPnPObject *self) { - if(UPNP_GetValidIGD(self->devlist, &self->urls, &self->data, - self->lanaddr, sizeof(self->lanaddr))) + int r; +Py_BEGIN_ALLOW_THREADS + r = UPNP_GetValidIGD(self->devlist, &self->urls, &self->data, + self->lanaddr, sizeof(self->lanaddr)); +Py_END_ALLOW_THREADS + if(r) { return Py_BuildValue("s", self->urls.controlURL); } @@ -103,33 +109,45 @@ UPnP_selectigd(UPnPObject *self) static PyObject * UPnP_totalbytesent(UPnPObject *self) { - return Py_BuildValue("I", - UPNP_GetTotalBytesSent(self->urls.controlURL_CIF, - self->data.servicetype_CIF)); + UNSIGNED_INTEGER i; +Py_BEGIN_ALLOW_THREADS + i = UPNP_GetTotalBytesSent(self->urls.controlURL_CIF, + self->data.CIF.servicetype); +Py_END_ALLOW_THREADS + return Py_BuildValue("I", i); } static PyObject * UPnP_totalbytereceived(UPnPObject *self) { - return Py_BuildValue("I", - UPNP_GetTotalBytesReceived(self->urls.controlURL_CIF, - self->data.servicetype_CIF)); + UNSIGNED_INTEGER i; +Py_BEGIN_ALLOW_THREADS + i = UPNP_GetTotalBytesReceived(self->urls.controlURL_CIF, + self->data.CIF.servicetype); +Py_END_ALLOW_THREADS + return Py_BuildValue("I", i); } static PyObject * UPnP_totalpacketsent(UPnPObject *self) { - return Py_BuildValue("I", - UPNP_GetTotalPacketsSent(self->urls.controlURL_CIF, - self->data.servicetype_CIF)); + UNSIGNED_INTEGER i; +Py_BEGIN_ALLOW_THREADS + i = UPNP_GetTotalPacketsSent(self->urls.controlURL_CIF, + self->data.CIF.servicetype); +Py_END_ALLOW_THREADS + return Py_BuildValue("I", i); } static PyObject * UPnP_totalpacketreceived(UPnPObject *self) { - return Py_BuildValue("I", - UPNP_GetTotalPacketsReceived(self->urls.controlURL_CIF, - self->data.servicetype_CIF)); + UNSIGNED_INTEGER i; +Py_BEGIN_ALLOW_THREADS + i = UPNP_GetTotalPacketsReceived(self->urls.controlURL_CIF, + self->data.CIF.servicetype); +Py_END_ALLOW_THREADS + return Py_BuildValue("I", i); } static PyObject * @@ -141,8 +159,10 @@ UPnP_statusinfo(UPnPObject *self) int r; status[0] = '\0'; lastconnerror[0] = '\0'; - r = UPNP_GetStatusInfo(self->urls.controlURL, self->data.servicetype, +Py_BEGIN_ALLOW_THREADS + r = UPNP_GetStatusInfo(self->urls.controlURL, self->data.first.servicetype, status, &uptime, lastconnerror); +Py_END_ALLOW_THREADS if(r==UPNPCOMMAND_SUCCESS) { return Py_BuildValue("(s,I,s)", status, uptime, lastconnerror); } else { @@ -158,9 +178,11 @@ UPnP_connectiontype(UPnPObject *self) char connectionType[64]; int r; connectionType[0] = '\0'; +Py_BEGIN_ALLOW_THREADS r = UPNP_GetConnectionTypeInfo(self->urls.controlURL, - self->data.servicetype, + self->data.first.servicetype, connectionType); +Py_END_ALLOW_THREADS if(r==UPNPCOMMAND_SUCCESS) { return Py_BuildValue("s", connectionType); } else { @@ -176,9 +198,11 @@ UPnP_externalipaddress(UPnPObject *self) char externalIPAddress[16]; int r; externalIPAddress[0] = '\0'; +Py_BEGIN_ALLOW_THREADS r = UPNP_GetExternalIPAddress(self->urls.controlURL, - self->data.servicetype, + self->data.first.servicetype, externalIPAddress); +Py_END_ALLOW_THREADS if(r==UPNPCOMMAND_SUCCESS) { return Py_BuildValue("s", externalIPAddress); } else { @@ -206,10 +230,12 @@ UPnP_addportmapping(UPnPObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "HssHss", &ePort, &proto, &host, &iPort, &desc, &remoteHost)) return NULL; +Py_BEGIN_ALLOW_THREADS sprintf(extPort, "%hu", ePort); sprintf(inPort, "%hu", iPort); - r = UPNP_AddPortMapping(self->urls.controlURL, self->data.servicetype, + r = UPNP_AddPortMapping(self->urls.controlURL, self->data.first.servicetype, extPort, inPort, host, desc, proto, remoteHost); +Py_END_ALLOW_THREADS if(r==UPNPCOMMAND_SUCCESS) { Py_RETURN_TRUE; @@ -237,9 +263,11 @@ UPnP_deleteportmapping(UPnPObject *self, PyObject *args) int r; if(!PyArg_ParseTuple(args, "Hs|z", &ePort, &proto, &remoteHost)) return NULL; +Py_BEGIN_ALLOW_THREADS sprintf(extPort, "%hu", ePort); - r = UPNP_DeletePortMapping(self->urls.controlURL, self->data.servicetype, + r = UPNP_DeletePortMapping(self->urls.controlURL, self->data.first.servicetype, extPort, proto, remoteHost); +Py_END_ALLOW_THREADS if(r==UPNPCOMMAND_SUCCESS) { Py_RETURN_TRUE; } else { @@ -254,9 +282,11 @@ UPnP_getportmappingnumberofentries(UPnPObject *self) { unsigned int n = 0; int r; +Py_BEGIN_ALLOW_THREADS r = UPNP_GetPortMappingNumberOfEntries(self->urls.controlURL, - self->data.servicetype, + self->data.first.servicetype, &n); +Py_END_ALLOW_THREADS if(r==UPNPCOMMAND_SUCCESS) { return Py_BuildValue("I", n); } else { @@ -279,11 +309,13 @@ UPnP_getspecificportmapping(UPnPObject *self, PyObject *args) unsigned short iPort; if(!PyArg_ParseTuple(args, "Hs", &ePort, &proto)) return NULL; +Py_BEGIN_ALLOW_THREADS sprintf(extPort, "%hu", ePort); UPNP_GetSpecificPortMappingEntry(self->urls.controlURL, - self->data.servicetype, + self->data.first.servicetype, extPort, proto, intClient, intPort); +Py_END_ALLOW_THREADS if(intClient[0]) { iPort = (unsigned short)atoi(intPort); @@ -314,16 +346,18 @@ UPnP_getgenericportmapping(UPnPObject *self, PyObject *args) unsigned int dur; if(!PyArg_ParseTuple(args, "i", &i)) return NULL; +Py_BEGIN_ALLOW_THREADS snprintf(index, sizeof(index), "%d", i); rHost[0] = '\0'; enabled[0] = '\0'; duration[0] = '\0'; desc[0] = '\0'; extPort[0] = '\0'; intPort[0] = '\0'; intClient[0] = '\0'; r = UPNP_GetGenericPortMappingEntry(self->urls.controlURL, - self->data.servicetype, + self->data.first.servicetype, index, extPort, intClient, intPort, protocol, desc, enabled, rHost, duration); +Py_END_ALLOW_THREADS if(r==UPNPCOMMAND_SUCCESS) { ePort = (unsigned short)atoi(extPort); diff --git a/libportfwd/third-party/miniupnpc-1.4.20100609/miniupnpcstrings.h b/libportfwd/third-party/miniupnpc-1.4.20100609/miniupnpcstrings.h new file mode 100644 index 000000000..8cbb4ec16 --- /dev/null +++ b/libportfwd/third-party/miniupnpc-1.4.20100609/miniupnpcstrings.h @@ -0,0 +1,15 @@ +/* $Id: miniupnpcstrings.h.in,v 1.2 2009/10/30 09:18:18 nanard Exp $ */ +/* Project: miniupnp + * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ + * Author: Thomas Bernard + * Copyright (c) 2005-2009 Thomas Bernard + * This software is subjects to the conditions detailed + * in the LICENCE file provided within this distribution */ +#ifndef __MINIUPNPCSTRINGS_H__ +#define __MINIUPNPCSTRINGS_H__ + +#define OS_STRING "Linux/2.6.35-ARCH" +#define MINIUPNPC_VERSION_STRING "1.4" + +#endif + diff --git a/libportfwd/third-party/miniupnpc-20090605/miniupnpcstrings.h b/libportfwd/third-party/miniupnpc-1.4.20100609/miniupnpcstrings.h.in similarity index 70% rename from libportfwd/third-party/miniupnpc-20090605/miniupnpcstrings.h rename to libportfwd/third-party/miniupnpc-1.4.20100609/miniupnpcstrings.h.in index 8f1b6c26d..8ab3f29f7 100644 --- a/libportfwd/third-party/miniupnpc-20090605/miniupnpcstrings.h +++ b/libportfwd/third-party/miniupnpc-1.4.20100609/miniupnpcstrings.h.in @@ -1,4 +1,4 @@ -/* $Id: miniupnpcstrings.h,v 1.3 2009/06/04 09:05:56 nanard Exp $ */ +/* $Id: miniupnpcstrings.h.in,v 1.2 2009/10/30 09:18:18 nanard Exp $ */ /* Project: miniupnp * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ * Author: Thomas Bernard @@ -8,8 +8,8 @@ #ifndef __MINIUPNPCSTRINGS_H__ #define __MINIUPNPCSTRINGS_H__ -#define OS_STRING "OpenBSD/4.3" -#define MINIUPNPC_VERSION_STRING "1.3" +#define OS_STRING "OS/version" +#define MINIUPNPC_VERSION_STRING "1.4" #endif diff --git a/libportfwd/third-party/miniupnpc-20090605/miniwget.c b/libportfwd/third-party/miniupnpc-1.4.20100609/miniwget.c similarity index 60% rename from libportfwd/third-party/miniupnpc-20090605/miniwget.c rename to libportfwd/third-party/miniupnpc-1.4.20100609/miniwget.c index 0a026cbb1..aa5ee26ec 100644 --- a/libportfwd/third-party/miniupnpc-20090605/miniwget.c +++ b/libportfwd/third-party/miniupnpc-1.4.20100609/miniwget.c @@ -1,84 +1,79 @@ -/* $Id: miniwget.c,v 1.22 2009/02/28 10:36:35 nanard Exp $ */ +/* $Id: miniwget.c,v 1.37 2010/04/12 20:39:42 nanard Exp $ */ /* Project : miniupnp * Author : Thomas Bernard - * Copyright (c) 2005 Thomas Bernard + * Copyright (c) 2005-2010 Thomas Bernard * This software is subject to the conditions detailed in the - * LICENCE file provided in this distribution. - * */ + * LICENCE file provided in this distribution. */ + #include #include #include #include "miniupnpc.h" #ifdef WIN32 #include +#include #include #define MAXHOSTNAMELEN 64 #define MIN(x,y) (((x)<(y))?(x):(y)) #define snprintf _snprintf -#define herror #define socklen_t int -#else +#else /* #ifdef WIN32 */ #include #include +#if defined(__amigaos__) && !defined(__amigaos4__) +#define socklen_t int +#else /* #if defined(__amigaos__) && !defined(__amigaos4__) */ +#include +#endif /* #else defined(__amigaos__) && !defined(__amigaos4__) */ #include -#include -#include #include +#include #define closesocket close -#endif +/* defining MINIUPNPC_IGNORE_EINTR enable the ignore of interruptions + * during the connect() call */ +#define MINIUPNPC_IGNORE_EINTR +#endif /* #else WIN32 */ #if defined(__sun) || defined(sun) #define MIN(x,y) (((x)<(y))?(x):(y)) #endif #include "miniupnpcstrings.h" +#include "miniwget.h" +#include "connecthostport.h" -/* miniwget2() : - * */ +/* miniwget3() : + * do all the work. + * Return NULL if something failed. */ static void * -miniwget2(const char * url, const char * host, +miniwget3(const char * url, const char * host, unsigned short port, const char * path, - int * size, char * addr_str, int addr_str_len) + int * size, char * addr_str, int addr_str_len, const char * httpversion) { char buf[2048]; int s; - struct sockaddr_in dest; - struct hostent *hp; + int n; + int len; + int sent; + *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); + s = connecthostport(host, port); 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; + struct sockaddr saddr; + socklen_t saddrlen; - len = sizeof(saddr); - getsockname(s, (struct sockaddr *)&saddr, &len); -#ifndef WIN32 - inet_ntop(AF_INET, &saddr.sin_addr, addr_str, addr_str_len); -#else + saddrlen = sizeof(saddr); + if(getsockname(s, &saddr, &saddrlen) < 0) + { + perror("getsockname"); + } + else + { +#if defined(__amigaos__) && !defined(__amigaos4__) /* 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), @@ -86,25 +81,56 @@ miniwget2(const char * url, const char * host, { printf("WSAAddressToStringA() failed : %d\n", WSAGetLastError()); }*/ - strncpy(addr_str, inet_ntoa(saddr.sin_addr), addr_str_len); + strncpy(addr_str, inet_ntoa(((struct sockaddr_in *)&saddr)->sin_addr), addr_str_len); +#else + /*inet_ntop(AF_INET, &saddr.sin_addr, addr_str, addr_str_len);*/ + n = getnameinfo(&saddr, saddrlen, + addr_str, addr_str_len, + NULL, 0, + NI_NUMERICHOST | NI_NUMERICSERV); + if(n != 0) { +#ifdef WIN32 + fprintf(stderr, "getnameinfo() failed : %d\n", n); +#else + fprintf(stderr, "getnameinfo() failed : %s\n", gai_strerror(n)); #endif + } +#endif + } #ifdef DEBUG printf("address miniwget : %s\n", addr_str); #endif } - snprintf(buf, sizeof(buf), - "GET %s HTTP/1.1\r\n" + len = snprintf(buf, sizeof(buf), + "GET %s HTTP/%s\r\n" "Host: %s:%d\r\n" "Connection: Close\r\n" "User-Agent: " OS_STRING ", UPnP/1.0, MiniUPnPc/" MINIUPNPC_VERSION_STRING "\r\n" "\r\n", - path, host, port); - /*write(s, buf, strlen(buf));*/ - send(s, buf, strlen(buf), 0); + path, httpversion, host, port); + sent = 0; + /* sending the HTTP request */ + while(sent < len) { - int n, headers=1; + n = send(s, buf+sent, len-sent, 0); + if(n < 0) + { + perror("send"); + closesocket(s); + return NULL; + } + else + { + sent += n; + } + } + { + /* TODO : in order to support HTTP/1.1, chunked transfer encoding + * must be supported. That means parsing of headers must be + * added. */ + int headers=1; char * respbuffer = NULL; int allreadyread = 0; /*while((n = recv(s, buf, 2048, 0)) > 0)*/ @@ -115,12 +141,14 @@ miniwget2(const char * url, const char * host, int i=0; while(i + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libportfwd/third-party/miniupnpc-1.4.20100609/msvc/upnpc-static.vcproj b/libportfwd/third-party/miniupnpc-1.4.20100609/msvc/upnpc-static.vcproj new file mode 100644 index 000000000..294613877 --- /dev/null +++ b/libportfwd/third-party/miniupnpc-1.4.20100609/msvc/upnpc-static.vcproj @@ -0,0 +1,195 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libportfwd/third-party/miniupnpc-20090605/pymoduletest.py b/libportfwd/third-party/miniupnpc-1.4.20100609/pymoduletest.py similarity index 100% rename from libportfwd/third-party/miniupnpc-20090605/pymoduletest.py rename to libportfwd/third-party/miniupnpc-1.4.20100609/pymoduletest.py diff --git a/libportfwd/third-party/miniupnpc-20090605/setup.py b/libportfwd/third-party/miniupnpc-1.4.20100609/setup.py similarity index 73% rename from libportfwd/third-party/miniupnpc-20090605/setup.py rename to libportfwd/third-party/miniupnpc-1.4.20100609/setup.py index 8ecb5f392..119ec4bec 100644 --- a/libportfwd/third-party/miniupnpc-20090605/setup.py +++ b/libportfwd/third-party/miniupnpc-1.4.20100609/setup.py @@ -1,13 +1,13 @@ #! /usr/bin/python -# $Id: setup.py,v 1.3 2009/04/17 20:59:42 nanard Exp $ -# the MiniUPnP Project (c) 2007 Thomas Bernard +# $Id: setup.py,v 1.5 2009/10/30 09:18:18 nanard Exp $ +# the MiniUPnP Project (c) 2007-2009 Thomas Bernard # http://miniupnp.tuxfamily.org/ or http://miniupnp.free.fr/ # # python script to build the miniupnpc module under unix # # replace libminiupnpc.a by libminiupnpc.so for shared library usage from distutils.core import setup, Extension -setup(name="miniupnpc", version="1.3", +setup(name="miniupnpc", version="1.4", ext_modules=[ Extension(name="miniupnpc", sources=["miniupnpcmodule.c"], extra_objects=["libminiupnpc.a"]) diff --git a/libportfwd/third-party/miniupnpc-20090605/setupmingw32.py b/libportfwd/third-party/miniupnpc-1.4.20100609/setupmingw32.py old mode 100755 new mode 100644 similarity index 70% rename from libportfwd/third-party/miniupnpc-20090605/setupmingw32.py rename to libportfwd/third-party/miniupnpc-1.4.20100609/setupmingw32.py index 62433e4ac..6e612453d --- a/libportfwd/third-party/miniupnpc-20090605/setupmingw32.py +++ b/libportfwd/third-party/miniupnpc-1.4.20100609/setupmingw32.py @@ -1,12 +1,12 @@ #! /usr/bin/python -# $Id: setupmingw32.py,v 1.1 2007/06/12 23:04:13 nanard Exp $ -# the MiniUPnP Project (c) 2007 Thomas Bernard +# $Id: setupmingw32.py,v 1.3 2009/10/30 09:18:18 nanard Exp $ +# the MiniUPnP Project (c) 2007-2009 Thomas Bernard # http://miniupnp.tuxfamily.org/ or http://miniupnp.free.fr/ # # python script to build the miniupnpc module under unix # from distutils.core import setup, Extension -setup(name="miniupnpc", version="1.0-RC6", +setup(name="miniupnpc", version="1.4", ext_modules=[ Extension(name="miniupnpc", sources=["miniupnpcmodule.c"], libraries=["ws2_32"], diff --git a/libportfwd/third-party/miniupnpc-20090605/testigddescparse.c b/libportfwd/third-party/miniupnpc-1.4.20100609/testigddescparse.c similarity index 75% rename from libportfwd/third-party/miniupnpc-20090605/testigddescparse.c rename to libportfwd/third-party/miniupnpc-1.4.20100609/testigddescparse.c index 527f5e111..1b0cde90e 100644 --- a/libportfwd/third-party/miniupnpc-20090605/testigddescparse.c +++ b/libportfwd/third-party/miniupnpc-1.4.20100609/testigddescparse.c @@ -1,8 +1,8 @@ -/* $Id: testigddescparse.c,v 1.1 2008/04/23 11:53:45 nanard Exp $ */ +/* $Id: testigddescparse.c,v 1.2 2009/12/03 13:50:06 nanard Exp $ */ /* Project : miniupnp * http://miniupnp.free.fr/ * Author : Thomas Bernard - * Copyright (c) 2008 Thomas Bernard + * Copyright (c) 2008-2009 Thomas Bernard * This software is subject to the conditions detailed in the * LICENCE file provided in this distribution. * */ @@ -11,11 +11,13 @@ #include #include "igd_desc_parse.h" #include "minixml.h" +#include "miniupnpc.h" int test_igd_desc_parse(char * buffer, int len) { struct IGDdatas igd; struct xmlparser parser; + struct UPNPUrls urls; memset(&igd, 0, sizeof(struct IGDdatas)); memset(&parser, 0, sizeof(struct xmlparser)); parser.xmlstart = buffer; @@ -26,6 +28,11 @@ int test_igd_desc_parse(char * buffer, int len) parser.datafunc = IGDdata; parsexml(&parser); printIGD(&igd); + GetUPNPUrls(&urls, &igd, "http://fake/desc/url/file.xml"); + printf("ipcondescURL='%s'\n", urls.ipcondescURL); + printf("controlURL='%s'\n", urls.controlURL); + printf("controlURL_CIF='%s'\n", urls.controlURL_CIF); + FreeUPNPUrls(&urls); return 0; } diff --git a/libportfwd/third-party/miniupnpc-1.4.20100609/testminiwget.c b/libportfwd/third-party/miniupnpc-1.4.20100609/testminiwget.c new file mode 100644 index 000000000..0624e5adf --- /dev/null +++ b/libportfwd/third-party/miniupnpc-1.4.20100609/testminiwget.c @@ -0,0 +1,45 @@ +/* $Id: testminiwget.c,v 1.1 2009/12/03 18:44:32 nanard Exp $ */ +/* Project : miniupnp + * Author : Thomas Bernard + * Copyright (c) 2005-2009 Thomas Bernard + * This software is subject to the conditions detailed in the + * LICENCE file provided in this distribution. + * */ +#include +#include +#include "miniwget.h" + +int main(int argc, char * * argv) +{ + void * data; + int size, writtensize; + FILE *f; + if(argc < 3) { + fprintf(stderr, "Usage:\t%s url file\n", argv[0]); + fprintf(stderr, "Example:\t%s http://www.google.com/ out.html\n", argv[0]); + return 1; + } + data = miniwget(argv[1], &size); + if(!data) { + fprintf(stderr, "Error fetching %s\n", argv[1]); + return 1; + } + printf("got %d bytes\n", size); + f = fopen(argv[2], "wb"); + if(!f) { + fprintf(stderr, "Cannot open file %s for writing\n", argv[2]); + free(data); + return 1; + } + writtensize = fwrite(data, 1, size, f); + if(writtensize != size) { + fprintf(stderr, "Could only write %d bytes out of %d to %s\n", + writtensize, size, argv[2]); + } else { + printf("%d bytes written to %s\n", writtensize, argv[2]); + } + fclose(f); + free(data); + return 0; +} + diff --git a/libportfwd/third-party/miniupnpc-20090605/testminixml.c b/libportfwd/third-party/miniupnpc-1.4.20100609/testminixml.c similarity index 100% rename from libportfwd/third-party/miniupnpc-20090605/testminixml.c rename to libportfwd/third-party/miniupnpc-1.4.20100609/testminixml.c diff --git a/libportfwd/third-party/miniupnpc-20090605/testupnpigd.py b/libportfwd/third-party/miniupnpc-1.4.20100609/testupnpigd.py similarity index 100% rename from libportfwd/third-party/miniupnpc-20090605/testupnpigd.py rename to libportfwd/third-party/miniupnpc-1.4.20100609/testupnpigd.py diff --git a/libportfwd/third-party/miniupnpc-20090605/testupnpreplyparse.c b/libportfwd/third-party/miniupnpc-1.4.20100609/testupnpreplyparse.c similarity index 100% rename from libportfwd/third-party/miniupnpc-20090605/testupnpreplyparse.c rename to libportfwd/third-party/miniupnpc-1.4.20100609/testupnpreplyparse.c diff --git a/libportfwd/third-party/miniupnpc-20090605/updateminiupnpcstrings.sh b/libportfwd/third-party/miniupnpc-1.4.20100609/updateminiupnpcstrings.sh similarity index 56% rename from libportfwd/third-party/miniupnpc-20090605/updateminiupnpcstrings.sh rename to libportfwd/third-party/miniupnpc-1.4.20100609/updateminiupnpcstrings.sh index f7b95a560..32fbf55ab 100755 --- a/libportfwd/third-party/miniupnpc-20090605/updateminiupnpcstrings.sh +++ b/libportfwd/third-party/miniupnpc-1.4.20100609/updateminiupnpcstrings.sh @@ -1,7 +1,10 @@ #! /bin/sh -# $Id: updateminiupnpcstrings.sh,v 1.2 2009/06/04 09:13:53 nanard Exp $ +# $Id: updateminiupnpcstrings.sh,v 1.6 2009/12/07 11:29:57 nanard Exp $ +# project miniupnp : http://miniupnp.free.fr/ +# (c) 2009 Thomas Bernard FILE=miniupnpcstrings.h +TEMPLATE_FILE=${FILE}.in # detecting the OS name and version OS_NAME=`uname -s` @@ -12,7 +15,7 @@ if [ -f /etc/debian_version ]; then fi # use lsb_release (Linux Standard Base) when available LSB_RELEASE=`which lsb_release` -if [ 0 -eq $? ]; then +if [ 0 -eq $? -a -x "${LSB_RELEASE}" ]; then OS_NAME=`${LSB_RELEASE} -i -s` OS_VERSION=`${LSB_RELEASE} -r -s` case $OS_NAME in @@ -25,12 +28,18 @@ if [ 0 -eq $? ]; then esac fi +# on AmigaOS 3, uname -r returns "unknown", so we use uname -v +if [ "$OS_NAME" = "AmigaOS" ]; then + if [ "$OS_VERSION" = "unknown" ]; then + OS_VERSION=`uname -v` + fi +fi + echo "Detected OS [$OS_NAME] version [$OS_VERSION]" -EXPR="s/OS_STRING \".*\"/OS_STRING \"${OS_NAME}\/${OS_VERSION}\"/" +EXPR="s|OS_STRING \".*\"|OS_STRING \"${OS_NAME}/${OS_VERSION}\"|" #echo $EXPR -echo "Backuping $FILE to $FILE.bak." -cp $FILE $FILE.bak +test -f ${FILE}.in echo "setting OS_STRING macro value to ${OS_NAME}/${OS_VERSION} in $FILE." -cat $FILE.bak | sed -e "$EXPR" > $FILE +sed -e "$EXPR" < $TEMPLATE_FILE > $FILE diff --git a/libportfwd/third-party/miniupnpc-20090605/upnpc.c b/libportfwd/third-party/miniupnpc-1.4.20100609/upnpc.c similarity index 85% rename from libportfwd/third-party/miniupnpc-20090605/upnpc.c rename to libportfwd/third-party/miniupnpc-1.4.20100609/upnpc.c index 2c5debe31..f89e8779a 100644 --- a/libportfwd/third-party/miniupnpc-20090605/upnpc.c +++ b/libportfwd/third-party/miniupnpc-1.4.20100609/upnpc.c @@ -1,13 +1,14 @@ -/* $Id: upnpc.c,v 1.65 2008/10/14 18:05:27 nanard Exp $ */ +/* $Id: upnpc.c,v 1.72 2010/05/29 09:21:12 nanard Exp $ */ /* Project : miniupnp * Author : Thomas Bernard - * Copyright (c) 2005-2008 Thomas Bernard + * Copyright (c) 2005-2010 Thomas Bernard * This software is subject to the conditions detailed in the - * LICENCE file provided in this distribution. - * */ + * LICENCE file provided in this distribution. */ + #include #include #include +#include #ifdef WIN32 #include #define snprintf _snprintf @@ -46,23 +47,27 @@ static void DisplayInfos(struct UPNPUrls * urls, char lastconnerr[64]; unsigned int uptime; unsigned int brUp, brDown; + time_t timenow, timestarted; int r; UPNP_GetConnectionTypeInfo(urls->controlURL, - data->servicetype, + data->first.servicetype, connectionType); if(connectionType[0]) printf("Connection Type : %s\n", connectionType); else printf("GetConnectionTypeInfo failed.\n"); - UPNP_GetStatusInfo(urls->controlURL, data->servicetype, + UPNP_GetStatusInfo(urls->controlURL, data->first.servicetype, status, &uptime, lastconnerr); - printf("Status : %s, uptime=%u, LastConnectionError : %s\n", + printf("Status : %s, uptime=%us, LastConnectionError : %s\n", status, uptime, lastconnerr); - UPNP_GetLinkLayerMaxBitRates(urls->controlURL_CIF, data->servicetype_CIF, + timenow = time(NULL); + timestarted = timenow - uptime; + printf(" Time started : %s", ctime(×tarted)); + UPNP_GetLinkLayerMaxBitRates(urls->controlURL_CIF, data->CIF.servicetype, &brDown, &brUp); printf("MaxBitRateDown : %u bps MaxBitRateUp %u bps\n", brDown, brUp); r = UPNP_GetExternalIPAddress(urls->controlURL, - data->servicetype, + data->first.servicetype, externalIPAddress); if(r != UPNPCOMMAND_SUCCESS) printf("GetExternalIPAddress() returned %d\n", r); @@ -77,10 +82,10 @@ static void GetConnectionStatus(struct UPNPUrls * urls, { unsigned int bytessent, bytesreceived, packetsreceived, packetssent; DisplayInfos(urls, data); - bytessent = UPNP_GetTotalBytesSent(urls->controlURL_CIF, data->servicetype_CIF); - bytesreceived = UPNP_GetTotalBytesReceived(urls->controlURL_CIF, data->servicetype_CIF); - packetssent = UPNP_GetTotalPacketsSent(urls->controlURL_CIF, data->servicetype_CIF); - packetsreceived = UPNP_GetTotalPacketsReceived(urls->controlURL_CIF, data->servicetype_CIF); + bytessent = UPNP_GetTotalBytesSent(urls->controlURL_CIF, data->CIF.servicetype); + bytesreceived = UPNP_GetTotalBytesReceived(urls->controlURL_CIF, data->CIF.servicetype); + packetssent = UPNP_GetTotalPacketsSent(urls->controlURL_CIF, data->CIF.servicetype); + packetsreceived = UPNP_GetTotalPacketsReceived(urls->controlURL_CIF, data->CIF.servicetype); printf("Bytes: Sent: %8u\tRecv: %8u\n", bytessent, bytesreceived); printf("Packets: Sent: %8u\tRecv: %8u\n", packetssent, packetsreceived); } @@ -107,7 +112,8 @@ static void ListRedirections(struct UPNPUrls * urls, rHost[0] = '\0'; enabled[0] = '\0'; duration[0] = '\0'; desc[0] = '\0'; extPort[0] = '\0'; intPort[0] = '\0'; intClient[0] = '\0'; - r = UPNP_GetGenericPortMappingEntry(urls->controlURL, data->servicetype, + r = UPNP_GetGenericPortMappingEntry(urls->controlURL, + data->first.servicetype, index, extPort, intClient, intPort, protocol, desc, enabled, @@ -160,25 +166,26 @@ static void SetRedirectAndTest(struct UPNPUrls * urls, } UPNP_GetExternalIPAddress(urls->controlURL, - data->servicetype, + data->first.servicetype, externalIPAddress); if(externalIPAddress[0]) printf("ExternalIPAddress = %s\n", externalIPAddress); else printf("GetExternalIPAddress failed.\n"); - r = UPNP_AddPortMapping(urls->controlURL, data->servicetype, + r = UPNP_AddPortMapping(urls->controlURL, data->first.servicetype, eport, iport, iaddr, 0, proto, 0); if(r!=UPNPCOMMAND_SUCCESS) - printf("AddPortMapping(%s, %s, %s) failed with code %d\n", - eport, iport, iaddr, r); + printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n", + eport, iport, iaddr, r, strupnperror(r)); r = UPNP_GetSpecificPortMappingEntry(urls->controlURL, - data->servicetype, + data->first.servicetype, eport, proto, intClient, intPort); if(r!=UPNPCOMMAND_SUCCESS) - printf("GetSpecificPortMappingEntry() failed with code %d\n", r); + printf("GetSpecificPortMappingEntry() failed with code %d (%s)\n", + r, strupnperror(r)); if(intClient[0]) { printf("InternalIP:Port = %s:%s\n", intClient, intPort); @@ -205,7 +212,7 @@ RemoveRedirect(struct UPNPUrls * urls, fprintf(stderr, "protocol invalid\n"); return; } - r = UPNP_DeletePortMapping(urls->controlURL, data->servicetype, eport, proto, 0); + r = UPNP_DeletePortMapping(urls->controlURL, data->first.servicetype, eport, proto, 0); printf("UPNP_DeletePortMapping() returned : %d\n", r); } @@ -217,11 +224,12 @@ int main(int argc, char ** argv) char ** commandargv = 0; int commandargc = 0; struct UPNPDev * devlist = 0; - char lanaddr[16]; /* my ip address on the LAN */ + char lanaddr[64]; /* my ip address on the LAN */ int i; const char * rootdescurl = 0; const char * multicastif = 0; const char * minissdpdpath = 0; + int retcode = 0; #ifdef WIN32 WSADATA wsaData; @@ -232,7 +240,7 @@ int main(int argc, char ** argv) return -1; } #endif - printf("upnpc : miniupnpc library test client. (c) 2006-2008 Thomas Bernard\n"); + printf("upnpc : miniupnpc library test client. (c) 2006-2010 Thomas Bernard\n"); printf("Go to http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/\n" "for more information.\n"); /* command line processing */ @@ -266,7 +274,7 @@ int main(int argc, char ** argv) || (command == 'r' && argc<2)) { fprintf(stderr, "Usage :\t%s [options] -a ip port external_port protocol\n\t\tAdd port redirection\n", argv[0]); - fprintf(stderr, " \t%s [options] -d external_port protocol\n\t\tDelete port redirection\n", argv[0]); + fprintf(stderr, " \t%s [options] -d external_port protocol [port2 protocol2] [...]\n\t\tDelete port redirection\n", argv[0]); fprintf(stderr, " \t%s [options] -s\n\t\tGet Connection status\n", argv[0]); fprintf(stderr, " \t%s [options] -l\n\t\tList redirections\n", argv[0]); fprintf(stderr, " \t%s [options] -r port1 protocol1 [port2 protocol2] [...]\n\t\tAdd all redirections to the current host\n", argv[0]); @@ -336,7 +344,10 @@ int main(int argc, char ** argv) commandargv[2], commandargv[3]); break; case 'd': - RemoveRedirect(&urls, &data, commandargv[0], commandargv[1]); + for(i=0; i diff --git a/libportfwd/third-party/miniupnpc-1.4.20100609/wingenminiupnpcstrings.c b/libportfwd/third-party/miniupnpc-1.4.20100609/wingenminiupnpcstrings.c new file mode 100644 index 000000000..0da8bedfc --- /dev/null +++ b/libportfwd/third-party/miniupnpc-1.4.20100609/wingenminiupnpcstrings.c @@ -0,0 +1,69 @@ +/* $Id: wingenminiupnpcstrings.c,v 1.1 2009/12/10 18:46:15 nanard Exp $ */ +/* Project: miniupnp + * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ + * Author: Thomas Bernard + * Copyright (c) 2005-2009 Thomas Bernard + * This software is subjects to the conditions detailed + * in the LICENSE file provided within this distribution */ +#include +#include + +/* This program display the Windows version and is used to + * generate the miniupnpcstrings.h + * wingenminiupnpcstrings miniupnpcstrings.h.in miniupnpcstrings.h + */ +int main(int argc, char * * argv) { + char buffer[256]; + OSVERSIONINFO osvi; + FILE * fin; + FILE * fout; + int n; + /* dwMajorVersion : + The major version number of the operating system. For more information, see Remarks. + dwMinorVersion : + The minor version number of the operating system. For more information, see Remarks. + dwBuildNumber : + The build number of the operating system. + dwPlatformId + The operating system platform. This member can be the following value. + szCSDVersion + A null-terminated string, such as "Service Pack 3", that indicates the + latest Service Pack installed on the system. If no Service Pack has + been installed, the string is empty. + */ + ZeroMemory(&osvi, sizeof(OSVERSIONINFO)); + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + + GetVersionEx(&osvi); + + printf("Windows %lu.%lu Build %lu %s\n", + osvi.dwMajorVersion, osvi.dwMinorVersion, + osvi.dwBuildNumber, (const char *)&(osvi.szCSDVersion)); + + if(argc >= 3) { + fin = fopen(argv[1], "r"); + if(!fin) { + fprintf(stderr, "Cannot open %s for reading.\n", argv[1]); + return 1; + } + fout = fopen(argv[2], "w"); + if(!fout) { + fprintf(stderr, "Cannot open %s for writing.\n", argv[2]); + return 1; + } + n = 0; + while(fgets(buffer, sizeof(buffer), fin)) { + if(0 == memcmp(buffer, "#define OS_STRING \"OS/version\"", 30)) { + sprintf(buffer, "#define OS_STRING \"MSWindows/%ld.%ld.%ld\"\n", + osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber); + } + /*fputs(buffer, stdout);*/ + fputs(buffer, fout); + n++; + } + fclose(fin); + fclose(fout); + printf("%d lines written to %s.\n", n, argv[2]); + } + return 0; +} From 23d7eeeb0251b42b8a1d7ffef3ee87532b6babef Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Wed, 27 Oct 2010 04:37:22 +0200 Subject: [PATCH 02/13] * Prevent shutting down socket before all data has been read. --- src/bufferiodevice.cpp | 18 ++++----- src/bufferiodevice.h | 1 - src/connection.cpp | 11 +++++- src/connection.h | 8 ++-- src/filetransferconnection.cpp | 69 +++++++++++++++++++--------------- src/filetransferconnection.h | 5 +-- 6 files changed, 61 insertions(+), 51 deletions(-) diff --git a/src/bufferiodevice.cpp b/src/bufferiodevice.cpp index 17c4fbf30..b4e533643 100644 --- a/src/bufferiodevice.cpp +++ b/src/bufferiodevice.cpp @@ -1,10 +1,11 @@ #include #include "bufferiodevice.h" + BufferIODevice::BufferIODevice( unsigned int size, QObject *parent ) : QIODevice( parent ), - m_size(size), - m_received(0) + m_size( size ), + m_received( 0 ) { } @@ -27,7 +28,6 @@ BufferIODevice::close() qDebug() << Q_FUNC_INFO; QIODevice::close(); - // TODO ? } @@ -39,6 +39,7 @@ BufferIODevice::inputComplete( const QString& errmsg ) emit readChannelFinished(); } + void BufferIODevice::addData( QByteArray ba ) { @@ -57,10 +58,8 @@ BufferIODevice::bytesAvailable() const qint64 BufferIODevice::readData( char * data, qint64 maxSize ) { - // qDebug() << Q_FUNC_INFO << maxSize; - + //qDebug() << Q_FUNC_INFO << maxSize; QMutexLocker lock( &m_mut ); -// qDebug() << "readData begins, bufersize:" << m_buffer.length(); qint64 size = maxSize; if ( m_buffer.length() < maxSize ) @@ -69,7 +68,7 @@ BufferIODevice::readData( char * data, qint64 maxSize ) memcpy( data, m_buffer.data(), size ); m_buffer.remove( 0, size ); -// qDebug() << "readData ends, bufersize:" << m_buffer.length(); + //qDebug() << "readData ends, bufersize:" << m_buffer.length(); return size; } @@ -93,13 +92,14 @@ qint64 BufferIODevice::size() const return m_size; } + bool BufferIODevice::atEnd() const { QMutexLocker lock( &m_mut ); - return m_size == m_received && - m_buffer.length() == 0; + return ( m_size == m_received && m_buffer.length() == 0 ); } + void BufferIODevice::clear() { diff --git a/src/bufferiodevice.h b/src/bufferiodevice.h index d54e98c9e..69a661d76 100644 --- a/src/bufferiodevice.h +++ b/src/bufferiodevice.h @@ -21,7 +21,6 @@ public: void addData( QByteArray ba ); void clear(); - bool isOpen() const { qDebug() << "isOpen"; return true; } OpenMode openMode() const { qDebug() << "openMode"; return QIODevice::ReadWrite; } void inputComplete( const QString& errmsg = "" ); diff --git a/src/connection.cpp b/src/connection.cpp index 13fb28d9e..21fb2bd44 100644 --- a/src/connection.cpp +++ b/src/connection.cpp @@ -266,10 +266,17 @@ Connection::socketDisconnected() void Connection::socketDisconnectedError(QAbstractSocket::SocketError e) { - qDebug() << "SOCKET ERROR CODE" << e << this->name() << " CALLING Connection::shutdown(false)"; + if ( e == QAbstractSocket::RemoteHostClosedError ) + return; + + qDebug() << "SOCKET ERROR CODE" << e << this->name() << "CALLING Connection::shutdown(false)"; + m_peer_disconnected = true; + emit socketErrored(e); - shutdown(false); + emit socketClosed(); + + shutdown( false ); } diff --git a/src/connection.h b/src/connection.h index a771c6eba..79a3259e9 100644 --- a/src/connection.h +++ b/src/connection.h @@ -65,8 +65,8 @@ public: qint64 bytesSent() const { return m_tx_bytes; } qint64 bytesReceived() const { return m_rx_bytes; } - void setMsgProcessorModeOut( quint32 m ) { m_msgprocessor_out.setMode(m); } - void setMsgProcessorModeIn( quint32 m ) { m_msgprocessor_in.setMode(m); } + void setMsgProcessorModeOut( quint32 m ) { m_msgprocessor_out.setMode( m ); } + void setMsgProcessorModeIn( quint32 m ) { m_msgprocessor_in.setMode( m ); } signals: void ready(); @@ -74,7 +74,7 @@ signals: void finished(); void statsTick( qint64 tx_bytes_sec, qint64 rx_bytes_sec ); void socketClosed(); - void socketErrored(QAbstractSocket::SocketError); + void socketErrored( QAbstractSocket::SocketError ); protected: virtual void setup() = 0; @@ -93,7 +93,7 @@ private slots: void handleIncomingQueueEmpty(); void sendMsg_now( msg_ptr ); void socketDisconnected(); - void socketDisconnectedError(QAbstractSocket::SocketError); + void socketDisconnectedError( QAbstractSocket::SocketError ); void readyRead(); void doSetup(); void authCheckTimeout(); diff --git a/src/filetransferconnection.cpp b/src/filetransferconnection.cpp index 517e5be31..3bb5cddbc 100644 --- a/src/filetransferconnection.cpp +++ b/src/filetransferconnection.cpp @@ -16,8 +16,7 @@ using namespace Tomahawk; -FileTransferConnection::FileTransferConnection( Servent* s, ControlConnection* cc, - QString fid, unsigned int size ) +FileTransferConnection::FileTransferConnection( Servent* s, ControlConnection* cc, QString fid, unsigned int size ) : Connection( s ) , m_cc( cc ) , m_fid( fid ) @@ -27,8 +26,9 @@ FileTransferConnection::FileTransferConnection( Servent* s, ControlConnection* c , m_allok( false ) { qDebug() << Q_FUNC_INFO; - BufferIODevice * bio = new BufferIODevice(size); - m_iodev = QSharedPointer( bio ); // device audio data gets written to + + BufferIODevice* bio = new BufferIODevice( size ); + m_iodev = QSharedPointer( bio ); // device audio data gets written to m_iodev->open( QIODevice::ReadWrite ); APP->servent().registerFileTransferConnection( this ); @@ -41,13 +41,18 @@ FileTransferConnection::FileTransferConnection( Servent* s, ControlConnection* c connect( this, SIGNAL( finished() ), SLOT( deleteLater() ), Qt::QueuedConnection ); // don't fuck with our messages at all. No compression, no parsing, nothing: - this->setMsgProcessorModeIn( MsgProcessor::NOTHING ); + this->setMsgProcessorModeIn ( MsgProcessor::NOTHING ); this->setMsgProcessorModeOut( MsgProcessor::NOTHING ); } FileTransferConnection::FileTransferConnection( Servent* s, QString fid ) - : Connection(s), m_fid(fid), m_type(SENDING), m_badded(0), m_bsent(0), m_allok( false ) + : Connection( s ) + , m_fid( fid ) + , m_type( SENDING ) + , m_badded( 0 ) + , m_bsent( 0 ) + , m_allok( false ) { APP->servent().registerFileTransferConnection( this ); // auto delete when connection closes: @@ -65,7 +70,10 @@ FileTransferConnection::~FileTransferConnection() // protected, we could expose it: //m_iodev->setErrorString("FTConnection providing data went away mid-transfer"); + + ((BufferIODevice*)m_iodev.data())->inputComplete(); } + APP->servent().fileTransferFinished( this ); } @@ -73,9 +81,9 @@ FileTransferConnection::~FileTransferConnection() QString FileTransferConnection::id() const { - return QString("FTC[%1 %2]") - .arg( m_type == SENDING ? "TX" : "RX" ) - .arg(m_fid); + return QString( "FTC[%1 %2]" ) + .arg( m_type == SENDING ? "TX" : "RX" ) + .arg( m_fid ); } @@ -85,8 +93,8 @@ FileTransferConnection::showStats( qint64 tx, qint64 rx ) if( tx > 0 || rx > 0 ) { qDebug() << id() - << QString("Down: %L1 bytes/sec, ").arg(rx) - << QString("Up: %L1 bytes/sec").arg(tx); + << QString( "Down: %L1 bytes/sec," ).arg( rx ) + << QString( "Up: %L1 bytes/sec" ).arg( tx ); } } @@ -95,7 +103,7 @@ void FileTransferConnection::setup() { connect( this, SIGNAL( statsTick( qint64, qint64 ) ), SLOT( showStats( qint64, qint64 ) ) ); - if(m_type == RECEIVING) + if( m_type == RECEIVING ) { qDebug() << "in RX mode"; return; @@ -103,25 +111,25 @@ FileTransferConnection::setup() qDebug() << "in TX mode, fid:" << m_fid; - DatabaseCommand_LoadFile * cmd = new DatabaseCommand_LoadFile(m_fid); - connect(cmd, SIGNAL(result(QVariantMap)), this, SLOT(startSending(QVariantMap))); - TomahawkApp::instance()->database()->enqueue(QSharedPointer(cmd)); + DatabaseCommand_LoadFile* cmd = new DatabaseCommand_LoadFile( m_fid ); + connect( cmd, SIGNAL( result( QVariantMap ) ), SLOT( startSending( QVariantMap ) ) ); + TomahawkApp::instance()->database()->enqueue( QSharedPointer( cmd ) ); } void FileTransferConnection::startSending( QVariantMap f ) { - Tomahawk::result_ptr result(new Tomahawk::Result(f, collection_ptr())); + Tomahawk::result_ptr result( new Tomahawk::Result( f, collection_ptr() ) ); qDebug() << "Starting to transmit" << result->url(); - QSharedPointer io = TomahawkApp::instance()->getIODeviceForUrl(result); - if(!io) + QSharedPointer io = TomahawkApp::instance()->getIODeviceForUrl( result ); + if( !io ) { qDebug() << "Couldn't read from source:" << result->url(); shutdown(); return; } - m_readdev = QSharedPointer(io); + m_readdev = QSharedPointer( io ); sendSome(); } @@ -129,7 +137,7 @@ FileTransferConnection::startSending( QVariantMap f ) void FileTransferConnection::handleMsg( msg_ptr msg ) { - Q_ASSERT(m_type == FileTransferConnection::RECEIVING); + Q_ASSERT( m_type == FileTransferConnection::RECEIVING ); Q_ASSERT( msg->is( Msg::RAW ) ); m_badded += msg->payload().length(); @@ -139,13 +147,11 @@ FileTransferConnection::handleMsg( msg_ptr msg ) // << "payload len" << msg->payload().length() // << "written to device so far: " << m_badded; - if( !msg->is( Msg::FRAGMENT ) ) { - qDebug() << endl - << "*** Got last msg in filetransfer. added" << m_badded - << "io size" << m_iodev->size() - << endl; + qDebug() << "*** Got last msg in filetransfer. added" << m_badded + << "io size" << m_iodev->size(); + m_allok = true; // tell our iodev there is no more data to read, no args meaning a success: ((BufferIODevice*)m_iodev.data())->inputComplete(); @@ -156,23 +162,24 @@ FileTransferConnection::handleMsg( msg_ptr msg ) Connection* FileTransferConnection::clone() { - Q_ASSERT(false); return 0; + Q_ASSERT( false ); + return 0; } void FileTransferConnection::sendSome() { - Q_ASSERT(m_type == FileTransferConnection::SENDING); + Q_ASSERT( m_type == FileTransferConnection::SENDING ); - QByteArray ba = m_readdev->read(BLOCKSIZE); + QByteArray ba = m_readdev->read( BLOCKSIZE ); m_bsent += ba.length(); - //qDebug() << "Sending " << ba.length() << " bytes of audiofile"; + //qDebug() << "Sending" << ba.length() << "bytes of audiofile"; if( m_readdev->atEnd() ) { sendMsg( Msg::factory( ba, Msg::RAW ) ); - qDebug() << "Sent all. DONE. " << m_bsent; - shutdown(true); + qDebug() << "Sent all. DONE." << m_bsent; + shutdown( true ); return; } else diff --git a/src/filetransferconnection.h b/src/filetransferconnection.h index 7814df758..6dd0464bd 100644 --- a/src/filetransferconnection.h +++ b/src/filetransferconnection.h @@ -32,10 +32,7 @@ public: void setup(); Connection* clone(); - const QSharedPointer& iodevice() - { - return m_iodev; - } + const QSharedPointer& iodevice() { return m_iodev; } Type type() const { return m_type; } QString fid() const { return m_fid; } From 96e7ea91f20e472890cfbb9d4a394a6b112df8ca Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Wed, 27 Oct 2010 05:00:48 +0200 Subject: [PATCH 03/13] * Only activate Playlist / Collection items on double-click. * Cleanup whitespace / remove debug. --- src/jabber/jabber_p.cpp | 12 ++++++------ src/playlist/trackview.cpp | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/jabber/jabber_p.cpp b/src/jabber/jabber_p.cpp index 6d9e1e69d..7a94bc89e 100644 --- a/src/jabber/jabber_p.cpp +++ b/src/jabber/jabber_p.cpp @@ -443,19 +443,19 @@ Jabber_p::handleRosterPresence( const RosterItem& item, const std::string& resou QRegExp regex( "tomahawk\\d+" ); if( res != "tomahawk-tomahawk" && !res.contains( regex ) ) { - qDebug() << "not considering resource of " << res; + //qDebug() << "not considering resource of" << res; // Disco them to check if they are tomahawk-capable - //qDebug() << "No tomahawk resource, DISCOing... " << jid.full().c_str(); + //qDebug() << "No tomahawk resource, DISCOing..." << jid.full().c_str(); //m_client->disco()->getDiscoInfo( jid, "", this, 0 ); return; } - qDebug() << "handling presence for resource of " << res; + //qDebug() << "handling presence for resource of" << res; - //qDebug() << Q_FUNC_INFO << "jid: " << QString::fromStdString(item.jid()) - // << " resource: " << QString::fromStdString(resource) - // << " presencetype " << presence; + //qDebug() << Q_FUNC_INFO << "jid:" << QString::fromStdString(item.jid()) + // << " resource:" << QString::fromStdString(resource) + // << " presencetype" << presence; // "going offline" event if ( !presenceMeansOnline( presence ) && diff --git a/src/playlist/trackview.cpp b/src/playlist/trackview.cpp index 4b2d93b33..ada0a2e49 100644 --- a/src/playlist/trackview.cpp +++ b/src/playlist/trackview.cpp @@ -35,7 +35,7 @@ TrackView::TrackView( QWidget* parent ) header()->setMinimumSectionSize( 60 ); restoreColumnsState(); - connect( this, SIGNAL( activated( QModelIndex ) ), SLOT( onItemActivated( QModelIndex ) ) ); + connect( this, SIGNAL( doubleClicked( QModelIndex ) ), SLOT( onItemActivated( QModelIndex ) ) ); connect( header(), SIGNAL( sectionResized( int, int, int ) ), SLOT( onSectionResized( int, int, int ) ) ); } From da92dbfc4b69eb61491543dd3607d186e99fbb23 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Wed, 27 Oct 2010 05:21:07 +0200 Subject: [PATCH 04/13] * Fix crash in TopBar when fading out dudes. --- src/topbar/topbar.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/topbar/topbar.cpp b/src/topbar/topbar.cpp index 71864a2f3..e21514b63 100644 --- a/src/topbar/topbar.cpp +++ b/src/topbar/topbar.cpp @@ -97,8 +97,8 @@ TopBar::fadeInDude( unsigned int i ) { // qDebug() << Q_FUNC_INFO << i; - QLabel * dude = m_dudes.at( i ); - QPropertyAnimation * ani = new QPropertyAnimation( dude, "pos" ); + QLabel* dude = m_dudes.at( i ); + QPropertyAnimation* ani = new QPropertyAnimation( dude, "pos" ); ani->setDuration( 1000 ); ani->setEasingCurve( QEasingCurve::InQuad ); ani->setStartValue( QPoint( -10,0 ) ); @@ -115,8 +115,8 @@ TopBar::fadeOutDude( unsigned int i ) { // qDebug() << Q_FUNC_INFO << i; - QLabel * dude = m_dudes.at( i ); - QPropertyAnimation * ani = new QPropertyAnimation( dude, "pos" ); + QLabel* dude = m_dudes.at( i ); + QPropertyAnimation* ani = new QPropertyAnimation( dude, "pos" ); ani->setDuration( 1000 ); ani->setEasingCurve( QEasingCurve::OutQuad ); ani->setStartValue( dude->pos() ); @@ -152,12 +152,14 @@ TopBar::setNumSources( unsigned int i ) } else { - int k = qMin( (unsigned int)2, m_sources - 1 ); + int k = qMin( (unsigned int)MAXDUDES - 1, m_sources - 1 ); do { - fadeOutDude( k-- ); + fadeOutDude( k ); m_sources--; - } while( m_sources != i ); + } while( k-- > i ); + + m_sources = i; } } From 338639593ccb7243aea6306e851f74969b2e3b06 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Wed, 27 Oct 2010 07:39:59 +0200 Subject: [PATCH 05/13] * Added DatabaseCommand_RenamePlaylist. * Added ItemDelegate for the SourcesModel which provides an editor for inline renaming playlist items. --- include/tomahawk/playlist.h | 9 +-- src/CMakeLists.txt | 4 ++ .../databasecommand_renameplaylist.cpp | 56 +++++++++++++++++++ src/database/databasecommand_renameplaylist.h | 39 +++++++++++++ src/playlist.cpp | 11 ++++ src/playlist/playlistitemdelegate.cpp | 7 +++ src/playlist/playlistitemdelegate.h | 2 + src/sourcetree/sourcesmodel.cpp | 34 +++++++++++ src/sourcetree/sourcesmodel.h | 3 + src/sourcetree/sourcetreedelegate.cpp | 52 +++++++++++++++++ src/sourcetree/sourcetreedelegate.h | 25 +++++++++ src/sourcetree/sourcetreeview.cpp | 7 ++- src/sourcetree/sourcetreeview.h | 2 + src/topbar/topbar.cpp | 2 +- 14 files changed, 247 insertions(+), 6 deletions(-) create mode 100644 src/database/databasecommand_renameplaylist.cpp create mode 100644 src/database/databasecommand_renameplaylist.h create mode 100644 src/sourcetree/sourcetreedelegate.cpp create mode 100644 src/sourcetree/sourcetreedelegate.h diff --git a/include/tomahawk/playlist.h b/include/tomahawk/playlist.h index 1825b358b..88b60dab3 100644 --- a/include/tomahawk/playlist.h +++ b/include/tomahawk/playlist.h @@ -97,6 +97,7 @@ public: bool shared ); static bool remove( const playlist_ptr& playlist ); + bool rename( const QString& title ); virtual void loadRevision( const QString& rev = "" ); @@ -117,14 +118,14 @@ public: // these need to exist and be public for the json serialization stuff // you SHOULD NOT call them. They are used for an alternate CTOR method from json. // maybe friend QObjectHelper and make them private? - Playlist( const source_ptr& author ) : - m_source( author ) - , m_lastmodified( 0 ) + Playlist( const source_ptr& author ) + : m_source( author ) + , m_lastmodified( 0 ) { qDebug() << Q_FUNC_INFO << "JSON"; } void setCurrentrevision( const QString& s ) { m_currentrevision = s; } - void setTitle( const QString& s ) { m_title= s; } + void setTitle( const QString& s ) { m_title = s; } void setInfo( const QString& s ) { m_info = s; } void setCreator( const QString& s ) { m_creator = s; } void setGuid( const QString& s ) { m_guid = s; } diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3718af5dd..ed62920c5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -73,6 +73,7 @@ SET( tomahawkSources ${tomahawkSources} database/databasecommand_loadallplaylists.cpp database/databasecommand_createplaylist.cpp database/databasecommand_deleteplaylist.cpp + database/databasecommand_renameplaylist.cpp database/databasecommand_loadops.cpp database/databasecommand_updatesearchindex.cpp database/databasecollection.cpp @@ -113,6 +114,7 @@ SET( tomahawkSourcesGui ${tomahawkSourcesGui} sourcetree/sourcetreeitem.cpp sourcetree/sourcetreeitemwidget.cpp sourcetree/sourcetreeview.cpp + sourcetree/sourcetreedelegate.cpp topbar/topbar.cpp topbar/clearbutton.cpp @@ -171,6 +173,7 @@ SET( tomahawkHeaders ${tomahawkHeaders} database/databasecommand_loadallplaylists.h database/databasecommand_createplaylist.h database/databasecommand_deleteplaylist.h + database/databasecommand_renameplaylist.h database/databasecommand_loadops.h database/databasecommand_updatesearchindex.h database/databasecollection.h @@ -228,6 +231,7 @@ SET( tomahawkHeadersGui ${tomahawkHeadersGui} sourcetree/sourcetreeitem.h sourcetree/sourcetreeitemwidget.h sourcetree/sourcetreeview.h + sourcetree/sourcetreedelegate.h topbar/topbar.h topbar/clearbutton.h diff --git a/src/database/databasecommand_renameplaylist.cpp b/src/database/databasecommand_renameplaylist.cpp new file mode 100644 index 000000000..4f9462943 --- /dev/null +++ b/src/database/databasecommand_renameplaylist.cpp @@ -0,0 +1,56 @@ +#include "databasecommand_renameplaylist.h" + +#include + +#include "tomahawk/tomahawkapp.h" + +using namespace Tomahawk; + + +DatabaseCommand_RenamePlaylist::DatabaseCommand_RenamePlaylist( const source_ptr& source, const QString& playlistguid, const QString& playlistTitle ) + : DatabaseCommandLoggable( source ) +{ + setPlaylistguid( playlistguid ); + setPlaylistTitle( playlistTitle ); +} + + +void +DatabaseCommand_RenamePlaylist::exec( DatabaseImpl* lib ) +{ + qDebug() << Q_FUNC_INFO; + + TomahawkSqlQuery cre = lib->newquery(); + + QString sql = QString( "UPDATE playlist SET title = :title WHERE guid = :id AND source %1" ) + .arg( source()->isLocal() ? "IS NULL" : QString( "= %1" ).arg( source()->id() ) ); + + cre.prepare( sql ); + cre.bindValue( ":id", m_playlistguid ); + cre.bindValue( ":title", m_playlistguid ); + + bool ok = cre.exec(); + if( !ok ) + { + qDebug() << cre.lastError().databaseText() + << cre.lastError().driverText() + << cre.executedQuery() + << cre.boundValues(); + Q_ASSERT( ok ); + } +} + + +void +DatabaseCommand_RenamePlaylist::postCommitHook() +{ + qDebug() << Q_FUNC_INFO << "..reporting.."; + + playlist_ptr playlist = source()->collection()->playlist( m_playlistguid ); + Q_ASSERT( !playlist.isNull() ); + + playlist->setTitle( m_playlistTitle ); + + if( source()->isLocal() ) + APP->servent().triggerDBSync(); +} diff --git a/src/database/databasecommand_renameplaylist.h b/src/database/databasecommand_renameplaylist.h new file mode 100644 index 000000000..a5e3c186e --- /dev/null +++ b/src/database/databasecommand_renameplaylist.h @@ -0,0 +1,39 @@ +#ifndef DATABASECOMMAND_RENAMEPLAYLIST_H +#define DATABASECOMMAND_RENAMEPLAYLIST_H + +#include "databaseimpl.h" +#include "databasecommandloggable.h" +#include "tomahawk/source.h" +#include "tomahawk/typedefs.h" + +class DatabaseCommand_RenamePlaylist : public DatabaseCommandLoggable +{ +Q_OBJECT +Q_PROPERTY( QString playlistguid READ playlistguid WRITE setPlaylistguid ) +Q_PROPERTY( QString playlistTitle READ playlistTitle WRITE setPlaylistTitle ) + +public: + explicit DatabaseCommand_RenamePlaylist( QObject* parent = 0 ) + : DatabaseCommandLoggable( parent ) + {} + + explicit DatabaseCommand_RenamePlaylist( const Tomahawk::source_ptr& source, const QString& playlistguid, const QString& playlistTitle ); + + QString commandname() const { return "renameplaylist"; } + + virtual void exec( DatabaseImpl* lib ); + virtual void postCommitHook(); + virtual bool doesMutates() const { return true; } + + QString playlistguid() const { return m_playlistguid; } + void setPlaylistguid( const QString& s ) { m_playlistguid = s; } + + QString playlistTitle() const { return m_playlistTitle; } + void setPlaylistTitle( const QString& s ) { m_playlistTitle = s; } + +private: + QString m_playlistguid; + QString m_playlistTitle; +}; + +#endif // DATABASECOMMAND_RENAMEPLAYLIST_H diff --git a/src/playlist.cpp b/src/playlist.cpp index 892e3191e..824e34c48 100644 --- a/src/playlist.cpp +++ b/src/playlist.cpp @@ -9,6 +9,7 @@ #include "databasecommand_setplaylistrevision.h" #include "databasecommand_createplaylist.h" #include "databasecommand_deleteplaylist.h" +#include "databasecommand_renameplaylist.h" using namespace Tomahawk; @@ -108,6 +109,16 @@ Playlist::remove( const playlist_ptr& playlist ) } +bool +Playlist::rename( const QString& title ) +{ + DatabaseCommand_RenamePlaylist* cmd = new DatabaseCommand_RenamePlaylist( author(), guid(), title ); + APP->database()->enqueue( QSharedPointer(cmd) ); + + return true; // FIXME +} + + void Playlist::reportCreated( const playlist_ptr& self ) { diff --git a/src/playlist/playlistitemdelegate.cpp b/src/playlist/playlistitemdelegate.cpp index b21629fbf..c5ca11fb4 100644 --- a/src/playlist/playlistitemdelegate.cpp +++ b/src/playlist/playlistitemdelegate.cpp @@ -34,6 +34,13 @@ PlaylistItemDelegate::sizeHint( const QStyleOptionViewItem& option, const QModel } +QWidget* +PlaylistItemDelegate::createEditor ( QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index ) const +{ + return 0; +} + + void PlaylistItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const { diff --git a/src/playlist/playlistitemdelegate.h b/src/playlist/playlistitemdelegate.h index 1f31ca5f4..f47826f63 100644 --- a/src/playlist/playlistitemdelegate.h +++ b/src/playlist/playlistitemdelegate.h @@ -21,6 +21,8 @@ protected: void paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const; QSize sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const; + QWidget* createEditor( QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index ) const; + private: unsigned int m_removalProgress; QAbstractItemView* m_view; diff --git a/src/sourcetree/sourcesmodel.cpp b/src/sourcetree/sourcesmodel.cpp index da7a015a5..6ed71bf76 100644 --- a/src/sourcetree/sourcesmodel.cpp +++ b/src/sourcetree/sourcesmodel.cpp @@ -52,7 +52,14 @@ SourcesModel::flags( const QModelIndex& index ) const Qt::ItemFlags defaultFlags = QStandardItemModel::flags( index ); if ( index.isValid() ) + { + QModelIndex idx = index.model()->index( index.row(), 0, index.parent() ); + int type = idx.data( Qt::UserRole + 1 ).toInt(); + if ( type == 1 ) + defaultFlags |= Qt::ItemIsEditable; + return Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | defaultFlags; + } else return defaultFlags; } @@ -198,3 +205,30 @@ SourcesModel::indexToTreeItem( const QModelIndex& index ) return 0; } + + +bool +SourcesModel::setData( const QModelIndex& index, const QVariant& value, int role ) +{ + qDebug() << Q_FUNC_INFO; + + if ( !index.isValid() ) + return false; + + QModelIndex idx = index.model()->index( index.row(), 0, index.parent() ); + int type = idx.data( Qt::UserRole + 1 ).toInt(); + if ( type == 1 ) + { + qlonglong pptr = idx.data( Qt::UserRole + 3 ).toLongLong(); + playlist_ptr* playlist = reinterpret_cast(pptr); + if ( playlist ) + { + playlist->data()->rename( value.toString() ); + QStandardItemModel::setData( index, value, Qt::DisplayRole ); + } + + return true; + } + + return false; +} diff --git a/src/sourcetree/sourcesmodel.h b/src/sourcetree/sourcesmodel.h index c53f40b85..cd5e0cab7 100644 --- a/src/sourcetree/sourcesmodel.h +++ b/src/sourcetree/sourcesmodel.h @@ -29,6 +29,9 @@ public: signals: void clicked( const QModelIndex& ); +protected: + bool setData( const QModelIndex& index, const QVariant& value, int role = Qt::EditRole ); + private slots: void onSourceAdded( const Tomahawk::source_ptr& source ); void onSourceRemoved( const Tomahawk::source_ptr& source ); diff --git a/src/sourcetree/sourcetreedelegate.cpp b/src/sourcetree/sourcetreedelegate.cpp new file mode 100644 index 000000000..e6fae45c6 --- /dev/null +++ b/src/sourcetree/sourcetreedelegate.cpp @@ -0,0 +1,52 @@ +#include "sourcetreedelegate.h" + +#include +#include + + +SourceTreeDelegate::SourceTreeDelegate( QAbstractItemView* parent ) + : QStyledItemDelegate( (QObject*)parent ) + , m_view( parent ) +{ +} + + +QWidget* +SourceTreeDelegate::createEditor( QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index ) const +{ + QLineEdit* editor = new QLineEdit( parent ); + editor->setFrame( false ); + editor->setObjectName( "playlistEditor" ); + + return editor; +} + + +void +SourceTreeDelegate::updateEditorGeometry( QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index ) const +{ + if ( editor->objectName() != "playlistEditor" ) + return; + + QRect r = option.rect; + r.adjust( 20, -1, -8, 1 ); + + editor->setGeometry( r ); +} + + +void +SourceTreeDelegate::setModelData( QWidget* editor, QAbstractItemModel* model, const QModelIndex& index ) const +{ + QLineEdit* le = static_cast( editor ); + + model->setData( index, le->text(), Qt::EditRole ); +} + + +QSize +SourceTreeDelegate::sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const +{ + QSize size = QStyledItemDelegate::sizeHint( option, index ); + return size; +} diff --git a/src/sourcetree/sourcetreedelegate.h b/src/sourcetree/sourcetreedelegate.h new file mode 100644 index 000000000..0166f2cb3 --- /dev/null +++ b/src/sourcetree/sourcetreedelegate.h @@ -0,0 +1,25 @@ +#ifndef SOURCETREEDELEGATE_H +#define SOURCETREEDELEGATE_H + +#include +#include + +class SourceTreeDelegate : public QStyledItemDelegate +{ +Q_OBJECT + +public: + SourceTreeDelegate( QAbstractItemView* parent = 0 ); + +protected: + QSize sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const; + + QWidget* createEditor( QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index ) const; + void updateEditorGeometry( QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index ) const; + void setModelData( QWidget* editor, QAbstractItemModel* model, const QModelIndex& index ) const; + +private: + QAbstractItemView* m_view; +}; + +#endif // SOURCETREEDELEGATE_H diff --git a/src/sourcetree/sourcetreeview.cpp b/src/sourcetree/sourcetreeview.cpp index 8d331f418..16af2a4da 100644 --- a/src/sourcetree/sourcetreeview.cpp +++ b/src/sourcetree/sourcetreeview.cpp @@ -6,6 +6,7 @@ #include "playlistmanager.h" #include "sourcetreeitem.h" #include "sourcesmodel.h" +#include "sourcetreedelegate.h" #include #include @@ -29,11 +30,15 @@ SourceTreeView::SourceTreeView( QWidget* parent ) setDragDropMode( QAbstractItemView::DropOnly ); setAcceptDrops( true ); setDropIndicatorShown( false ); - setAllColumnsShowFocus( false ); + setAllColumnsShowFocus( true ); + setUniformRowHeights( false ); setContextMenuPolicy( Qt::CustomContextMenu ); connect( this, SIGNAL( customContextMenuRequested( const QPoint& ) ), SLOT( onCustomContextMenu( const QPoint& ) ) ); + m_delegate = new SourceTreeDelegate( this ); + setItemDelegate( m_delegate ); + m_model = new SourcesModel( this ); setModel( m_model ); diff --git a/src/sourcetree/sourcetreeview.h b/src/sourcetree/sourcetreeview.h index f4bfd0a45..adc81663a 100644 --- a/src/sourcetree/sourcetreeview.h +++ b/src/sourcetree/sourcetreeview.h @@ -9,6 +9,7 @@ class CollectionModel; class PlaylistModel; class SourcesModel; +class SourceTreeDelegate; class SourceTreeView : public QTreeView { @@ -47,6 +48,7 @@ private: CollectionModel* m_collectionModel; SourcesModel* m_model; + SourceTreeDelegate* m_delegate; QModelIndex m_contextMenuIndex; QMenu m_playlistMenu; diff --git a/src/topbar/topbar.cpp b/src/topbar/topbar.cpp index e21514b63..cf06c18c7 100644 --- a/src/topbar/topbar.cpp +++ b/src/topbar/topbar.cpp @@ -157,7 +157,7 @@ TopBar::setNumSources( unsigned int i ) { fadeOutDude( k ); m_sources--; - } while( k-- > i ); + } while( (unsigned int)k-- > i ); m_sources = i; } From d4d14a4a961b5ba0737df894a36efb96ed64fa1d Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Wed, 27 Oct 2010 07:50:48 +0200 Subject: [PATCH 06/13] * Make miniupnp compile on OSX. --- libportfwd/third-party/miniupnpc-1.4.20100609/miniupnpc.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libportfwd/third-party/miniupnpc-1.4.20100609/miniupnpc.c b/libportfwd/third-party/miniupnpc-1.4.20100609/miniupnpc.c index 484a17e77..a0f1e893b 100644 --- a/libportfwd/third-party/miniupnpc-1.4.20100609/miniupnpc.c +++ b/libportfwd/third-party/miniupnpc-1.4.20100609/miniupnpc.c @@ -16,6 +16,10 @@ #endif #endif +#ifdef __APPLE__ +#define _DARWIN_C_SOURCE +#endif + #include #include #include From c0551612a8b8267d7d7fde5ff6bab2a0be8c7dd2 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Wed, 27 Oct 2010 08:04:57 +0200 Subject: [PATCH 07/13] * Fix DatabaseCommand_RenamePlaylist. --- src/database/databasecommand.cpp | 8 ++++++++ src/database/databasecommand_renameplaylist.cpp | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/database/databasecommand.cpp b/src/database/databasecommand.cpp index f4cdfa658..c88dc7dde 100644 --- a/src/database/databasecommand.cpp +++ b/src/database/databasecommand.cpp @@ -5,6 +5,7 @@ #include "databasecommand_addfiles.h" #include "databasecommand_createplaylist.h" #include "databasecommand_deleteplaylist.h" +#include "databasecommand_renameplaylist.h" #include "databasecommand_setplaylistrevision.h" @@ -69,6 +70,13 @@ DatabaseCommand::factory( const QVariant& op, const source_ptr& source ) QJson::QObjectHelper::qvariant2qobject( op.toMap(), cmd ); return cmd; } + else if( name == "renameplaylist" ) + { + DatabaseCommand_RenamePlaylist * cmd = new DatabaseCommand_RenamePlaylist; + cmd->setSource( source ); + QJson::QObjectHelper::qvariant2qobject( op.toMap(), cmd ); + return cmd; + } else if( name == "setplaylistrevision" ) { DatabaseCommand_SetPlaylistRevision * cmd = new DatabaseCommand_SetPlaylistRevision; diff --git a/src/database/databasecommand_renameplaylist.cpp b/src/database/databasecommand_renameplaylist.cpp index 4f9462943..f5e52d96f 100644 --- a/src/database/databasecommand_renameplaylist.cpp +++ b/src/database/databasecommand_renameplaylist.cpp @@ -27,7 +27,7 @@ DatabaseCommand_RenamePlaylist::exec( DatabaseImpl* lib ) cre.prepare( sql ); cre.bindValue( ":id", m_playlistguid ); - cre.bindValue( ":title", m_playlistguid ); + cre.bindValue( ":title", m_playlistTitle ); bool ok = cre.exec(); if( !ok ) From 8e110af480987d7c8619305e0f0b67935aeb809f Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Wed, 27 Oct 2010 08:21:37 +0200 Subject: [PATCH 08/13] * Protect remote playlists from being renamed. --- src/sourcetree/sourcesmodel.cpp | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/src/sourcetree/sourcesmodel.cpp b/src/sourcetree/sourcesmodel.cpp index 6ed71bf76..521bf0323 100644 --- a/src/sourcetree/sourcesmodel.cpp +++ b/src/sourcetree/sourcesmodel.cpp @@ -53,10 +53,12 @@ SourcesModel::flags( const QModelIndex& index ) const if ( index.isValid() ) { - QModelIndex idx = index.model()->index( index.row(), 0, index.parent() ); - int type = idx.data( Qt::UserRole + 1 ).toInt(); - if ( type == 1 ) - defaultFlags |= Qt::ItemIsEditable; + if ( indexType( index ) == 1 ) + { + playlist_ptr playlist = indexToPlaylist( index ); + if ( !playlist.isNull() && playlist->author()->isLocal() ) + defaultFlags |= Qt::ItemIsEditable; + } return Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | defaultFlags; } @@ -173,10 +175,9 @@ SourcesModel::indexToPlaylist( const QModelIndex& index ) if ( !index.isValid() ) return res; - QModelIndex idx = index.model()->index( index.row(), 0, index.parent() ); - int type = idx.data( Qt::UserRole + 1 ).toInt(); - if ( type == 1 ) + if ( indexType( index ) == 1 ) { + QModelIndex idx = index.model()->index( index.row(), 0, index.parent() ); qlonglong pptr = idx.data( Qt::UserRole + 3 ).toLongLong(); playlist_ptr* playlist = reinterpret_cast(pptr); if ( playlist ) @@ -193,10 +194,10 @@ SourcesModel::indexToTreeItem( const QModelIndex& index ) if ( !index.isValid() ) return 0; - QModelIndex idx = index.model()->index( index.row(), 0, index.parent() ); - int type = idx.data( Qt::UserRole + 1 ).toInt(); + int type = indexType( index ); if ( type == 0 || type == 1 ) { + QModelIndex idx = index.model()->index( index.row(), 0, index.parent() ); qlonglong pptr = idx.data( Qt::UserRole + 2 ).toLongLong(); SourceTreeItem* item = reinterpret_cast(pptr); if ( item ) @@ -215,15 +216,12 @@ SourcesModel::setData( const QModelIndex& index, const QVariant& value, int role if ( !index.isValid() ) return false; - QModelIndex idx = index.model()->index( index.row(), 0, index.parent() ); - int type = idx.data( Qt::UserRole + 1 ).toInt(); - if ( type == 1 ) + if ( indexType( index ) == 1 ) { - qlonglong pptr = idx.data( Qt::UserRole + 3 ).toLongLong(); - playlist_ptr* playlist = reinterpret_cast(pptr); - if ( playlist ) + playlist_ptr playlist = indexToPlaylist( index ); + if ( !playlist.isNull() ) { - playlist->data()->rename( value.toString() ); + playlist->rename( value.toString() ); QStandardItemModel::setData( index, value, Qt::DisplayRole ); } From fc986529ced7c84249dca8a64592b5e938653c7a Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Wed, 27 Oct 2010 09:18:26 +0200 Subject: [PATCH 09/13] * No need for our own SourceTreeView ItemDelegate. --- src/CMakeLists.txt | 2 - src/sourcetree/sourcesmodel.cpp | 12 ++++++ src/sourcetree/sourcesmodel.h | 1 + src/sourcetree/sourcetreedelegate.cpp | 52 -------------------------- src/sourcetree/sourcetreedelegate.h | 25 ------------- src/sourcetree/sourcetreeitemwidget.ui | 4 +- src/sourcetree/sourcetreeview.cpp | 4 -- src/sourcetree/sourcetreeview.h | 2 - 8 files changed, 15 insertions(+), 87 deletions(-) delete mode 100644 src/sourcetree/sourcetreedelegate.cpp delete mode 100644 src/sourcetree/sourcetreedelegate.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ed62920c5..5f6e7904e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -114,7 +114,6 @@ SET( tomahawkSourcesGui ${tomahawkSourcesGui} sourcetree/sourcetreeitem.cpp sourcetree/sourcetreeitemwidget.cpp sourcetree/sourcetreeview.cpp - sourcetree/sourcetreedelegate.cpp topbar/topbar.cpp topbar/clearbutton.cpp @@ -231,7 +230,6 @@ SET( tomahawkHeadersGui ${tomahawkHeadersGui} sourcetree/sourcetreeitem.h sourcetree/sourcetreeitemwidget.h sourcetree/sourcetreeview.h - sourcetree/sourcetreedelegate.h topbar/topbar.h topbar/clearbutton.h diff --git a/src/sourcetree/sourcesmodel.cpp b/src/sourcetree/sourcesmodel.cpp index 521bf0323..6ff6be8fe 100644 --- a/src/sourcetree/sourcesmodel.cpp +++ b/src/sourcetree/sourcesmodel.cpp @@ -67,6 +67,18 @@ SourcesModel::flags( const QModelIndex& index ) const } +QVariant +SourcesModel::data( const QModelIndex& index, int role ) const +{ + if ( role == Qt::SizeHintRole ) + { + return QSize( 0, 18 ); + } + + return QStandardItemModel::data( index, role ); +} + + void SourcesModel::loadSources() { diff --git a/src/sourcetree/sourcesmodel.h b/src/sourcetree/sourcesmodel.h index cd5e0cab7..e39f3b11c 100644 --- a/src/sourcetree/sourcesmodel.h +++ b/src/sourcetree/sourcesmodel.h @@ -18,6 +18,7 @@ public: virtual QStringList mimeTypes() const; virtual Qt::DropActions supportedDropActions() const; virtual Qt::ItemFlags flags( const QModelIndex& index ) const; + QVariant data( const QModelIndex& index, int role ) const; bool appendItem( const Tomahawk::source_ptr& source ); bool removeItem( const Tomahawk::source_ptr& source ); diff --git a/src/sourcetree/sourcetreedelegate.cpp b/src/sourcetree/sourcetreedelegate.cpp deleted file mode 100644 index e6fae45c6..000000000 --- a/src/sourcetree/sourcetreedelegate.cpp +++ /dev/null @@ -1,52 +0,0 @@ -#include "sourcetreedelegate.h" - -#include -#include - - -SourceTreeDelegate::SourceTreeDelegate( QAbstractItemView* parent ) - : QStyledItemDelegate( (QObject*)parent ) - , m_view( parent ) -{ -} - - -QWidget* -SourceTreeDelegate::createEditor( QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index ) const -{ - QLineEdit* editor = new QLineEdit( parent ); - editor->setFrame( false ); - editor->setObjectName( "playlistEditor" ); - - return editor; -} - - -void -SourceTreeDelegate::updateEditorGeometry( QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index ) const -{ - if ( editor->objectName() != "playlistEditor" ) - return; - - QRect r = option.rect; - r.adjust( 20, -1, -8, 1 ); - - editor->setGeometry( r ); -} - - -void -SourceTreeDelegate::setModelData( QWidget* editor, QAbstractItemModel* model, const QModelIndex& index ) const -{ - QLineEdit* le = static_cast( editor ); - - model->setData( index, le->text(), Qt::EditRole ); -} - - -QSize -SourceTreeDelegate::sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const -{ - QSize size = QStyledItemDelegate::sizeHint( option, index ); - return size; -} diff --git a/src/sourcetree/sourcetreedelegate.h b/src/sourcetree/sourcetreedelegate.h deleted file mode 100644 index 0166f2cb3..000000000 --- a/src/sourcetree/sourcetreedelegate.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef SOURCETREEDELEGATE_H -#define SOURCETREEDELEGATE_H - -#include -#include - -class SourceTreeDelegate : public QStyledItemDelegate -{ -Q_OBJECT - -public: - SourceTreeDelegate( QAbstractItemView* parent = 0 ); - -protected: - QSize sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const; - - QWidget* createEditor( QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index ) const; - void updateEditorGeometry( QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index ) const; - void setModelData( QWidget* editor, QAbstractItemModel* model, const QModelIndex& index ) const; - -private: - QAbstractItemView* m_view; -}; - -#endif // SOURCETREEDELEGATE_H diff --git a/src/sourcetree/sourcetreeitemwidget.ui b/src/sourcetree/sourcetreeitemwidget.ui index 8910bcde2..0bacbbba7 100644 --- a/src/sourcetree/sourcetreeitemwidget.ui +++ b/src/sourcetree/sourcetreeitemwidget.ui @@ -6,12 +6,12 @@ 0 0 - 400 + 298 44 - + 0 0 diff --git a/src/sourcetree/sourcetreeview.cpp b/src/sourcetree/sourcetreeview.cpp index 16af2a4da..777f7becf 100644 --- a/src/sourcetree/sourcetreeview.cpp +++ b/src/sourcetree/sourcetreeview.cpp @@ -6,7 +6,6 @@ #include "playlistmanager.h" #include "sourcetreeitem.h" #include "sourcesmodel.h" -#include "sourcetreedelegate.h" #include #include @@ -36,9 +35,6 @@ SourceTreeView::SourceTreeView( QWidget* parent ) setContextMenuPolicy( Qt::CustomContextMenu ); connect( this, SIGNAL( customContextMenuRequested( const QPoint& ) ), SLOT( onCustomContextMenu( const QPoint& ) ) ); - m_delegate = new SourceTreeDelegate( this ); - setItemDelegate( m_delegate ); - m_model = new SourcesModel( this ); setModel( m_model ); diff --git a/src/sourcetree/sourcetreeview.h b/src/sourcetree/sourcetreeview.h index adc81663a..f4bfd0a45 100644 --- a/src/sourcetree/sourcetreeview.h +++ b/src/sourcetree/sourcetreeview.h @@ -9,7 +9,6 @@ class CollectionModel; class PlaylistModel; class SourcesModel; -class SourceTreeDelegate; class SourceTreeView : public QTreeView { @@ -48,7 +47,6 @@ private: CollectionModel* m_collectionModel; SourcesModel* m_model; - SourceTreeDelegate* m_delegate; QModelIndex m_contextMenuIndex; QMenu m_playlistMenu; From 30d25e7b4c41d1b80a9371363ec9aaf3b0453362 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Wed, 27 Oct 2010 10:32:45 +0200 Subject: [PATCH 10/13] * Clean up XMPPBot and make it work with Google Talk: You need to set a presence state before connecting. --- src/jabber/jabber_p.cpp | 2 +- src/tomahawkapp.cpp | 2 +- src/xmppbot/xmppbot.cpp | 46 ++++++++++++++++------------------------- src/xmppbot/xmppbot.h | 2 +- 4 files changed, 21 insertions(+), 31 deletions(-) diff --git a/src/jabber/jabber_p.cpp b/src/jabber/jabber_p.cpp index 7a94bc89e..67975b5e2 100644 --- a/src/jabber/jabber_p.cpp +++ b/src/jabber/jabber_p.cpp @@ -47,7 +47,7 @@ Jabber_p::Jabber_p( const QString& jid, const QString& password, const QString& } } - m_client = QSharedPointer( new gloox::Client( m_jid, password.toStdString(), port) ); + m_client = QSharedPointer( new gloox::Client( m_jid, password.toStdString(), port ) ); if( !server.isEmpty() ) m_client->setServer( server.toStdString() ); } diff --git a/src/tomahawkapp.cpp b/src/tomahawkapp.cpp index 1be3b5f5c..7e7ae1091 100644 --- a/src/tomahawkapp.cpp +++ b/src/tomahawkapp.cpp @@ -177,7 +177,6 @@ TomahawkApp::TomahawkApp( int& argc, char *argv[] ) QNetworkProxy::setApplicationProxy( *m_proxy ); m_infoSystem = new Tomahawk::InfoSystem::InfoSystem( this ); - m_xmppBot = new XMPPBot( this ); boost::function(result_ptr)> fac = boost::bind( &TomahawkApp::httpIODeviceFactory, this, _1 ); @@ -192,6 +191,7 @@ TomahawkApp::TomahawkApp( int& argc, char *argv[] ) startHTTP(); if( !arguments().contains("--nojabber") ) setupJabber(); + m_xmppBot = new XMPPBot( this ); if ( !arguments().contains( "--nozeroconf" ) ) { diff --git a/src/xmppbot/xmppbot.cpp b/src/xmppbot/xmppbot.cpp index a71f16dd1..0869b2688 100644 --- a/src/xmppbot/xmppbot.cpp +++ b/src/xmppbot/xmppbot.cpp @@ -8,6 +8,8 @@ #include #include #include +#include + #include using namespace gloox; @@ -29,15 +31,17 @@ XMPPBot::XMPPBot(QObject *parent) return; JID jid(jidstring.toStdString()); - + jid.setResource( QString( "tomahawkbot%1" ).arg( qrand() ).toStdString() ); + m_client = new XMPPBotClient(this, jid, password.toStdString(), port); if (!server.isEmpty()) m_client.data()->setServer(server.toStdString()); - + m_client.data()->registerConnectionListener(this); m_client.data()->registerSubscriptionHandler(this); m_client.data()->registerMessageHandler(this); - + m_client.data()->setPresence(Presence::Available, 1, "Tomahawkbot available"); + connect(TomahawkApp::instance()->audioEngine(), SIGNAL(started(const Tomahawk::result_ptr &)), SLOT(newTrackSlot(const Tomahawk::result_ptr &))); @@ -46,7 +50,7 @@ XMPPBot::XMPPBot(QObject *parent) SLOT(infoReturnedSlot(QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, Tomahawk::InfoSystem::InfoCustomDataHash))); connect(TomahawkApp::instance()->infoSystem(), SIGNAL(finished(QString)), SLOT(infoFinishedSlot(QString))); - + bool success = m_client.data()->gloox::Client::connect(false); if (success) m_client.data()->run(); @@ -70,7 +74,8 @@ void XMPPBot::newTrackSlot(const Tomahawk::result_ptr &track) .arg(track->artist()) .arg(track->track()) .arg(track->album()); - m_client.data()->setPresence(Presence::Chat, 1, status.toStdString()); + + m_client.data()->setPresence(Presence::Available, 1, status.toStdString()); } void XMPPBot::onConnect() @@ -83,8 +88,7 @@ void XMPPBot::onDisconnect(ConnectionError e) { qDebug() << Q_FUNC_INFO; qDebug() << "XMPPBot Disconnected"; - if (e != gloox::ConnNoError && e != gloox::ConnUserDisconnected) - qDebug() << "ERROR: in XMPPBot, disconnected"; + qDebug() << "Connection error msg:" << e; } bool XMPPBot::onTLSConnect(const gloox::CertInfo& info) @@ -125,13 +129,15 @@ void XMPPBot::handleMessage(const Message& msg, MessageSession* session) if (msg.subtype() != Message::Chat || msg.from().full().empty() || msg.to().full().empty()) return; - qDebug() << "jid from: " << QString::fromStdString(msg.from().full()) << ", jid to: " << QString::fromStdString(msg.to().full()); - QString body = QString::fromStdString(msg.body()); QString originatingJid = QString::fromStdString(msg.from().full()); QStringList tokens(body.split(QString(" and "), QString::SkipEmptyParts)); - - qDebug() << "Operating on tokens: " << tokens; + + if ( tokens.isEmpty() ) + return; + + qDebug() << "jid from:" << QString::fromStdString(msg.from().full()) << ", jid to:" << QString::fromStdString(msg.to().full()); + qDebug() << "Operating on tokens:" << tokens; if (m_currTrack.isNull() || m_currTrack->artist().isEmpty() || m_currTrack->track().isEmpty()) { @@ -357,20 +363,6 @@ XMPPBotClient::XMPPBotClient(QObject *parent, JID &jid, std::string password, in , m_timer(this) { qDebug() << Q_FUNC_INFO; - setResource(QString( "tomahawkbot%1" ).arg( qrand() ).toStdString() ); - - // the google hack, because they filter disco features they don't know. - if( server().find( "googlemail." ) != std::string::npos - || server().find( "gmail." ) != std::string::npos - || server().find( "gtalk." ) != std::string::npos ) - { - if( resource().find( "tomahawkbot" ) == std::string::npos ) - { - qDebug() << "Forcing your /resource to contain 'tomahawk' (the google workaround)"; - setResource( "tomahawkbot-tomahawkbot" ); - } - } - } XMPPBotClient::~XMPPBotClient() @@ -381,7 +373,6 @@ XMPPBotClient::~XMPPBotClient() void XMPPBotClient::run() { qDebug() << Q_FUNC_INFO; - setPresence(Presence::Chat, 1, "Hi!"); QObject::connect(&m_timer, SIGNAL(timeout()), SLOT(recvSlot())); m_timer.start(200); qDebug() << "XMPPBot running"; @@ -391,6 +382,5 @@ void XMPPBotClient::recvSlot() { gloox::ConnectionError error = recv(100); if (error != gloox::ConnNoError) - qDebug() << "ERROR: in XMPPBotClient::recvSlot"; + qDebug() << "ERROR: in XMPPBotClient::recvSlot" << error; } - diff --git a/src/xmppbot/xmppbot.h b/src/xmppbot/xmppbot.h index e438029e9..54e2e223f 100644 --- a/src/xmppbot/xmppbot.h +++ b/src/xmppbot/xmppbot.h @@ -62,7 +62,7 @@ protected: // MessageHandler virtual void handleMessage(const gloox::Message &msg, gloox::MessageSession *session = 0); - + private: QWeakPointer m_client; Tomahawk::result_ptr m_currTrack; From 21a1af7c369f3bbcd380614c7a8840c7f0ca4afe Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Wed, 27 Oct 2010 12:14:23 +0200 Subject: [PATCH 11/13] * Possible OSX shutdown crash fix. --- src/audio/rtaudiooutput.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/audio/rtaudiooutput.cpp b/src/audio/rtaudiooutput.cpp index 6d043ebbe..b750460a3 100644 --- a/src/audio/rtaudiooutput.cpp +++ b/src/audio/rtaudiooutput.cpp @@ -67,6 +67,7 @@ RTAudioOutput::RTAudioOutput() : RTAudioOutput::~RTAudioOutput() { qDebug() << Q_FUNC_INFO; + stopPlayback(); } From ce66303e133c321ff4c4c67b68a4260d51537cc5 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Wed, 27 Oct 2010 14:01:43 +0200 Subject: [PATCH 12/13] * Keep indentation, but select entire rows in SourceTreeView. --- src/sourcetree/sourcetreeview.cpp | 51 ++++++++++++++++++++++++++++++- src/sourcetree/sourcetreeview.h | 3 +- 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/src/sourcetree/sourcetreeview.cpp b/src/sourcetree/sourcetreeview.cpp index 777f7becf..82e7cfb81 100644 --- a/src/sourcetree/sourcetreeview.cpp +++ b/src/sourcetree/sourcetreeview.cpp @@ -12,10 +12,31 @@ #include #include #include +#include using namespace Tomahawk; +class SourceDelegate : public QStyledItemDelegate +{ +public: + SourceDelegate( QAbstractItemView* parent = 0 ) : QStyledItemDelegate( parent ), m_parent( parent ) {} + +protected: + void paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const; + void updateEditorGeometry( QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index ) const + { + if ( SourcesModel::indexType( index ) == 1 ) + editor->setGeometry( option.rect.adjusted( 32, 0, 0, 0 ) ); + else + QStyledItemDelegate::updateEditorGeometry( editor, option, index ); + } + +private: + QAbstractItemView* m_parent; +}; + + SourceTreeView::SourceTreeView( QWidget* parent ) : QTreeView( parent ) , m_collectionModel( new CollectionModel( this ) ) @@ -31,6 +52,9 @@ SourceTreeView::SourceTreeView( QWidget* parent ) setDropIndicatorShown( false ); setAllColumnsShowFocus( true ); setUniformRowHeights( false ); + setIndentation( 0 ); + + setItemDelegate( new SourceDelegate( this ) ); setContextMenuPolicy( Qt::CustomContextMenu ); connect( this, SIGNAL( customContextMenuRequested( const QPoint& ) ), SLOT( onCustomContextMenu( const QPoint& ) ) ); @@ -55,6 +79,7 @@ SourceTreeView::setupMenus() m_playlistMenu.clear(); m_loadPlaylistAction = m_playlistMenu.addAction( tr( "&Load Playlist" ) ); + m_renamePlaylistAction = m_playlistMenu.addAction( tr( "&Rename Playlist" ) ); m_playlistMenu.addSeparator(); m_deletePlaylistAction = m_playlistMenu.addAction( tr( "&Delete Playlist" ) ); @@ -323,7 +348,31 @@ SourceTreeView::paintEvent( QPaintEvent* event ) opt.rect = itemRect; opt.state = QStyle::State_Enabled | QStyle::State_Selected; - style()->drawPrimitive( QStyle::PE_PanelItemViewRow, &opt, &painter, this ); + style()->drawPrimitive( QStyle::PE_PanelItemViewItem, &opt, &painter, this ); } + QTreeView::paintEvent( event ); } + + +void +SourceTreeView::drawRow( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const +{ + QTreeView::drawRow( painter, option, index ); +} + + +void +SourceDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const +{ + QStyleOptionViewItem o = option; + o.rect.adjust( 12, 0, 0, 0 ); + + if ( ( option.state & QStyle::State_Enabled ) == QStyle::State_Enabled ) + { + o.state = QStyle::State_Enabled; + } + + QStyledItemDelegate::paint( painter, option, QModelIndex() ); + QStyledItemDelegate::paint( painter, o, index ); +} diff --git a/src/sourcetree/sourcetreeview.h b/src/sourcetree/sourcetreeview.h index f4bfd0a45..169f710eb 100644 --- a/src/sourcetree/sourcetreeview.h +++ b/src/sourcetree/sourcetreeview.h @@ -33,7 +33,7 @@ private slots: protected: void drawBranches( QPainter* painter, const QRect& rect, const QModelIndex& index ) const {} - void drawTree( QPainter* painter, const QRegion& region ) const {} + void drawRow( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const; virtual void paintEvent( QPaintEvent* event ); @@ -51,6 +51,7 @@ private: QMenu m_playlistMenu; QAction* m_loadPlaylistAction; + QAction* m_renamePlaylistAction; QAction* m_deletePlaylistAction; bool m_dragging; From 34999922d4ec3437614aebbbe00ca8c4d8f9ff15 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Wed, 27 Oct 2010 14:05:13 +0200 Subject: [PATCH 13/13] * Fix selecting playlists when hovering them during D&D operations. --- src/sourcetree/sourcetreeview.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sourcetree/sourcetreeview.cpp b/src/sourcetree/sourcetreeview.cpp index 82e7cfb81..f8d856df8 100644 --- a/src/sourcetree/sourcetreeview.cpp +++ b/src/sourcetree/sourcetreeview.cpp @@ -348,7 +348,7 @@ SourceTreeView::paintEvent( QPaintEvent* event ) opt.rect = itemRect; opt.state = QStyle::State_Enabled | QStyle::State_Selected; - style()->drawPrimitive( QStyle::PE_PanelItemViewItem, &opt, &painter, this ); + style()->drawPrimitive( QStyle::PE_PanelItemViewRow, &opt, &painter, this ); } QTreeView::paintEvent( event );