#!/usr/bin/python
+# tinc-gui -- GUI for controlling a running tincd
+# Copyright (C) 2009-2012 Guus Sliepen <guus@tinc-vpn.org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
import string
import socket
import wx
import sys
+import os
+import platform
from wx.lib.mixins.listctrl import ColumnSorterMixin
from wx.lib.mixins.listctrl import ListCtrlAutoWidthMixin
+if platform.system == 'Windows':
+ import _winreg
+
# Classes to interface with a running tinc daemon
REQ_STOP = 0
CONTROL = 18
class Node:
- def __init__(self):
- print('New node')
-
- def __exit__(self):
- print('Deleting node ' + self.name)
-
def parse(self, args):
self.name = args[0]
self.address = args[2]
class VPN:
confdir = '/etc/tinc'
- cookiedir = '/var/run/'
+ piddir = '/var/run/'
def connect(self):
- f = open(self.cookiefile)
- cookie = string.split(f.readline())
+ f = open(self.pidfile)
+ info = string.split(f.readline())
f.close()
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- s.connect(('127.0.0.1', int(cookie[1])))
+ s.connect((info[2], int(info[4])))
self.sf = s.makefile()
s.close()
hello = string.split(self.sf.readline())
self.name = hello[1]
- self.sf.write('0 ^' + cookie[0] + ' 17\r\n')
+ self.sf.write('0 ^' + info[1] + ' 17\r\n')
self.sf.flush()
resp = string.split(self.sf.readline())
- self.port = cookie[1]
+ self.port = info[4]
self.nodes = {}
self.edges = {}
self.subnets = {}
resp = string.split(self.sf.readline())
return int(resp[2])
- def __init__(self, netname = None, controlcookie = None):
- self.tincconf = VPN.confdir + '/'
+ def __init__(self, netname = None, pidfile = None):
+ if platform.system == 'Windows':
+ try:
+ reg = _winreg.ConnectRegistry(None, HKEY_LOCAL_MACHINE)
+ key = _winreg.OpenKey(reg, "SOFTWARE\\tinc")
+ VPN.confdir = _winreg.QueryValue(key, None)
+ except WindowsError:
+ pass
if netname:
self.netname = netname
- self.tincconf += netname + '/'
+ self.confbase = os.path.join(VPN.confdir, netname)
+ else:
+ self.confbase = VPN.confdir
- self.tincconf += 'tinc.conf'
+ self.tincconf = os.path.join(self.confbase, 'tinc.conf')
- if controlcookie is not None:
- self.cookiefile = controlcookie
+ if pidfile != None:
+ self.pidfile = pidfile
else:
- self.cookiefile = VPN.cookiedir + 'tinc.'
- if netname:
- self.cookiefile += netname + '.'
- self.cookiefile += 'cookie'
+ if platform.system == 'Windows':
+ self.pidfile = os.path.join(self.confbase, 'pid')
+ else:
+ if netname:
+ self.pidfile = os.path.join(VPN.piddir, 'tinc.' + netname + '.pid')
+ else:
+ self.pidfile = os.path.join(VPN.piddir, 'tinc.pid')
# GUI starts here
+argv0 = sys.argv[0]
del sys.argv[0]
-net = None
-controlcookie = None
-
-while len(sys.argv) >= 2:
+netname = None
+pidfile = None
+
+def usage(exitcode = 0):
+ print('Usage: ' + argv0 + ' [options]')
+ print('\nValid options are:')
+ print(' -n, --net=NETNAME Connect to net NETNAME.')
+ print(' --pidfile=FILENAME Read control cookie from FILENAME.')
+ print(' --help Display this help and exit.')
+ print('\nReport bugs to tinc@tinc-vpn.org.')
+ sys.exit(exitcode)
+
+while sys.argv:
if sys.argv[0] in ('-n', '--net'):
- net = sys.argv[1]
- elif sys.argv[0] in ('--controlcookie'):
- controlcookie = sys.argv[1]
+ del sys.argv[0]
+ netname = sys.argv[0]
+ elif sys.argv[0] in ('--pidfile'):
+ del sys.argv[0]
+ pidfile = sys.argv[0]
+ elif sys.argv[0] in ('--help'):
+ usage(0)
else:
- print('Unknown option ' + sys.argv[0])
- sys.exit(1)
+ print(argv0 + ': unrecognized option \'' + sys.argv[0] + '\'')
+ usage(1)
del sys.argv[0]
- del sys.argv[0]
-vpn = VPN(net, controlcookie)
+if netname == None:
+ netname = os.getenv("NETNAME")
+
+if netname == ".":
+ netname = None
+
+vpn = VPN(netname, pidfile)
vpn.connect()
class SuperListCtrl(wx.ListCtrl, ColumnSorterMixin, ListCtrlAutoWidthMixin):
self.Bind(wx.EVT_MENU, self.OnDisconnect, id=disconnect.GetId())
def OnDisconnect(self, event):
- print('Disconnecting ' + self.item[0])
vpn.disconnect(self.item[0])
def OnContext(self, event):
- print('Context menu!')
i = event.GetIndex()
- print(i)
self.PopupMenu(self.ContextMenu(self.list.itemDataMap[event.GetIndex()]), event.GetPosition())
def refresh(self):
class MainWindow(wx.Frame):
def OnQuit(self, event):
- self.Close(True)
+ app.ExitMainLoop()
def OnTimer(self, event):
vpn.refresh()