diff --git a/gitso/trunk/ArgsParser.py b/gitso/trunk/ArgsParser.py
index e96eca7..8e7c402 100644
--- a/gitso/trunk/ArgsParser.py
+++ b/gitso/trunk/ArgsParser.py
@@ -43,7 +43,7 @@ class ArgsParser:
self.paths['mode'] = ''
self.paths['low-colors'] = False
- if sys.platform.find('linux') != -1:
+ if re.match('(?:open|free|net)bsd|linux',sys.platform):
self.paths['main'] = os.path.join(sys.path[0], '..', 'share', 'gitso')
self.paths['copyright'] = os.path.join(sys.path[0], '..', 'share', 'doc', 'gitso', 'COPYING')
elif sys.platform == "darwin":
diff --git a/gitso/trunk/ConnectionWindow.py b/gitso/trunk/ConnectionWindow.py
index 39ba8e4..b0eba76 100644
--- a/gitso/trunk/ConnectionWindow.py
+++ b/gitso/trunk/ConnectionWindow.py
@@ -50,7 +50,7 @@ class ConnectionWindow(wx.Frame):
# Disable until 0.7 release
self.enablePMP = False
- if sys.platform.find('linux') != -1:
+ if re.match('(?:open|free|net)bsd|linux',sys.platform):
width = 165
height = 350
xval1 = 155
@@ -88,7 +88,7 @@ class ConnectionWindow(wx.Frame):
self.Bind(wx.EVT_RADIOBUTTON, self.RadioToggle, id=self.rb2.GetId())
# checkbox for natpmp
- if sys.platform == 'darwin' or sys.platform.find('linux') != -1:
+ if sys.platform == 'darwin' or re.match('(?:open|free|net)bsd|linux',sys.platform):
if self.enablePMP:
self.cb1 = wx.CheckBox(self, -1, 'Use NAT-PMP', (130, 48))
self.cb1.Enable(False)
@@ -135,7 +135,7 @@ class ConnectionWindow(wx.Frame):
menuBar.Append(fileMenu, "&File")
menuBar.Append(editMenu, "&Edit")
- if sys.platform.find('linux') != -1 or sys.platform == 'win32':
+ if re.match('(?:open|free|net)bsd|linux',sys.platform) or sys.platform == 'win32':
menuBar.Append(helpMenu, "&Help")
self.SetMenuBar(menuBar)
@@ -174,14 +174,14 @@ class ConnectionWindow(wx.Frame):
self.ToggleValue = 0
self.hostField.Enable(True)
self.cb2.Enable(False)
- if sys.platform == 'darwin' or sys.platform.find('linux') != -1:
+ if sys.platform == 'darwin' or re.match('(?:open|free|net)bsd|linux',sys.platform):
if self.enablePMP:
self.cb1.Enable(False)
else:
self.ToggleValue = 1
self.hostField.Enable(False)
self.cb2.Enable(True)
- if sys.platform == 'darwin' or sys.platform.find('linux') != -1:
+ if sys.platform == 'darwin' or re.match('(?:open|free|net)bsd|linux',sys.platform):
if self.enablePMP:
self.cb1.Enable(True)
diff --git a/gitso/trunk/GitsoThread.py b/gitso/trunk/GitsoThread.py
index 8d9eeae..0a65d7c 100755
--- a/gitso/trunk/GitsoThread.py
+++ b/gitso/trunk/GitsoThread.py
@@ -27,7 +27,7 @@ import threading, time
import os, sys, signal, os.path
import Processes
-if sys.platform == 'darwin' or sys.platform.find('linux') != -1:
+if sys.platform == 'darwin' or re.match('(?:open|free|net)bsd|linux',sys.platform):
import NATPMP
class GitsoThread(threading.Thread):
@@ -59,7 +59,7 @@ class GitsoThread(threading.Thread):
self.error = True
else:
# Give Support
- if sys.platform == 'darwin' or sys.platform.find('linux') != -1:
+ if sys.platform == 'darwin' or re.match('(?:open|free|net)bsd|linux',sys.platform):
if self.window.enablePMP:
self.window.cb1.Enable(False)
if self.window.cb1.GetValue() == True:
@@ -99,7 +99,7 @@ class GitsoThread(threading.Thread):
@author: Aaron Gerber
"""
- if sys.platform == 'darwin' or sys.platform.find('linux') != -1:
+ if sys.platform == 'darwin' or re.match('(?:open|free|net)bsd|linux',sys.platform):
if self.window.enablePMP:
if self.window.rb1.GetValue() == False: #give support
if self.window.cb1.GetValue() == True:
@@ -122,7 +122,7 @@ class GitsoThread(threading.Thread):
connection = []
listen = []
- if sys.platform == 'darwin' or sys.platform.find('linux') != -1:
+ if sys.platform == 'darwin' or re.match('(?:open|free|net)bsd|linux',sys.platform):
if self.host <> "":
connection = os.popen('LANG=C netstat -an | grep 5500 | grep ESTABLISHED').readlines()
else:
@@ -149,7 +149,7 @@ class GitsoThread(threading.Thread):
@author: Dennis Koot
"""
- if sys.platform == 'darwin' or sys.platform.find('linux') != -1:
+ if sys.platform == 'darwin' or re.match('(?:open|free|net)bsd|linux',sys.platform):
if self.window.enablePMP:
if action == 'request':
lifetime = 3600
diff --git a/gitso/trunk/NATPMP.py b/gitso/trunk/NATPMP.py
index 7012987..479272c 100644
--- a/gitso/trunk/NATPMP.py
+++ b/gitso/trunk/NATPMP.py
@@ -15,16 +15,19 @@ For more information on NAT-PMP, see the NAT-PMP draft specification:
http://files.dns-sd.org/draft-cheshire-nat-pmp.txt
Requires Python 2.3 or later.
-Tested on Python 2.3, 2.4, 2.5 against Apple AirPort Express.
+Tested on Python 2.5, 2.6 against Apple AirPort Express.
+0.2.2 - changed gateway autodetect, per github issue #1. thanks to jirib
+0.2 - changed useException to use_exception, responseDataClass to response_data_class parameters in function calls for consistency
+0.1 - repackaged via setuptools. Fixed major bug in gateway detection. Experimental gateway detection support for Windows 7. Python 2.6 testing.
0.0.1.2 - NT autodetection code. Thanks to roee shlomo for the gateway detection regex!
0.0.1.1 - Removed broken mutex code
0.0.1 - Initial release
"""
-__version__ = "0.0.1.2"
-__license__ = """Copyright (c) 2008, Yiming Liu, All rights reserved.
+__version__ = "0.2"
+__license__ = """Copyright (c) 2008-2010, Yiming Liu, All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
@@ -49,9 +52,9 @@ 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."""
-__author__ = "Yiming Liu "
+__author__ = "Yiming Liu "
-import struct, socket, select, time
+import struct, socket, select, time, platform
import sys, os, re
NATPMP_PORT = 5351
@@ -199,19 +202,18 @@ def get_gateway_addr():
It does not guarantee correct results.
This function requires the presence of
- netstat on the path on POSIX and NT. It requires ip on
- Linux.
+ netstat on the path on POSIX and NT.
"""
addr = ""
shell_command = 'netstat -rn'
if os.name == "posix":
- pattern = re.compile('default\s+([\w.:]+)\s+\w')
- if "linux" in sys.platform:
- shell_command = "ip route show"
- pattern = re.compile('default via\s+([\w.:]+)\s+\w')
+ pattern = re.compile('(?:default|0\.0\.0\.0|::/0)\s+([\w\.:]+)\s+.*UG')
elif os.name == "nt":
- pattern = re.compile(".*?Default Gateway:[ ]+(.*?)\n")
- system_out = os.popen(shell_command, 'r').read() # TODO: this could be a security issue
+ if platform.version().startswith("6.1"):
+ pattern = re.compile(".*?0.0.0.0[ ]+0.0.0.0[ ]+(.*?)[ ]+?.*?\n")
+ else:
+ pattern = re.compile(".*?Default Gateway:[ ]+(.*?)\n")
+ system_out = os.popen(shell_command, 'r').read()
if not system_out:
raise NATPMPNetworkError(NATPMP_GATEWAY_CANNOT_FIND, error_str(NATPMP_GATEWAY_CANNOT_FIND))
match = pattern.search(system_out)
@@ -243,7 +245,7 @@ def get_gateway_socket(gateway):
response_socket.connect((gateway, NATPMP_PORT))
return response_socket
-def get_public_address(gateway_ip=get_gateway_addr(), retry=9):
+def get_public_address(gateway_ip=None, retry=9):
"""A high-level function that returns the public interface IP of
the current host by querying the NAT-PMP gateway. IP is
returned as string.
@@ -255,9 +257,11 @@ def get_public_address(gateway_ip=get_gateway_addr(), retry=9):
retry - the number of times to retry the request if unsuccessful.
Defaults to 9 as per specification.
"""
+ if gateway_ip == None:
+ gateway_ip = get_gateway_addr()
addr = None
addr_request = PublicAddressRequest()
- addr_response = send_request_with_retry(gateway_ip, addr_request, responseDataClass=PublicAddressResponse, retry=retry)
+ addr_response = send_request_with_retry(gateway_ip, addr_request, response_data_class=PublicAddressResponse, retry=retry)
if addr_response.result != 0:
#sys.stderr.write("NAT-PMP error %d: %s\n" % (addr_response.result, error_str(addr_response.result)))
#sys.stderr.flush()
@@ -265,7 +269,7 @@ def get_public_address(gateway_ip=get_gateway_addr(), retry=9):
addr = addr_response.ip
return addr
-def map_tcp_port(public_port, private_port, lifetime=3600, gateway_ip=get_gateway_addr(), retry=9, useException=True):
+def map_tcp_port(public_port, private_port, lifetime=3600, gateway_ip=None, retry=9, use_exception=True):
"""A high-level wrapper to map_port() that requests a mapping
for a public TCP port on the NAT to a private TCP port on this host.
Returns the complete response on success.
@@ -279,12 +283,12 @@ def map_tcp_port(public_port, private_port, lifetime=3600, gateway_ip=get_gatewa
get_gateway_addr()
retry - the number of times to retry the request if unsuccessful.
Defaults to 9 as per specification.
- useException - throw an exception if an error result is
+ use_exception - throw an exception if an error result is
received from the gateway. Defaults to True.
"""
- return map_port(NATPMP_PROTOCOL_TCP, public_port, private_port, lifetime, gateway_ip=gateway_ip, retry=retry, useException=useException)
+ return map_port(NATPMP_PROTOCOL_TCP, public_port, private_port, lifetime, gateway_ip=gateway_ip, retry=retry, use_exception=use_exception)
-def map_udp_port(public_port, private_port, lifetime=3600, gateway_ip=get_gateway_addr(), retry=9, useException=True):
+def map_udp_port(public_port, private_port, lifetime=3600, gateway_ip=None, retry=9, use_exception=True):
"""A high-level wrapper to map_port() that requests a mapping for
a public UDP port on the NAT to a private UDP port on this host.
Returns the complete response on success.
@@ -298,12 +302,12 @@ def map_udp_port(public_port, private_port, lifetime=3600, gateway_ip=get_gatewa
get_gateway_addr()
retry - the number of times to retry the request if unsuccessful.
Defaults to 9 as per specification.
- useException - throw an exception if an error result is
+ use_exception - throw an exception if an error result is
received from the gateway. Defaults to True.
"""
- return map_port(NATPMP_PROTOCOL_UDP, public_port, private_port, lifetime, gateway_ip=gateway_ip, retry=retry, useException=useException)
+ return map_port(NATPMP_PROTOCOL_UDP, public_port, private_port, lifetime, gateway_ip=gateway_ip, retry=retry, use_exception=use_exception)
-def map_port(protocol, public_port, private_port, lifetime=3600, gateway_ip=get_gateway_addr(), retry=9, useException=True):
+def map_port(protocol, public_port, private_port, lifetime=3600, gateway_ip=None, retry=9, use_exception=True):
"""A function to map public_port to private_port of protocol.
Returns the complete response on success.
@@ -317,15 +321,17 @@ def map_port(protocol, public_port, private_port, lifetime=3600, gateway_ip=get_
get_gateway_addr()
retry - the number of times to retry the request if unsuccessful.
Defaults to 9 as per specification.
- useException - throw an exception if an error result
+ use_exception - throw an exception if an error result
is received from the gateway. Defaults to True.
"""
if protocol not in [NATPMP_PROTOCOL_UDP, NATPMP_PROTOCOL_TCP]:
raise ValueError("Must be either NATPMP_PROTOCOL_UDP or NATPMP_PROTOCOL_TCP")
+ if gateway_ip == None:
+ gateway_ip = get_gateway_addr()
response = None
port_mapping_request = PortMapRequest(protocol, private_port, public_port, lifetime)
- port_mapping_response = send_request_with_retry(gateway_ip, port_mapping_request, responseDataClass=PortMapResponse, retry=retry)
- if port_mapping_response.result != 0 and useException:
+ port_mapping_response = send_request_with_retry(gateway_ip, port_mapping_request, response_data_class=PortMapResponse, retry=retry)
+ if port_mapping_response.result != 0 and use_exception:
raise NATPMPResultError(port_mapping_response.result, error_str(port_mapping_response.result), port_mapping_response)
return port_mapping_response
@@ -342,7 +348,7 @@ def read_response(gateway_socket, timeout, responseSize=16):
data,source_addr = resp_socket.recvfrom(responseSize)
return data,source_addr
-def send_request_with_retry(gateway_ip, request, responseDataClass=None, retry=9):
+def send_request_with_retry(gateway_ip, request, response_data_class=None, retry=9):
gateway_socket = get_gateway_socket(gateway_ip)
n = 1
data = ""
@@ -354,8 +360,8 @@ def send_request_with_retry(gateway_ip, request, responseDataClass=None, retry=9
n += 1
if n >= retry and not data:
raise NATPMPUnsupportedError(NATPMP_GATEWAY_NO_SUPPORT, error_str(NATPMP_GATEWAY_NO_SUPPORT))
- if data and responseDataClass:
- data = responseDataClass(data)
+ if data and response_data_class:
+ data = response_data_class(data)
return data
diff --git a/gitso/trunk/Processes.py b/gitso/trunk/Processes.py
index 2ee9a9a..aa9aba0 100644
--- a/gitso/trunk/Processes.py
+++ b/gitso/trunk/Processes.py
@@ -35,7 +35,7 @@ class Processes:
def getSupport(self, host):
if sys.platform == 'darwin':
self.returnPID = os.spawnl(os.P_NOWAIT, '%sOSXvnc/OSXvnc-server' % self.paths['resources'], '%sOSXvnc/OSXvnc-server' % self.paths['resources'], '-connectHost', '%s' % host)
- elif sys.platform.find('linux') != -1:
+ elif re.match('(?:open|free|net)bsd|linux',sys.platform):
# We should include future versions with options for speed.
#self.returnPID = os.spawnlp(os.P_NOWAIT, 'x11vnc', 'x11vnc','-nopw','-ncache','20','-solid','black','-connect','%s' % host)
@@ -59,7 +59,7 @@ class Processes:
if sys.platform == 'darwin':
vncviewer = '%scotvnc.app/Contents/MacOS/cotvnc' % self.paths['resources']
self.returnPID = os.spawnlp(os.P_NOWAIT, vncviewer, vncviewer, '--listen')
- elif sys.platform.find('linux') != -1:
+ elif re.match('(?:open|free|net)bsd|linux',sys.platform):
# These are the options for low-res connections.
# In the future, I'd like to support cross-platform low-res options.
@@ -93,11 +93,11 @@ class Processes:
handle = win32api.OpenProcess(PROCESS_TERMINATE, False, self.returnPID.pid)
win32api.TerminateProcess(handle, -1)
win32api.CloseHandle(handle)
- elif sys.platform.find('linux') != -1:
+ elif re.match('(?:open|free|net)bsd|linux',sys.platform):
# New processes are created when you made connections. So if you kill self.returnPID,
# you're just killing the dispatch process, not the one actually doing business...
- os.spawnlp(os.P_NOWAIT, 'killall', 'killall', 'vncviewer')
- os.spawnlp(os.P_NOWAIT, 'killall', 'killall', 'x11vnc')
+ os.spawnlp(os.P_NOWAIT, 'pkill', 'pkill', '-f', 'vncviewer')
+ os.spawnlp(os.P_NOWAIT, 'pkill', 'pkill', '-f', 'x11vnc')
else:
os.kill(self.returnPID, signal.SIGKILL)
self.returnPID = 0