Merge remote-tracking branch 'mweinelt/tinc-gui' into 1.1

This commit is contained in:
Guus Sliepen 2016-01-17 23:29:23 +01:00
commit 7418e9077f

View file

@ -1,4 +1,4 @@
#!/usr/bin/env python #!/usr/bin/env python2
# tinc-gui -- GUI for controlling a running tincd # tinc-gui -- GUI for controlling a running tincd
# Copyright (C) 2009-2014 Guus Sliepen <guus@tinc-vpn.org> # Copyright (C) 2009-2014 Guus Sliepen <guus@tinc-vpn.org>
@ -20,11 +20,12 @@
import string import string
import socket import socket
import wx
import sys
import os import os
import platform import platform
import time import time
from argparse import ArgumentParser
import wx
from wx.lib.mixins.listctrl import ColumnSorterMixin from wx.lib.mixins.listctrl import ColumnSorterMixin
from wx.lib.mixins.listctrl import ListCtrlAutoWidthMixin from wx.lib.mixins.listctrl import ListCtrlAutoWidthMixin
@ -32,7 +33,6 @@ if platform.system() == 'Windows':
import _winreg import _winreg
# Classes to interface with a running tinc daemon # Classes to interface with a running tinc daemon
REQ_STOP = 0 REQ_STOP = 0
REQ_RELOAD = 1 REQ_RELOAD = 1
REQ_RESTART = 2 REQ_RESTART = 2
@ -51,65 +51,120 @@ ID = 0
ACK = 4 ACK = 4
CONTROL = 18 CONTROL = 18
class Node:
def parse(self, args): class Node(object):
def __init__(self, args):
self.name = args[0] self.name = args[0]
self.address = args[1] self.id = args[1]
self.port = args[3]
self.cipher = int(args[4]) self.address = args[2]
self.digest = int(args[5]) self.port = args[4]
self.maclength = int(args[6])
self.compression = int(args[7]) self.cipher = int(args[5])
self.options = int(args[8], 0x10) self.digest = int(args[6])
self.status = int(args[9], 0x10) self.maclength = int(args[7])
self.nexthop = args[10]
self.via = args[11] self.compression = int(args[8])
self.distance = int(args[12]) self.options = int(args[9], 0x10)
self.pmtu = int(args[13]) self.status = int(args[10], 0x10)
self.minmtu = int(args[14])
self.maxmtu = int(args[15]) self.nexthop = args[11]
self.last_state_change = float(args[16]) self.via = args[12]
self.distance = int(args[13])
self.pmtu = int(args[14])
self.minmtu = int(args[15])
self.maxmtu = int(args[16])
self.last_state_change = float(args[17])
self.subnets = {} self.subnets = {}
class Edge:
def parse(self, args): class Edge(object):
self.fr = args[0] def __init__(self, args):
self.to = args[1] self.source = args[0]
self.sink = args[1]
self.address = args[2] self.address = args[2]
self.port = args[4] self.port = args[4]
self.options = int(args[-2], 16) self.options = int(args[-2], 16)
self.weight = int(args[-1]) self.weight = int(args[-1])
class Subnet:
def parse(self, args): class Subnet(object):
def __init__(self, args):
if args[0].find('#') >= 0: if args[0].find('#') >= 0:
(address, self.weight) = args[0].split('#', 1) address, self.weight = args[0].split('#', 1)
else: else:
self.weight = 10 self.weight = 10
address = args[0] address = args[0]
if address.find('/') >= 0: if address.find('/') >= 0:
(self.address, self.prefixlen) = address.split('/', 1) self.address, self.prefixlen = address.split('/', 1)
else: else:
self.address = address self.address = address
self.prefixlen = '48' self.prefixlen = '48'
self.owner = args[1] self.owner = args[1]
class Connection:
def parse(self, args): class Connection(object):
def __init__(self, args):
self.name = args[0] self.name = args[0]
self.address = args[1] self.address = args[1]
self.port = args[3] self.port = args[3]
self.options = int(args[4], 0x10) self.options = int(args[4], 0x10)
self.socket = int(args[5]) self.socket = int(args[5])
self.status = int(args[6], 0x10) self.status = int(args[6], 0x10)
self.weight = 123
class VPN: self.weight = 'n/a'
confdir = '/etc/tinc'
piddir = '/var/run/'
class VPN(object):
def __init__(self, netname=None, pidfile=None, confdir='/etc/tinc', piddir='/run'):
if platform.system() == 'Windows':
sam = _winreg.KEY_READ
if platform.machine().endswith('64'):
sam = sam | _winreg.KEY_WOW64_64KEY
try:
reg = _winreg.ConnectRegistry(None, _winreg.HKEY_LOCAL_MACHINE)
try:
key = _winreg.OpenKey(reg, "SOFTWARE\\tinc", 0, sam)
except WindowsError:
key = _winreg.OpenKey(reg, "SOFTWARE\\Wow6432Node\\tinc", 0, sam)
confdir = _winreg.QueryValue(key, None)
except WindowsError:
pass
if netname:
self.netname = netname
self.confbase = os.path.join(confdir, netname)
else:
self.confbase = confdir
self.tincconf = os.path.join(self.confbase, 'tinc.conf')
if pidfile is not None:
self.pidfile = pidfile
else:
if platform.system() == 'Windows':
self.pidfile = os.path.join(self.confbase, 'pid')
else:
if netname:
self.pidfile = os.path.join(piddir, 'tinc.' + netname + '.pid')
else:
self.pidfile = os.path.join(piddir, 'tinc.pid')
self.sf = None
self.name = None
self.port = None
self.nodes = {}
self.edges = {}
self.subnets = {}
self.connections = {}
def connect(self): def connect(self):
# read the pidfile # read the pidfile
@ -118,10 +173,10 @@ class VPN:
f.close() f.close()
# check if there is a UNIX socket as well # check if there is a UNIX socket as well
if self.pidfile.endswith(".pid"): if self.pidfile.endswith('.pid'):
unixfile = self.pidfile.replace(".pid", ".socket"); unixfile = self.pidfile.replace('.pid', '.socket');
else: else:
unixfile = self.pidfile + ".socket"; unixfile = self.pidfile + '.socket';
if os.path.exists(unixfile): if os.path.exists(unixfile):
# use it if it exists # use it if it exists
@ -146,14 +201,11 @@ class VPN:
self.sf.flush() self.sf.flush()
resp = string.split(self.sf.readline()) resp = string.split(self.sf.readline())
self.port = info[4] self.port = info[4]
self.nodes = {}
self.edges = {}
self.subnets = {}
self.connections = {}
self.refresh() self.refresh()
def refresh(self): def refresh(self):
self.sf.write('18 3\r\n18 4\r\n18 5\r\n18 6\r\n') for request in (REQ_DUMP_NODES, REQ_DUMP_EDGES, REQ_DUMP_SUBNETS, REQ_DUMP_CONNECTIONS):
self.sf.write('{} {}\r\n'.format(CONTROL, request))
self.sf.flush() self.sf.flush()
for node in self.nodes.values(): for node in self.nodes.values():
@ -174,22 +226,19 @@ class VPN:
if resp[1] == '3': if resp[1] == '3':
if len(resp) < 19: if len(resp) < 19:
continue continue
node = self.nodes.get(resp[2]) or Node() node = self.nodes.get(resp[2]) or Node(resp[2:])
node.parse(resp[2:])
node.visited = True node.visited = True
self.nodes[resp[2]] = node self.nodes[resp[2]] = node
elif resp[1] == '4': elif resp[1] == '4':
if len(resp) < 9: if len(resp) < 9:
continue continue
edge = self.nodes.get((resp[2], resp[3])) or Edge() edge = self.nodes.get((resp[2], resp[3])) or Edge(resp[2:])
edge.parse(resp[2:])
edge.visited = True edge.visited = True
self.edges[(resp[2], resp[3])] = edge self.edges[(resp[2], resp[3])] = edge
elif resp[1] == '5': elif resp[1] == '5':
if len(resp) < 4: if len(resp) < 4:
continue continue
subnet = self.subnets.get((resp[2], resp[3])) or Subnet() subnet = self.subnets.get((resp[2], resp[3])) or Subnet(resp[2:])
subnet.parse(resp[2:])
subnet.visited = True subnet.visited = True
self.subnets[(resp[2], resp[3])] = subnet self.subnets[(resp[2], resp[3])] = subnet
if subnet.owner == "(broadcast)": if subnet.owner == "(broadcast)":
@ -198,8 +247,7 @@ class VPN:
elif resp[1] == '6': elif resp[1] == '6':
if len(resp) < 9: if len(resp) < 9:
break break
connection = self.connections.get((resp[2], resp[3], resp[5])) or Connection() connection = self.connections.get((resp[2], resp[3], resp[5])) or Connection(resp[2:])
connection.parse(resp[2:])
connection.visited = True connection.visited = True
self.connections[(resp[2], resp[3], resp[5])] = connection self.connections[(resp[2], resp[3], resp[5])] = connection
else: else:
@ -233,85 +281,12 @@ class VPN:
self.sf.flush() self.sf.flush()
resp = string.split(self.sf.readline()) resp = string.split(self.sf.readline())
def debug(self, level = -1): def debug(self, level=-1):
self.sf.write('18 9 ' + str(level) + '\r\n') self.sf.write('18 9 ' + str(level) + '\r\n')
self.sf.flush() self.sf.flush()
resp = string.split(self.sf.readline()) resp = string.split(self.sf.readline())
return int(resp[2]) return int(resp[2])
def __init__(self, netname = None, pidfile = None):
if platform.system() == 'Windows':
sam = _winreg.KEY_READ
if platform.machine().endswith('64'):
sam = sam | _winreg.KEY_WOW64_64KEY
try:
reg = _winreg.ConnectRegistry(None, _winreg.HKEY_LOCAL_MACHINE)
try:
key = _winreg.OpenKey(reg, "SOFTWARE\\tinc", 0, sam)
except WindowsError:
key = _winreg.OpenKey(reg, "SOFTWARE\\Wow6432Node\\tinc", 0, sam)
VPN.confdir = _winreg.QueryValue(key, None)
except WindowsError:
pass
if netname:
self.netname = netname
self.confbase = os.path.join(VPN.confdir, netname)
else:
self.confbase = VPN.confdir
self.tincconf = os.path.join(self.confbase, 'tinc.conf')
if pidfile != None:
self.pidfile = pidfile
else:
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]
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'):
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(argv0 + ': unrecognized option \'' + sys.argv[0] + '\'')
usage(1)
del sys.argv[0]
if netname == None:
netname = os.getenv("NETNAME")
if netname == ".":
netname = None
vpn = VPN(netname, pidfile)
vpn.connect()
class SuperListCtrl(wx.ListCtrl, ColumnSorterMixin, ListCtrlAutoWidthMixin): class SuperListCtrl(wx.ListCtrl, ColumnSorterMixin, ListCtrlAutoWidthMixin):
def __init__(self, parent, style): def __init__(self, parent, style):
@ -324,12 +299,12 @@ class SuperListCtrl(wx.ListCtrl, ColumnSorterMixin, ListCtrlAutoWidthMixin):
class SettingsPage(wx.Panel): class SettingsPage(wx.Panel):
def OnDebugLevel(self, event): def on_debug_level(self, event):
vpn.debug(self.debug.GetValue()) vpn.debug(self.debug.GetValue())
def __init__(self, parent, id): def __init__(self, parent, id):
wx.Panel.__init__(self, parent, id) wx.Panel.__init__(self, parent, id)
grid = wx.FlexGridSizer(cols = 2) grid = wx.FlexGridSizer(cols=2)
grid.AddGrowableCol(1, 1) grid.AddGrowableCol(1, 1)
namelabel = wx.StaticText(self, -1, 'Name:') namelabel = wx.StaticText(self, -1, 'Name:')
@ -343,18 +318,19 @@ class SettingsPage(wx.Panel):
grid.Add(self.port) grid.Add(self.port)
debuglabel = wx.StaticText(self, -1, 'Debug level:') debuglabel = wx.StaticText(self, -1, 'Debug level:')
self.debug = wx.SpinCtrl(self, min = 0, max = 5, initial = vpn.debug()) self.debug = wx.SpinCtrl(self, min=0, max=5, initial=vpn.debug())
self.debug.Bind(wx.EVT_SPINCTRL, self.OnDebugLevel) self.debug.Bind(wx.EVT_SPINCTRL, self.on_debug_level)
grid.Add(debuglabel) grid.Add(debuglabel)
grid.Add(self.debug) grid.Add(self.debug)
modelabel = wx.StaticText(self, -1, 'Mode:') modelabel = wx.StaticText(self, -1, 'Mode:')
self.mode = wx.ComboBox(self, -1, style = wx.CB_READONLY, value = 'Router', choices = ['Router', 'Switch', 'Hub']) self.mode = wx.ComboBox(self, -1, style=wx.CB_READONLY, value='Router', choices=['Router', 'Switch', 'Hub'])
grid.Add(modelabel) grid.Add(modelabel)
grid.Add(self.mode) grid.Add(self.mode)
self.SetSizer(grid) self.SetSizer(grid)
class ConnectionsPage(wx.Panel): class ConnectionsPage(wx.Panel):
def __init__(self, parent, id): def __init__(self, parent, id):
wx.Panel.__init__(self, parent, id) wx.Panel.__init__(self, parent, id)
@ -378,13 +354,13 @@ class ConnectionsPage(wx.Panel):
disconnect = wx.MenuItem(self, -1, 'Disconnect') disconnect = wx.MenuItem(self, -1, 'Disconnect')
self.AppendItem(disconnect) self.AppendItem(disconnect)
self.Bind(wx.EVT_MENU, self.OnDisconnect, id=disconnect.GetId()) self.Bind(wx.EVT_MENU, self.on_disconnect, id=disconnect.GetId())
def OnDisconnect(self, event): def on_disconnect(self, event):
vpn.disconnect(self.item[0]) vpn.disconnect(self.item[0])
def OnContext(self, event): def on_context(self, event):
i = event.GetIndex() idx = event.GetIndex()
self.PopupMenu(self.ContextMenu(self.list.itemDataMap[event.GetIndex()]), event.GetPosition()) self.PopupMenu(self.ContextMenu(self.list.itemDataMap[event.GetIndex()]), event.GetPosition())
def refresh(self): def refresh(self):
@ -401,8 +377,9 @@ class ConnectionsPage(wx.Panel):
self.list.SetStringItem(i, 2, connection.port) self.list.SetStringItem(i, 2, connection.port)
self.list.SetStringItem(i, 3, str(connection.options)) self.list.SetStringItem(i, 3, str(connection.options))
self.list.SetStringItem(i, 4, str(connection.weight)) self.list.SetStringItem(i, 4, str(connection.weight))
self.list.itemDataMap[i] = (connection.name, connection.address, connection.port, connection.options, connection.weight) self.list.itemDataMap[i] = (connection.name, connection.address, connection.port, connection.options,
self.list.Bind(wx.EVT_LIST_ITEM_RIGHT_CLICK, self.OnContext) connection.weight)
self.list.Bind(wx.EVT_LIST_ITEM_RIGHT_CLICK, self.on_context)
self.list.SetItemData(i, i) self.list.SetItemData(i, i)
i += 1 i += 1
@ -411,20 +388,21 @@ class ConnectionsPage(wx.Panel):
self.list.SortListItems(sortstate[0], sortstate[1]) self.list.SortListItems(sortstate[0], sortstate[1])
class NodesPage(wx.Panel): class NodesPage(wx.Panel):
def __init__(self, parent, id): def __init__(self, parent, id):
wx.Panel.__init__(self, parent, id) wx.Panel.__init__(self, parent, id)
self.list = SuperListCtrl(self, id) self.list = SuperListCtrl(self, id)
self.list.InsertColumn( 0, 'Name') self.list.InsertColumn(0, 'Name')
self.list.InsertColumn( 1, 'Address') self.list.InsertColumn(1, 'Address')
self.list.InsertColumn( 2, 'Port') self.list.InsertColumn(2, 'Port')
self.list.InsertColumn( 3, 'Cipher') self.list.InsertColumn(3, 'Cipher')
self.list.InsertColumn( 4, 'Digest') self.list.InsertColumn(4, 'Digest')
self.list.InsertColumn( 5, 'MACLength') self.list.InsertColumn(5, 'MACLength')
self.list.InsertColumn( 6, 'Compression') self.list.InsertColumn(6, 'Compression')
self.list.InsertColumn( 7, 'Options') self.list.InsertColumn(7, 'Options')
self.list.InsertColumn( 8, 'Status') self.list.InsertColumn(8, 'Status')
self.list.InsertColumn( 9, 'Nexthop') self.list.InsertColumn(9, 'Nexthop')
self.list.InsertColumn(10, 'Via') self.list.InsertColumn(10, 'Via')
self.list.InsertColumn(11, 'Distance') self.list.InsertColumn(11, 'Distance')
self.list.InsertColumn(12, 'PMTU') self.list.InsertColumn(12, 'PMTU')
@ -466,7 +444,9 @@ class NodesPage(wx.Panel):
else: else:
since = "never" since = "never"
self.list.SetStringItem(i, 15, since) self.list.SetStringItem(i, 15, since)
self.list.itemDataMap[i] = (node.name, node.address, node.port, node.cipher, node.digest, node.maclength, node.compression, node.options, node.status, node.nexthop, node.via, node.distance, node.pmtu, node.minmtu, node.maxmtu, since) self.list.itemDataMap[i] = (node.name, node.address, node.port, node.cipher, node.digest, node.maclength,
node.compression, node.options, node.status, node.nexthop, node.via,
node.distance, node.pmtu, node.minmtu, node.maxmtu, since)
self.list.SetItemData(i, i) self.list.SetItemData(i, i)
i += 1 i += 1
@ -475,6 +455,7 @@ class NodesPage(wx.Panel):
self.list.SortListItems(sortstate[0], sortstate[1]) self.list.SortListItems(sortstate[0], sortstate[1])
class EdgesPage(wx.Panel): class EdgesPage(wx.Panel):
def __init__(self, parent, id): def __init__(self, parent, id):
wx.Panel.__init__(self, parent, id) wx.Panel.__init__(self, parent, id)
@ -498,15 +479,15 @@ class EdgesPage(wx.Panel):
for key, edge in vpn.edges.items(): for key, edge in vpn.edges.items():
if self.list.GetItemCount() <= i: if self.list.GetItemCount() <= i:
self.list.InsertStringItem(i, edge.fr) self.list.InsertStringItem(i, edge.source)
else: else:
self.list.SetStringItem(i, 0, edge.fr) self.list.SetStringItem(i, 0, edge.source)
self.list.SetStringItem(i, 1, edge.to) self.list.SetStringItem(i, 1, edge.sink)
self.list.SetStringItem(i, 2, edge.address) self.list.SetStringItem(i, 2, edge.address)
self.list.SetStringItem(i, 3, edge.port) self.list.SetStringItem(i, 3, edge.port)
self.list.SetStringItem(i, 4, format(edge.options, "x")) self.list.SetStringItem(i, 4, format(edge.options, "x"))
self.list.SetStringItem(i, 5, str(edge.weight)) self.list.SetStringItem(i, 5, str(edge.weight))
self.list.itemDataMap[i] = (edge.fr, edge.to, edge.address, edge.port, edge.options, edge.weight) self.list.itemDataMap[i] = (edge.source, edge.sink, edge.address, edge.port, edge.options, edge.weight)
self.list.SetItemData(i, i) self.list.SetItemData(i, i)
i += 1 i += 1
@ -515,6 +496,7 @@ class EdgesPage(wx.Panel):
self.list.SortListItems(sortstate[0], sortstate[1]) self.list.SortListItems(sortstate[0], sortstate[1])
class SubnetsPage(wx.Panel): class SubnetsPage(wx.Panel):
def __init__(self, parent, id): def __init__(self, parent, id):
wx.Panel.__init__(self, parent, id) wx.Panel.__init__(self, parent, id)
@ -548,14 +530,17 @@ class SubnetsPage(wx.Panel):
self.list.SortListItems(sortstate[0], sortstate[1]) self.list.SortListItems(sortstate[0], sortstate[1])
class StatusPage(wx.Panel): class StatusPage(wx.Panel):
def __init__(self, parent, id): def __init__(self, parent, id):
wx.Panel.__init__(self, parent, id) wx.Panel.__init__(self, parent, id)
class GraphPage(wx.Window): class GraphPage(wx.Window):
def __init__(self, parent, id): def __init__(self, parent, id):
wx.Window.__init__(self, parent, id) wx.Window.__init__(self, parent, id)
class NetPage(wx.Notebook): class NetPage(wx.Notebook):
def __init__(self, parent, id): def __init__(self, parent, id):
wx.Notebook.__init__(self, parent) wx.Notebook.__init__(self, parent)
@ -568,55 +553,82 @@ class NetPage(wx.Notebook):
self.status = StatusPage(self, id) self.status = StatusPage(self, id)
self.AddPage(self.settings, 'Settings') self.AddPage(self.settings, 'Settings')
#self.AddPage(self.status, 'Status') # self.AddPage(self.status, 'Status')
self.AddPage(self.connections, 'Connections') self.AddPage(self.connections, 'Connections')
self.AddPage(self.nodes, 'Nodes') self.AddPage(self.nodes, 'Nodes')
self.AddPage(self.edges, 'Edges') self.AddPage(self.edges, 'Edges')
self.AddPage(self.subnets, 'Subnets') self.AddPage(self.subnets, 'Subnets')
#self.AddPage(self.graph, 'Graph')
# self.AddPage(self.graph, 'Graph')
class MainWindow(wx.Frame): class MainWindow(wx.Frame):
def OnQuit(self, event): def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title)
menubar = wx.MenuBar()
menu = wx.Menu()
menu.Append(1, '&Quit\tCtrl-X', 'Quit tinc GUI')
menubar.Append(menu, '&File')
# nb = wx.Notebook(self, -1)
# nb.SetPadding((0, 0))
self.np = NetPage(self, -1)
# nb.AddPage(np, 'VPN')
self.timer = wx.Timer(self, -1)
self.Bind(wx.EVT_TIMER, self.on_timer, self.timer)
self.timer.Start(1000)
self.Bind(wx.EVT_MENU, self.on_quit, id=1)
self.SetMenuBar(menubar)
self.Show()
def on_quit(self, event):
app.ExitMainLoop() app.ExitMainLoop()
def OnTimer(self, event): def on_timer(self, event):
vpn.refresh() vpn.refresh()
self.np.nodes.refresh() self.np.nodes.refresh()
self.np.subnets.refresh() self.np.subnets.refresh()
self.np.edges.refresh() self.np.edges.refresh()
self.np.connections.refresh() self.np.connections.refresh()
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title)
menubar = wx.MenuBar() def main(netname, pidfile):
file = wx.Menu() global vpn, app
file.Append(1, '&Quit\tCtrl-X', 'Quit tinc GUI')
menubar.Append(file, '&File')
#nb = wx.Notebook(self, -1) if netname is None:
#nb.SetPadding((0, 0)) netname = os.getenv('NETNAME')
self.np = NetPage(self, -1)
#nb.AddPage(np, 'VPN')
self.timer = wx.Timer(self, -1) vpn = VPN(netname, pidfile)
self.Bind(wx.EVT_TIMER, self.OnTimer, self.timer) vpn.connect()
self.timer.Start(1000)
self.Bind(wx.EVT_MENU, self.OnQuit, id=1)
self.SetMenuBar(menubar)
self.Show()
app = wx.App() app = wx.App()
mw = MainWindow(None, -1, 'Tinc GUI') mw = MainWindow(None, -1, 'Tinc GUI')
#def OnTaskBarIcon(event): """
# mw.Raise() def OnTaskBarIcon(event):
# mw.Raise()
#icon = wx.Icon("tincgui.ico", wx.BITMAP_TYPE_PNG) """
#taskbaricon = wx.TaskBarIcon()
#taskbaricon.SetIcon(icon, 'Tinc GUI')
#wx.EVT_TASKBAR_RIGHT_UP(taskbaricon, OnTaskBarIcon)
app.MainLoop() """
vpn.close() icon = wx.Icon("tincgui.ico", wx.BITMAP_TYPE_PNG)
taskbaricon = wx.TaskBarIcon()
taskbaricon.SetIcon(icon, 'Tinc GUI')
wx.EVT_TASKBAR_RIGHT_UP(taskbaricon, OnTaskBarIcon)
"""
app.MainLoop()
vpn.close()
if __name__ == '__main__':
argparser = ArgumentParser(epilog='Report bugs to tinc@tinc-vpn.org.')
argparser.add_argument('-n', '--net', metavar='NETNAME', dest='netname', help='Connect to net NETNAME')
argparser.add_argument('-p', '--pidfile', help='Path to the pid file (containing the controlcookie)')
options = argparser.parse_args()
main(options.netname, options.pidfile)