1
0
mirror of https://github.com/gryf/wicd.git synced 2026-03-13 13:15:47 +01:00

initial merge, probably doesn't work yet

This commit is contained in:
Adam Blackburn
2009-08-12 23:03:16 -05:00
46 changed files with 9046 additions and 1450 deletions

View File

@@ -1,8 +1,10 @@
#!/usr/bin/python
""" autoconnect -- Triggers an automatic connection attempt. """
#
# Copyright (C) 2007 - 2008 Adam Blackburn
# Copyright (C) 2007 - 2008 Dan O'Reilly
# Copyright (C) 2007 - 2009 Adam Blackburn
# Copyright (C) 2007 - 2009 Dan O'Reilly
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License Version 2 as
@@ -21,7 +23,6 @@ from wicd import dbusmanager
import dbus
import time
import gobject
import sys
if getattr(dbus, 'version', (0, 0, 0)) < (0, 80, 0):

View File

@@ -7,8 +7,8 @@ Manages and loads the pluggable backends for wicd.
"""
#
# Copyright (C) 2008 Adam Blackburn
# Copyright (C) 2008 Dan O'Reilly
# Copyright (C) 2008-2009 Adam Blackburn
# Copyright (C) 2008-2009 Dan O'Reilly
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License Version 2 as

View File

@@ -13,8 +13,8 @@ class WirelessInterface() -- Control a wireless network interface.
"""
#
# Copyright (C) 2008 Adam Blackburn
# Copyright (C) 2008 Dan O'Reilly
# Copyright (C) 2008-2009 Adam Blackburn
# Copyright (C) 2008-2009 Dan O'Reilly
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License Version 2 as
@@ -29,15 +29,10 @@ class WirelessInterface() -- Control a wireless network interface.
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
from wicd import misc
from wicd import wnettools
from wicd.wnettools import *
import re
import os
import os.path
from wicd.wnettools import GetDefaultGateway, GetWiredInterfaces, \
GetWirelessInterfaces, IsValidWpaSuppDriver, BaseWirelessInterface, \
BaseWiredInterface, BaseInterface
# Regular expressions for wpa_cli output
auth_patten = re.compile('.*wpa_state=(.*?)\n', wnettools.__re_mode)
NAME = "external"
UPDATE_INTERVAL = 5
DESCRIPTION = """External app (original) backend
@@ -49,15 +44,13 @@ it doesn't require any third party libraries and may be
more stable for some set ups.
"""
RALINK_DRIVER = 'ralink legacy'
def NeedsExternalCalls(*args, **kargs):
""" Return True, since this backend using iwconfig/ifconfig. """
""" Return True, since this backend uses iwconfig/ifconfig. """
return True
class Interface(wnettools.BaseInterface):
class Interface(BaseInterface):
""" Control a network interface. """
def __init__(self, iface, verbose=False):
""" Initialize the object.
@@ -67,11 +60,11 @@ class Interface(wnettools.BaseInterface):
verbose -- whether to print every command run
"""
wnettools.BaseInterface.__init__(self, iface, verbose)
BaseInterface.__init__(self, iface, verbose)
self.Check()
class WiredInterface(Interface, wnettools.BaseWiredInterface):
class WiredInterface(Interface, BaseWiredInterface):
""" Control a wired network interface. """
def __init__(self, iface, verbose=False):
""" Initialise the wired network interface class.
@@ -81,11 +74,11 @@ class WiredInterface(Interface, wnettools.BaseWiredInterface):
verbose -- print all commands
"""
wnettools.BaseWiredInterface.__init__(self, iface, verbose)
BaseWiredInterface.__init__(self, iface, verbose)
Interface.__init__(self, iface, verbose)
class WirelessInterface(Interface, wnettools.BaseWirelessInterface):
class WirelessInterface(Interface, BaseWirelessInterface):
""" Control a wireless network interface. """
def __init__(self, iface, verbose=False, wpa_driver='wext'):
""" Initialise the wireless network interface class.
@@ -95,7 +88,5 @@ class WirelessInterface(Interface, wnettools.BaseWirelessInterface):
verbose -- print all commands
"""
wnettools.BaseWirelessInterface.__init__(self, iface, verbose,
wpa_driver)
BaseWirelessInterface.__init__(self, iface, verbose, wpa_driver)
Interface.__init__(self, iface, verbose)

View File

@@ -14,8 +14,8 @@ class WirelessInterface() -- Control a wireless network interface.
"""
#
# Copyright (C) 2008 Adam Blackburn
# Copyright (C) 2008 Dan O'Reilly
# Copyright (C) 2008-2009 Adam Blackburn
# Copyright (C) 2008-2009 Dan O'Reilly
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License Version 2 as
@@ -31,13 +31,23 @@ class WirelessInterface() -- Control a wireless network interface.
#
from wicd import misc
from wicd import wnettools
from wicd import wpath
from wicd.wnettools import *
from wicd.wnettools import wep_pattern, signaldbm_pattern, neediface
from wicd.wnettools import GetDefaultGateway, GetWiredInterfaces, \
GetWirelessInterfaces, IsValidWpaSuppDriver, BaseWirelessInterface, \
BaseWiredInterface, BaseInterface, wep_pattern, signaldbm_pattern, neediface
import iwscan
import wpactrl
try:
import iwscan
IWSCAN_AVAIL = True
except ImportError:
print "WARNING: python-iwscan not found, falling back to using iwlist scan."
IWSCAN_AVAIL = False
try:
import wpactrl
WPACTRL_AVAIL = True
except ImportError:
print "WARNING: python-wpactrl not found, falling back to using wpa_cli."
WPACTRL_AVAIL = False
import re
import os
@@ -56,7 +66,7 @@ This backend uses IOCTL calls and python libraries to query
network information whenever possible. This makes it fast,
but it may not work properly on all systems.
Dependencies:
(Optional) Dependencies:
python-wpactrl (http://projects.otaku42.de/wiki/PythonWpaCtrl)
python-iwscan (http://projects.otaku42.de/browser/python-iwscan/)"""
@@ -105,7 +115,7 @@ def NeedsExternalCalls(*args, **kargs):
return False
class Interface(wnettools.BaseInterface):
class Interface(BaseInterface):
""" Control a network interface. """
def __init__(self, iface, verbose=False):
""" Initialise the object.
@@ -115,14 +125,14 @@ class Interface(wnettools.BaseInterface):
verbose -- whether to print every command run
"""
wnettools.BaseInterface.__init__(self, iface, verbose)
BaseInterface.__init__(self, iface, verbose)
self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.Check()
def CheckWirelessTools(self):
""" Check for the existence needed wireless tools """
# We don't need any external apps so just return
pass
if not WPACTRL_AVAIL:
BaseInterface.CheckWirelessTools(self)
@neediface("")
def GetIP(self, ifconfig=""):
@@ -162,7 +172,7 @@ class Interface(wnettools.BaseInterface):
return bool(flags & 1)
class WiredInterface(Interface, wnettools.BaseWiredInterface):
class WiredInterface(Interface, BaseWiredInterface):
""" Control a wired network interface. """
def __init__(self, iface, verbose=False):
""" Initialise the wired network interface class.
@@ -172,7 +182,7 @@ class WiredInterface(Interface, wnettools.BaseWiredInterface):
verbose -- print all commands
"""
wnettools.BaseWiredInterface.__init__(self, iface, verbose)
BaseWiredInterface.__init__(self, iface, verbose)
Interface.__init__(self, iface, verbose)
@neediface(False)
@@ -240,7 +250,7 @@ class WiredInterface(Interface, wnettools.BaseWiredInterface):
return bool(reg & 0x0004)
class WirelessInterface(Interface, wnettools.BaseWirelessInterface):
class WirelessInterface(Interface, BaseWirelessInterface):
""" Control a wireless network interface. """
def __init__(self, iface, verbose=False, wpa_driver='wext'):
""" Initialise the wireless network interface class.
@@ -250,10 +260,11 @@ class WirelessInterface(Interface, wnettools.BaseWirelessInterface):
verbose -- print all commands
"""
wnettools.BaseWirelessInterface.__init__(self, iface, verbose,
BaseWirelessInterface.__init__(self, iface, verbose,
wpa_driver)
Interface.__init__(self, iface, verbose)
self.scan_iface = None
self.CheckWirelessTools()
@neediface([])
def GetNetworks(self):
@@ -263,6 +274,10 @@ class WirelessInterface(Interface, wnettools.BaseWirelessInterface):
A list containing available wireless networks.
"""
if not IWSCAN_AVAIL:
# Use the slow version if python-iwscan isn't available.
return BaseWirelessInterface.GetNetworks(self)
if not self.scan_iface:
try:
self.scan_iface = iwscan.WirelessInterface(self.iface)
@@ -273,7 +288,7 @@ class WirelessInterface(Interface, wnettools.BaseWirelessInterface):
try:
results = self.scan_iface.Scan()
except iwscan.error, e:
print "ERROR: %s"
print "ERROR: %s" % e
return []
return filter(None, [self._parse_ap(cell) for cell in results])
@@ -361,9 +376,10 @@ class WirelessInterface(Interface, wnettools.BaseWirelessInterface):
False otherwise.
"""
error= "Unable to find ctrl_interface for wpa_supplicant. " + \
"Could not validate authentication."
if not WPACTRL_AVAIL:
# If we don't have python-wpactrl, use the slow version.
return BaseWirelessInterface.ValidateAuthentication(self, auth_time)
# Right now there's no way to do this for ralink drivers
if self.wpa_driver == RALINK_DRIVER:
return True
@@ -391,7 +407,6 @@ class WirelessInterface(Interface, wnettools.BaseWirelessInterface):
except ValueError:
return False
result = result
if result.endswith("COMPLETED"):
return True
elif result.endswith("DISCONNECTED"):
@@ -410,6 +425,8 @@ class WirelessInterface(Interface, wnettools.BaseWirelessInterface):
@neediface(False)
def StopWPA(self):
""" Terminates wpa_supplicant using its ctrl interface. """
if not WPACTRL_AVAIL:
return BaseWirelessInterface.StopWPA(self)
wpa = self._connect_to_wpa_ctrl_iface()
if not wpa:
return

View File

@@ -1,6 +1,6 @@
#!/usr/bin/env python
""" Wicd Configuration Manager
""" configmanager -- Wicd configuration file manager
Wrapper around ConfigParser for wicd, though it should be
reusable for other purposes as well.
@@ -8,8 +8,8 @@ reusable for other purposes as well.
"""
#
# Copyright (C) 2008 Adam Blackburn
# Copyright (C) 2008 Dan O'Reilly
# Copyright (C) 2008-2009 Adam Blackburn
# Copyright (C) 2008-2009 Dan O'Reilly
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License Version 2 as
@@ -28,6 +28,7 @@ from ConfigParser import RawConfigParser
from wicd.misc import Noneify, to_unicode
from dbus import Int32
class ConfigManager(RawConfigParser):
""" A class that can be used to manage a given configuration file. """
@@ -105,10 +106,17 @@ class ConfigManager(RawConfigParser):
# Try to intelligently handle the type of the return value.
try:
ret = int(ret)
except (ValueError, TypeError):
if not ret.startswith('0') or len(ret) == 1:
ret = int(ret)
except (ValueError, TypeError, AttributeError):
ret = Noneify(ret)
return ret
# This is a workaround for a python-dbus issue on 64-bit systems.
if isinstance(ret, (int, long)):
try:
Int32(ret)
except OverflowError:
ret = str(ret)
return to_unicode(ret)
def get(self, *args, **kargs):
""" Calls the get_option method """

View File

@@ -1,6 +1,6 @@
#!/usr/bin/env python
""" Configure the scripts for a particular network.
""" configscript -- Configure the scripts for a particular network.
Script for configuring the scripts for a network passed in as a
command line argument. This needs to run a separate process because
@@ -10,8 +10,8 @@ run as the current user.
"""
#
# Copyright (C) 2007-2008 Adam Blackburn
# Copyright (C) 2007-2008 Dan O'Reilly
# Copyright (C) 2007-2009 Adam Blackburn
# Copyright (C) 2007-2009 Dan O'Reilly
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License Version 2 as
@@ -33,16 +33,17 @@ import ConfigParser
import gtk.glade
from wicd import wpath
from wicd import misc
from wicd import translations
from wicd import dbusmanager
_ = misc.get_gettext()
_ = translations.get_gettext()
language = {}
language['configure_scripts'] = _("Configure Scripts")
language['before_script'] = _("Pre-connection Script")
language['after_script'] = _("Post-connection Script")
language['disconnect_script'] = _("Disconnection Script")
language['pre_disconnect_script'] = _("Pre-disconnection Script")
language['post_disconnect_script'] = _("Post-disconnection Script")
dbus = dbusmanager.DBusManager()
dbus.connect_to_dbus()
@@ -100,14 +101,16 @@ def get_script_info(network, network_type):
if con.has_section(network):
info["pre_entry"] = get_val(con, network, "beforescript")
info["post_entry"] = get_val(con, network, "afterscript")
info["disconnect_entry"] = get_val(con, network, "disconnectscript")
info["pre_disconnect_entry"] = get_val(con, network, "predisconnectscript")
info["post_disconnect_entry"] = get_val(con, network, "postdisconnectscript")
else:
bssid = wireless.GetWirelessProperty(int(network), "bssid")
con.read(wireless_conf)
if con.has_section(bssid):
info["pre_entry"] = get_val(con, bssid, "beforescript")
info["post_entry"] = get_val(con, bssid, "afterscript")
info["disconnect_entry"] = get_val(con, bssid, "disconnectscript")
info["pre_disconnect_entry"] = get_val(con, bssid, "predisconnectscript")
info["post_disconnect_entry"] = get_val(con, bssid, "postdisconnectscript")
return info
def write_scripts(network, network_type, script_info):
@@ -120,7 +123,8 @@ def write_scripts(network, network_type, script_info):
con.add_section(network)
con.set(network, "beforescript", script_info["pre_entry"])
con.set(network, "afterscript", script_info["post_entry"])
con.set(network, "disconnectscript", script_info["disconnect_entry"])
con.set(network, "predisconnectscript", script_info["pre_disconnect_entry"])
con.set(network, "postdisconnectscript", script_info["post_disconnect_entry"])
con.write(open(wired_conf, "w"))
wired.ReloadConfig()
wired.ReadWiredNetworkProfile(network)
@@ -132,7 +136,8 @@ def write_scripts(network, network_type, script_info):
con.add_section(bssid)
con.set(bssid, "beforescript", script_info["pre_entry"])
con.set(bssid, "afterscript", script_info["post_entry"])
con.set(bssid, "disconnectscript", script_info["disconnect_entry"])
con.set(bssid, "predisconnectscript", script_info["pre_disconnect_entry"])
con.set(bssid, "postdisconnectscript", script_info["post_disconnect_entry"])
con.write(open(wireless_conf, "w"))
wireless.ReloadConfig()
wireless.ReadWirelessNetworkProfile(int(network))
@@ -155,25 +160,30 @@ def main (argv):
dialog = wTree.get_widget("configure_script_dialog")
wTree.get_widget("pre_label").set_label(language['before_script'] + ":")
wTree.get_widget("post_label").set_label(language['after_script'] + ":")
wTree.get_widget("disconnect_label").set_label(language['disconnect_script']
wTree.get_widget("pre_disconnect_label").set_label(language['pre_disconnect_script']
+ ":")
wTree.get_widget("post_disconnect_label").set_label(language['post_disconnect_script']
+ ":")
wTree.get_widget("window1").hide()
pre_entry = wTree.get_widget("pre_entry")
post_entry = wTree.get_widget("post_entry")
disconnect_entry = wTree.get_widget("disconnect_entry")
pre_disconnect_entry = wTree.get_widget("pre_disconnect_entry")
post_disconnect_entry = wTree.get_widget("post_disconnect_entry")
pre_entry.set_text(none_to_blank(script_info.get("pre_entry")))
post_entry.set_text(none_to_blank(script_info.get("post_entry")))
disconnect_entry.set_text(none_to_blank(script_info.get("disconnect_entry")))
pre_disconnect_entry.set_text(none_to_blank(script_info.get("pre_disconnect_entry")))
post_disconnect_entry.set_text(none_to_blank(script_info.get("post_disconnect_entry")))
dialog.show_all()
result = dialog.run()
if result == 1:
script_info["pre_entry"] = blank_to_none(pre_entry.get_text())
script_info["post_entry"] = blank_to_none(post_entry.get_text())
script_info["disconnect_entry"] = blank_to_none(disconnect_entry.get_text())
script_info["pre_disconnect_entry"] = blank_to_none(pre_disconnect_entry.get_text())
script_info["post_disconnect_entry"] = blank_to_none(post_disconnect_entry.get_text())
write_scripts(network, network_type, script_info)
dialog.destroy()

View File

@@ -7,8 +7,8 @@ A module for managing wicd's dbus interfaces.
"""
#
# Copyright (C) 2008 Adam Blackburn
# Copyright (C) 2008 Dan O'Reilly
# Copyright (C) 2008-2009 Adam Blackburn
# Copyright (C) 2008-2009 Dan O'Reilly
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License Version 2 as
@@ -24,7 +24,6 @@ A module for managing wicd's dbus interfaces.
#
import dbus
from dbus import DBusException
if getattr(dbus, "version", (0, 0, 0)) < (0, 80, 0):
import dbus.glib
else:

View File

@@ -1,15 +1,14 @@
#!/usr/bin/python
""" Wicd GUI module.
""" gui -- The main wicd GUI module.
Module containg all the code (other than the tray icon) related to the
Wicd user interface.
Module containing the code for the main wicd GUI.
"""
#
# Copyright (C) 2007 Adam Blackburn
# Copyright (C) 2007 Dan O'Reilly
# Copyright (C) 2007-2009 Adam Blackburn
# Copyright (C) 2007-2009 Dan O'Reilly
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License Version 2 as
@@ -32,7 +31,6 @@ import pango
import gtk
import gtk.glade
from dbus import DBusException
from dbus import version as dbus_version
from wicd import misc
from wicd import wpath
@@ -42,7 +40,7 @@ from wicd import netentry
from wicd.misc import noneToString
from wicd.netentry import WiredNetworkEntry, WirelessNetworkEntry
from wicd.prefs import PreferencesDialog
from wicd.guiutil import error, GreyLabel, LabelEntry, SmallLabel
from wicd.guiutil import error, LabelEntry
from wicd.translations import language
if __name__ == '__main__':
@@ -58,7 +56,9 @@ def setup_dbus(force=True):
except DBusException:
if force:
print "Can't connect to the daemon, trying to start it automatically..."
misc.PromptToStartDaemon()
if not misc.PromptToStartDaemon():
print "Failed to find a graphical sudo program, cannot continue."
return False
try:
dbusmanager.connect_to_dbus()
except DBusException:
@@ -141,13 +141,16 @@ class WiredProfileChooser:
class appGui(object):
""" The main wicd GUI class. """
def __init__(self, standalone=False):
def __init__(self, standalone=False, tray=None):
""" Initializes everything needed for the GUI. """
setup_dbus()
self.tray = tray
gladefile = os.path.join(wpath.share, "wicd.glade")
self.wTree = gtk.glade.XML(gladefile)
self.window = self.wTree.get_widget("window1")
self.window.set_icon_name("wicd-client")
size = daemon.ReadWindowSize("main")
width = size[0]
height = size[1]
@@ -283,7 +286,11 @@ class appGui(object):
def disconnect_all(self, widget=None):
""" Disconnects from any active network. """
daemon.Disconnect()
def handler(*args):
gobject.idle_add(self.network_list.set_sensitive, True)
self.network_list.set_sensitive(False)
daemon.Disconnect(reply_handler=handler, error_handler=handler)
def about_dialog(self, widget, event=None):
""" Displays an about dialog. """
@@ -304,7 +311,7 @@ class appGui(object):
def settings_dialog(self, widget, event=None):
""" Displays a general settings dialog. """
if not self.pref:
self.pref = PreferencesDialog(self.wTree)
self.pref = PreferencesDialog(self, self.wTree)
else:
self.pref.load_preferences_diag()
if self.pref.run() == 1:
@@ -508,11 +515,11 @@ class appGui(object):
printLine = True # In this case we print a separator.
wirednet = WiredNetworkEntry()
self.network_list.pack_start(wirednet, False, False)
wirednet.connect_button.connect("button-press-event", self.connect,
wirednet.connect_button.connect("clicked", self.connect,
"wired", 0, wirednet)
wirednet.disconnect_button.connect("button-press-event", self.disconnect,
wirednet.disconnect_button.connect("clicked", self.disconnect,
"wired", 0, wirednet)
wirednet.advanced_button.connect("button-press-event",
wirednet.advanced_button.connect("clicked",
self.edit_advanced, "wired", 0,
wirednet)
@@ -530,13 +537,13 @@ class appGui(object):
printLine = True
tempnet = WirelessNetworkEntry(x)
self.network_list.pack_start(tempnet, False, False)
tempnet.connect_button.connect("button-press-event",
tempnet.connect_button.connect("clicked",
self.connect, "wireless", x,
tempnet)
tempnet.disconnect_button.connect("button-press-event",
tempnet.disconnect_button.connect("clicked",
self.disconnect, "wireless",
x, tempnet)
tempnet.advanced_button.connect("button-press-event",
tempnet.advanced_button.connect("clicked",
self.edit_advanced, "wireless",
x, tempnet)
else:
@@ -595,7 +602,7 @@ class appGui(object):
return True
def edit_advanced(self, widget, event, ttype, networkid, networkentry):
def edit_advanced(self, widget, ttype, networkid, networkentry):
""" Display the advanced settings dialog.
Displays the advanced settings dialog and saves any changes made.
@@ -635,7 +642,7 @@ class appGui(object):
for entry_info in encryption_info.itervalues():
if entry_info[0].entry.get_text() == "" and \
entry_info[1] == 'required':
error(self, "%s (%s)" % (language['encrypt_info_missing'],
error(self.window, "%s (%s)" % (language['encrypt_info_missing'],
entry_info[0].label.get_label())
)
return False
@@ -646,21 +653,47 @@ class appGui(object):
return False
return True
def connect(self, widget, event, nettype, networkid, networkentry):
def _wait_for_connect_thread_start(self):
self.wTree.get_widget("progressbar").pulse()
if not self._connect_thread_started:
return True
else:
misc.timeout_add(2, self.update_statusbar)
self.update_statusbar()
return False
def connect(self, widget, nettype, networkid, networkentry):
""" Initiates the connection process in the daemon. """
cancel_button = self.wTree.get_widget("cancel_button")
cancel_button.set_sensitive(True)
def handler(*args):
self._connect_thread_started = True
def setup_interface_for_connection():
cancel_button = self.wTree.get_widget("cancel_button")
cancel_button.set_sensitive(True)
self.network_list.set_sensitive(False)
if self.statusID:
gobject.idle_add(self.status_bar.remove, 1, self.statusID)
gobject.idle_add(self.set_status, language["disconnecting_active"])
gobject.idle_add(self.status_area.show_all)
self.wait_for_events()
self._connect_thread_started = False
if nettype == "wireless":
if not self.check_encryption_valid(networkid,
networkentry.advanced_dialog):
self.edit_advanced(None, None, nettype, networkid, networkentry)
self.edit_advanced(None, nettype, networkid, networkentry)
return False
wireless.ConnectWireless(networkid)
setup_interface_for_connection()
wireless.ConnectWireless(networkid, reply_handler=handler,
error_handler=handler)
elif nettype == "wired":
wired.ConnectWired()
self.update_statusbar()
setup_interface_for_connection()
wired.ConnectWired(reply_handler=handler, error_handler=handler)
def disconnect(self, widget, event, nettype, networkid, networkentry):
gobject.source_remove(self.update_cb)
misc.timeout_add(100, self._wait_for_connect_thread_start, milli=True)
def disconnect(self, widget, nettype, networkid, networkentry):
""" Disconnects from the given network.
Keyword arguments:
@@ -671,13 +704,18 @@ class appGui(object):
networkentry -- The NetworkEntry containing the disconnect button.
"""
def handler(*args):
gobject.idle_add(self.network_list.set_sensitive, True)
widget.hide()
networkentry.connect_button.show()
daemon.SetForcedDisconnect(True)
self.network_list.set_sensitive(False)
if nettype == "wired":
wired.DisconnectWired()
wired.DisconnectWired(reply_handler=handler, error_handler=handler)
else:
wireless.DisconnectWireless()
wireless.DisconnectWireless(reply_handler=handler,
error_handler=handler)
def wait_for_events(self, amt=0):
""" Wait for any pending gtk events to finish before moving on.
@@ -707,7 +745,7 @@ class appGui(object):
try:
daemon.WriteWindowSize(width, height, "main")
daemon.SetGUIOpen(False)
except dbusmanager.DBusException:
except DBusException:
pass
if self.standalone:

View File

@@ -1,7 +1,7 @@
""" guiutil - A collection of commonly used gtk/gui functions and classes. """
#
# Copyright (C) 2007 - 2008 Adam Blackburn
# Copyright (C) 2007 - 2008 Dan O'Reilly
# Copyright (C) 2007 - 2009 Adam Blackburn
# Copyright (C) 2007 - 2009 Dan O'Reilly
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License Version 2 as
@@ -17,11 +17,39 @@
#
import gtk
import os.path
import wpath
HAS_NOTIFY = True
try:
import pynotify
if not pynotify.init("Wicd"):
print 'Could not initalize pynotify'
HAS_NOTIFY = False
except ImportError:
print "Importing pynotify failed, notifications disabled."
HAS_NOTIFY = False
print "Has notifications support", HAS_NOTIFY
if wpath.no_use_notifications:
print 'Notifications disabled during setup.py configure'
def can_use_notify():
use_notify = os.path.exists(os.path.join(os.path.expanduser('~/.wicd'),
'USE_NOTIFICATIONS')
)
return use_notify and HAS_NOTIFY and not wpath.no_use_notifications
def error(parent, message, block=True):
""" Shows an error dialog. """
def delete_event(dialog, id):
dialog.destroy()
if can_use_notify() and not block:
notification = pynotify.Notification("ERROR", message, "error")
notification.show()
return
dialog = gtk.MessageDialog(parent, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR,
gtk.BUTTONS_OK)
dialog.set_markup(message)
@@ -146,5 +174,5 @@ class GreyLabel(gtk.Label):
gtk.Label.__init__(self)
def set_label(self, text):
self.set_markup("<span color=\"#666666\"><i>" + text + "</i></span>")
self.set_markup(text)
self.set_alignment(0, 0)

View File

@@ -2,7 +2,7 @@
#
# Copyright (C) 1999-2006 Keith Dart <keith@kdart.com>
# Copyright (C) 2008 Dan O'Reilly <oreilldf@gmail.com>
# Copyright (C) 2008-2009 Dan O'Reilly <oreilldf@gmail.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -25,8 +25,6 @@ import sys
import os
import time
import wicd.wpath as wpath
class SizeError(IOError):
pass

View File

@@ -1,8 +1,13 @@
""" Misc - miscellaneous functions for wicd """
""" misc - miscellaneous functions for wicd
This module contains a large variety of utility functions used
throughout wicd.
"""
#
# Copyright (C) 2007 - 2008 Adam Blackburn
# Copyright (C) 2007 - 2008 Dan O'Reilly
# Copyright (C) 2007 - 2009 Adam Blackburn
# Copyright (C) 2007 - 2009 Dan O'Reilly
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License Version 2 as
@@ -44,6 +49,7 @@ AUTO = 0
DHCLIENT = 1
DHCPCD = 2
PUMP = 3
UDHCPC = 4
# Link detection tools
ETHTOOL = 1
@@ -68,7 +74,6 @@ class WicdError(Exception):
pass
__LANG = None
def Run(cmd, include_stderr=False, return_pipe=False,
return_obj=False, return_retcode=True):
""" Run a command.
@@ -88,7 +93,6 @@ def Run(cmd, include_stderr=False, return_pipe=False,
for the command that was run.
"""
global __LANG
if not isinstance(cmd, list):
cmd = to_unicode(str(cmd))
cmd = cmd.split()
@@ -105,11 +109,9 @@ def Run(cmd, include_stderr=False, return_pipe=False,
# We need to make sure that the results of the command we run
# are in English, so we set up a temporary environment.
if not __LANG:
__LANG = get_good_lang()
tmpenv = os.environ.copy()
tmpenv["LC_ALL"] = __LANG
tmpenv["LANG"] = __LANG
tmpenv["LC_ALL"] = "C"
tmpenv["LANG"] = "C"
try:
f = Popen(cmd, shell=False, stdout=PIPE, stdin=std_in, stderr=err,
@@ -118,7 +120,6 @@ def Run(cmd, include_stderr=False, return_pipe=False,
print "Running command %s failed: %s" % (str(cmd), str(e))
return ""
if return_obj:
return f
if return_pipe:
@@ -126,14 +127,6 @@ def Run(cmd, include_stderr=False, return_pipe=False,
else:
return f.communicate()[0]
def get_good_lang():
""" Check if en_US.utf8 is an available locale, if not use C. """
output = Popen(["locale", "-a"], shell=False, stdout=PIPE).communicate()[0]
if "en_US.utf8" in output:
return "en_US.utf8"
else:
return "C"
def LaunchAndWait(cmd):
""" Launches the given program with the given arguments, then blocks.
@@ -163,6 +156,8 @@ def PromptToStartDaemon():
""" Prompt the user to start the daemon """
daemonloc = wpath.sbin + 'wicd'
sudo_prog = choose_sudo_prog()
if not sudo_prog:
return False
if "gksu" in sudo_prog or "ktsuss" in sudo_prog:
msg = '--message'
else:
@@ -171,6 +166,7 @@ def PromptToStartDaemon():
'Wicd needs to access your computer\'s network cards.',
daemonloc]
os.spawnvpe(os.P_WAIT, sudo_prog, sudo_args, os.environ)
return True
def RunRegex(regex, string):
""" runs a regex search on a string """
@@ -186,6 +182,8 @@ def WriteLine(my_file, text):
def ExecuteScripts(scripts_dir, verbose=False):
""" Execute every executable file in a given directory. """
if not os.path.exists(scripts_dir):
return
for obj in os.listdir(scripts_dir):
obj = os.path.abspath(os.path.join(scripts_dir, obj))
if os.path.isfile(obj) and os.access(obj, os.X_OK):
@@ -197,7 +195,7 @@ def ExecuteScript(script, verbose=False):
print "Executing %s" % script
ret = call("%s > /dev/null 2>&1" % script, shell=True)
if verbose:
"%s returned %s" % (script, ret)
print "%s returned %s" % (script, ret)
def ReadFile(filename):
""" read in a file and return it's contents as a string """
@@ -256,7 +254,8 @@ def ParseEncryption(network):
else:
rep_val = network.get(cur_val[0].lower())
if rep_val:
line = line.replace("$_%s" % cur_val[0], rep_val)
line = line.replace("$_%s" % cur_val[0],
str(rep_val))
config_file = ''.join([config_file, line])
else:
print "Ignoring template line: '%s'" % line
@@ -450,7 +449,7 @@ def choose_sudo_prog(prog_num=0):
paths = []
if desktop_env == "kde":
progs = ["kdesu", "kdesudo", "ktusss"]
progs = ["kdesu", "kdesudo", "ktsuss"]
else:
progs = ["gksudo", "gksu", "ktsuss"]
@@ -460,8 +459,7 @@ def choose_sudo_prog(prog_num=0):
for path in paths:
if os.path.exists(path):
return path
return None
return ""
def find_path(cmd):
""" Try to find a full path for a given file name.
@@ -497,7 +495,7 @@ def stringToNone(text):
def checkboxTextboxToggle(checkbox, textboxes):
for textbox in textboxes:
textbox.set_sensitive(checkbox.get_active())
def threaded(f):
""" A decorator that will make any function run in a new thread. """
@@ -547,4 +545,3 @@ def grouper(n, iterable, fillvalue=None):
"""
args = [iter(iterable)] * n
return izip_longest(fillvalue=fillvalue, *args)

View File

@@ -8,8 +8,8 @@ when appropriate.
"""
#
# Copyright (C) 2007 - 2008 Adam Blackburn
# Copyright (C) 2007 - 2008 Dan O'Reilly
# Copyright (C) 2007 - 2009 Adam Blackburn
# Copyright (C) 2007 - 2009 Dan O'Reilly
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License Version 2 as
@@ -26,7 +26,6 @@ when appropriate.
import gobject
import time
import sys
from dbus import DBusException
@@ -45,7 +44,7 @@ daemon = dbus_dict["daemon"]
wired = dbus_dict["wired"]
wireless = dbus_dict["wireless"]
monitor = to_time = update_callback = mainloop = None
mainloop = None
def diewithdbus(func):
def wrapper(self, *__args, **__kargs):
@@ -53,7 +52,7 @@ def diewithdbus(func):
ret = func(self, *__args, **__kargs)
self.__lost_dbus_count = 0
return ret
except dbusmanager.DBusException, e:
except DBusException, e:
print "Caught exception %s" % str(e)
if not hasattr(self, "__lost_dbus_count"):
self.__lost_dbus_count = 0
@@ -86,11 +85,42 @@ class ConnectionStatus(object):
self.iwconfig = ""
self.trigger_reconnect = False
self.__lost_dbus_count = 0
self._to_time = daemon.GetBackendUpdateInterval()
self.add_poll_callback()
bus = dbusmanager.get_bus()
bus.add_signal_receiver(self._force_update_connection_status,
"UpdateState", "org.wicd.daemon")
bus.add_signal_receiver(self._update_timeout_interval,
"SignalBackendChanged", "org.wicd.daemon")
def _update_timeout_interval(self, interval):
""" Update the callback interval when signaled by the daemon. """
self._to_time = interval
gobject.source_remove(self.update_callback)
self.add_poll_callback()
def _force_update_connection_status(self):
""" Run a connection status update on demand.
Removes the scheduled update_connection_status()
call, explicitly calls the function, and reschedules
it.
"""
gobject.source_remove(self.update_callback)
self.update_connection_status()
self.add_poll_callback()
def add_poll_callback(self):
""" Registers a polling call at a predetermined interval.
The polling interval is determined by the backend in use.
"""
self.update_callback = misc.timeout_add(self._to_time,
self.update_connection_status)
def check_for_wired_connection(self, wired_ip):
""" Checks for a wired connection.
@@ -144,15 +174,18 @@ class ConnectionStatus(object):
self.iwconfig = ''
# Reset this, just in case.
self.tried_reconnect = False
bssid = wireless.GetApBssid()
if not bssid:
return False
wifi_signal = self._get_printable_sig_strength()
if wifi_signal == 0:
wifi_signal = self._get_printable_sig_strength(always_positive=True)
if wifi_signal <= 0:
# If we have no signal, increment connection loss counter.
# If we haven't gotten any signal 4 runs in a row (12 seconds),
# try to reconnect.
self.connection_lost_counter += 1
print self.connection_lost_counter
if self.connection_lost_counter >= 4:
if self.connection_lost_counter >= 4 and daemon.GetAutoReconnect():
wireless.DisconnectWireless()
self.connection_lost_counter = 0
return False
@@ -229,19 +262,6 @@ class ConnectionStatus(object):
self.auto_reconnect(from_wireless)
return self.update_state(state)
def _force_update_connection_status(self):
""" Run a connection status update on demand.
Removes the scheduled update_connection_status()
call, explicitly calls the function, and reschedules
it.
"""
global update_callback
gobject.source_remove(update_callback)
self.update_connection_status()
add_poll_callback()
def update_state(self, state, wired_ip=None, wifi_ip=None):
""" Set the current connection state. """
# Set our connection state/info.
@@ -277,13 +297,20 @@ class ConnectionStatus(object):
self.last_state = state
return True
def _get_printable_sig_strength(self):
def _get_printable_sig_strength(self, always_positive=False):
""" Get the correct signal strength format. """
try:
if daemon.GetSignalDisplayType() == 0:
wifi_signal = int(wireless.GetCurrentSignalStrength(self.iwconfig))
else:
wifi_signal = int(wireless.GetCurrentDBMStrength(self.iwconfig))
if always_positive:
# because dBm is negative, add 99 to the signal. This way, if
# the signal drops below -99, wifi_signal will == 0, and
# an automatic reconnect will be triggered
# this is only used in check_for_wireless_connection
wifi_signal = 99 + int(wireless.GetCurrentDBMStrength(self.iwconfig))
else:
wifi_signal = int(wireless.GetCurrentDBMStrength(self.iwconfig))
except TypeError:
wifi_signal = 0
@@ -334,12 +361,6 @@ def err_handle(error):
""" Just a dummy function needed for asynchronous dbus calls. """
pass
def add_poll_callback():
global monitor, to_time, update_callback
update_callback = misc.timeout_add(to_time,
monitor.update_connection_status)
def main():
""" Starts the connection monitor.
@@ -347,11 +368,8 @@ def main():
an amount of time determined by the active backend.
"""
global monitor, to_time, mainloop
global mainloop
monitor = ConnectionStatus()
to_time = daemon.GetBackendUpdateInterval()
add_poll_callback()
mainloop = gobject.MainLoop()
mainloop.run()

View File

@@ -1,6 +1,13 @@
""" netentry -- Network entry widgets for the GUI.
This module provides GUI widgets used to represent wired and wireless
entries in the GUI's network list, as well as any settings dialogs
contained within them.
"""
#
# Copyright (C) 2007 Adam Blackburn
# Copyright (C) 2007 Dan O'Reilly
# Copyright (C) 2008-2009 Adam Blackburn
# Copyright (C) 2008-2009 Dan O'Reilly
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License Version 2 as
@@ -22,7 +29,7 @@ import misc
import wpath
import dbusmanager
from misc import noneToString, stringToNone, noneToBlankString, to_bool
from guiutil import error, SmallLabel, LabelEntry, GreyLabel, LeftAlignedLabel, string_input
from guiutil import error, LabelEntry, GreyLabel, LeftAlignedLabel, string_input
from translations import language
@@ -38,14 +45,20 @@ def setup_dbus():
wired = dbusmanager.get_interface('wired')
class AdvancedSettingsDialog(gtk.Dialog):
def __init__(self):
def __init__(self, network_name=None):
""" Build the base advanced settings dialog.
This class isn't used by itself, instead it is used as a parent for
the WiredSettingsDialog and WirelessSettingsDialog.
"""
gtk.Dialog.__init__(self, title=language['properties'],
# if no network name was passed, just use Properties as the title
if network_name:
title = '%s - %s' % (network_name, language['properties'])
else:
title = language['properties']
gtk.Dialog.__init__(self, title=title,
flags=gtk.DIALOG_MODAL, buttons=(gtk.STOCK_CANCEL,
gtk.RESPONSE_REJECT,
gtk.STOCK_OK,
@@ -229,9 +242,9 @@ class AdvancedSettingsDialog(gtk.Dialog):
class WiredSettingsDialog(AdvancedSettingsDialog):
def __init__(self, name):
""" Build the wired settings dialog. """
AdvancedSettingsDialog.__init__(self)
AdvancedSettingsDialog.__init__(self, language['wired_network'])
self.des = self.connect("destroy", self.destroy_called)
self.script_button.connect("button-press-event", self.edit_scripts)
self.script_button.connect("clicked", self.edit_scripts)
self.prof_name = name
def set_net_prop(self, option, value):
@@ -287,7 +300,7 @@ class WiredSettingsDialog(AdvancedSettingsDialog):
class WirelessSettingsDialog(AdvancedSettingsDialog):
def __init__(self, networkID):
""" Build the wireless settings dialog. """
AdvancedSettingsDialog.__init__(self)
AdvancedSettingsDialog.__init__(self, wireless.GetWirelessProperty(networkID, 'essid'))
# Set up encryption stuff
self.networkID = networkID
self.combo_encryption = gtk.combo_box_new_text()
@@ -302,7 +315,7 @@ class WirelessSettingsDialog(AdvancedSettingsDialog):
information_button = gtk.Button(stock=gtk.STOCK_INFO)
self.button_hbox.pack_start(information_button, False, False)
information_button.connect('clicked', lambda *a, **k: WirelessInformationDialog(networkID))
information_button.connect('clicked', lambda *a, **k: WirelessInformationDialog(networkID, self))
information_button.show()
# Build the encryption menu
@@ -328,7 +341,7 @@ class WirelessSettingsDialog(AdvancedSettingsDialog):
# Connect signals.
self.chkbox_encryption.connect("toggled", self.toggle_encryption)
self.combo_encryption.connect("changed", self.change_encrypt_method)
self.script_button.connect("button-press-event", self.edit_scripts)
self.script_button.connect("clicked", self.edit_scripts)
self.des = self.connect("destroy", self.destroy_called)
def destroy_called(self, *args):
@@ -398,9 +411,9 @@ class WirelessSettingsDialog(AdvancedSettingsDialog):
def save_settings(self, networkid):
# Check encryption info
encrypt_info = self.encryption_info
if self.chkbox_encryption.get_active():
print "setting encryption info..."
encrypt_info = self.encryption_info
encrypt_methods = self.encrypt_types
self.set_net_prop("enctype",
encrypt_methods[self.combo_encryption.get_active()]['type'])
@@ -424,8 +437,6 @@ class WirelessSettingsDialog(AdvancedSettingsDialog):
else:
print "no encryption specified..."
self.set_net_prop("enctype", "None")
for entry in encrypt_info.iterkeys():
self.set_net_prop(entry[0].entry, "")
AdvancedSettingsDialog.save_settings(self)
if self.chkbox_global_settings.get_active():
@@ -550,7 +561,8 @@ class WiredNetworkEntry(NetworkEntry):
self.image.show()
self.connect_button.show()
self.name_label.set_label(language['wired_network'])
self.name_label.set_use_markup(True)
self.name_label.set_label("<b>" + language['wired_network'] + "</b>")
self.is_full_gui = True
@@ -643,17 +655,16 @@ class WiredNetworkEntry(NetworkEntry):
def add_profile(self, widget):
""" Add a profile to the profile list. """
print "adding profile"
response = string_input("Enter a profile name", "The profile name " +
"will not be used by the computer. It " +
"allows you to " +
"easily distinguish between different network " +
"profiles.", "Profile name:")
"profiles.", "Profile name:").strip()
# if response is "" or None
if not response:
return
error(None, "Invalid profile name", block=True)
return False
profile_name = response
profile_list = wired.GetWiredProfileList()
@@ -751,7 +762,7 @@ class WirelessNetworkEntry(NetworkEntry):
'encryption_method'))
self.set_channel(wireless.GetWirelessProperty(networkID, 'channel'))
self.name_label.set_use_markup(True)
self.name_label.set_label("%s %s %s %s" % (self._escape(self.essid),
self.name_label.set_label("<b>%s</b> %s %s %s" % (self._escape(self.essid),
self.lbl_strength.get_label(),
self.lbl_encryption.get_label(),
self.lbl_channel.get_label(),
@@ -872,8 +883,8 @@ class WirelessNetworkEntry(NetworkEntry):
class WirelessInformationDialog(gtk.Dialog):
def __init__(self, networkID):
gtk.Dialog.__init__(self)
def __init__(self, networkID, parent):
gtk.Dialog.__init__(self,parent=parent)
# Make the combo box.
self.lbl_strength = gtk.Label()

View File

@@ -19,9 +19,9 @@ class WiredConnectThread() -- Connection thread for wired
"""
#
# Copyright (C) 2007 - 2008 Adam Blackburn
# Copyright (C) 2007 - 2008 Dan O'Reilly
# Copyright (C) 2007 - 2008 Byron Hillis
# Copyright (C) 2007 - 2009 Adam Blackburn
# Copyright (C) 2007 - 2009 Dan O'Reilly
# Copyright (C) 2007 - 2009 Byron Hillis
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License Version 2 as
@@ -116,7 +116,9 @@ def expand_script_macros(script, msg, bssid, essid):
script -- the script to execute.
msg -- the name of the script, %{script} will be expanded to this.
bssid -- the bssid of the network we connect to, defaults to 'wired'.
essid -- the essid of the network we connect to, defaults to 'wired'."""
essid -- the essid of the network we connect to, defaults to 'wired'.
"""
def repl(match):
macro = match.group(1).lower()
if macro_dict.has_key(macro):
@@ -149,10 +151,10 @@ class Controller(object):
self.connecting_thread = None
self.before_script = None
self.after_script = None
self.disconnect_script = None
self.pre_disconnect_script = None
self.post_disconnect_script = None
self.driver = None
self.iface = None
self.backend_manager = BackendManager()
def get_debug(self): return self._debug
def set_debug(self, value):
@@ -202,17 +204,23 @@ class Controller(object):
def Disconnect(self, *args, **kargs):
""" Disconnect from the network. """
iface = self.iface
misc.ExecuteScripts(wpath.disconnectscripts, self.debug)
if self.disconnect_script:
print 'Running disconnect script'
misc.ExecuteScript(expand_script_macros(self.disconnect_script,
'disconnection', *args),
misc.ExecuteScripts(wpath.predisconnectscripts, self.debug)
if self.pre_disconnect_script:
print 'Running pre-disconnect script'
misc.ExecuteScript(expand_script_macros(self.pre_disconnect_script,
'pre-disconnection', *args),
self.debug)
iface.ReleaseDHCP()
iface.SetAddress('0.0.0.0')
iface.FlushRoutes()
iface.Down()
iface.Up()
misc.ExecuteScripts(wpath.postdisconnectscripts, self.debug)
if self.post_disconnect_script:
print 'Running post-disconnect script'
misc.ExecuteScript(expand_script_macros(self.post_disconnect_script,
'post-disconnection', *args),
self.debug)
def ReleaseDHCP(self):
""" Release the DHCP lease for this interface. """
@@ -272,8 +280,8 @@ class ConnectThread(threading.Thread):
lock = threading.Lock()
def __init__(self, network, interface_name, before_script, after_script,
disconnect_script, gdns1, gdns2, gdns3, gdns_dom, gsearch_dom,
iface, debug):
pre_disconnect_script, post_disconnect_script, gdns1,
gdns2, gdns3, gdns_dom, gsearch_dom, iface, debug):
""" Initialise the required object variables and the thread.
Keyword arguments:
@@ -282,7 +290,8 @@ class ConnectThread(threading.Thread):
wired -- name of the wired interface
before_script -- script to run before bringing up the interface
after_script -- script to run after bringing up the interface
disconnect_script -- script to run after disconnection
pre_disconnect_script -- script to run before disconnection
post_disconnect_script -- script to run after disconnection
gdns1 -- global DNS server 1
gdns2 -- global DNS server 2
gdns3 -- global DNS server 3
@@ -296,7 +305,8 @@ class ConnectThread(threading.Thread):
self.connect_result = None
self.before_script = before_script
self.after_script = after_script
self.disconnect_script = disconnect_script
self.pre_disconnect_script = pre_disconnect_script
self.post_disconnect_script = post_disconnect_script
self._should_die = False
self.abort_reason = ""
self.connect_result = ""
@@ -314,6 +324,13 @@ class ConnectThread(threading.Thread):
self.SetStatus('interface_down')
def run(self):
self.connect_result = "Failed"
try:
self._connect()
finally:
self.is_connecting = False
def set_should_die(self, val):
self.lock.acquire()
try:
@@ -564,23 +581,13 @@ class Wireless(Controller):
"""
def comp(x, y):
if x.has_key('quality'):
if x['quality'] > y['quality']:
return 1
elif x['quality'] < y['quality']:
return -1
else:
return 0
if 'quality' in x:
key = 'quality'
else:
if x['strength'] < y['strength']:
return 1
elif x['strength'] > y['strength']:
return -1
else:
return 0
key = 'strength'
return cmp(x[key], y[key])
if not self.wiface: return []
wiface = self.wiface
# Prepare the interface for scanning
@@ -609,7 +616,8 @@ class Wireless(Controller):
self.connecting_thread = WirelessConnectThread(network,
self.wireless_interface, self.wpa_driver, self.before_script,
self.after_script, self.disconnect_script, self.global_dns_1,
self.after_script, self.pre_disconnect_script,
self.post_disconnect_script, self.global_dns_1,
self.global_dns_2, self.global_dns_3, self.global_dns_dom,
self.global_search_dom, self.wiface, debug)
self.connecting_thread.setDaemon(True)
@@ -711,7 +719,7 @@ class Wireless(Controller):
wiface = self.wiface
print 'Creating ad-hoc network'
print 'Stopping dhcp client and wpa_supplicant'
BACKEND.ReleaseDHCP()
wiface.ReleaseDHCP()
wiface.StopWPA()
print 'Putting wireless interface down'
wiface.Down()
@@ -771,6 +779,7 @@ class Wireless(Controller):
""" Sets the wpa_supplicant driver associated with the interface. """
self.wiface.SetWpaDriver(driver)
class WirelessConnectThread(ConnectThread):
""" A thread class to perform the connection to a wireless network.
@@ -780,8 +789,9 @@ class WirelessConnectThread(ConnectThread):
"""
def __init__(self, network, wireless, wpa_driver, before_script,
after_script, disconnect_script, gdns1, gdns2, gdns3,
gdns_dom, gsearch_dom, wiface, debug=False):
after_script, pre_disconnect_script, post_disconnect_script,
gdns1, gdns2, gdns3, gdns_dom, gsearch_dom, wiface,
debug=False):
""" Initialise the thread with network information.
Keyword arguments:
@@ -790,19 +800,21 @@ class WirelessConnectThread(ConnectThread):
wpa_driver -- type of wireless interface
before_script -- script to run before bringing up the interface
after_script -- script to run after bringing up the interface
disconnect_script -- script to run after disconnection
pre_disconnect_script -- script to run before disconnection
post_disconnect_script -- script to run after disconnection
gdns1 -- global DNS server 1
gdns2 -- global DNS server 2
gdns3 -- global DNS server 3
"""
ConnectThread.__init__(self, network, wireless, before_script,
after_script, disconnect_script, gdns1, gdns2,
after_script, pre_disconnect_script,
post_disconnect_script, gdns1, gdns2,
gdns3, gdns_dom, gsearch_dom, wiface, debug)
self.wpa_driver = wpa_driver
def run(self):
def _connect(self):
""" The main function of the connection thread.
This function performs the necessary calls to connect to the
@@ -831,17 +843,17 @@ class WirelessConnectThread(ConnectThread):
self.reset_ip_addresses(wiface)
self.stop_wpa(wiface)
self.flush_routes(wiface)
# Generate PSK and authenticate if needed.
if self.wpa_driver != 'ralink legacy':
self.generate_psk_and_authenticate(wiface)
wiface.SetMode(self.network['mode'])
# Put interface up.
self.SetStatus('configuring_interface')
self.put_iface_up(wiface)
# Generate PSK and authenticate if needed.
if self.wpa_driver != 'ralink legacy':
self.generate_psk_and_authenticate(wiface)
# Associate.
wiface.SetMode(self.network['mode'])
wiface.Associate(self.network['essid'], self.network['channel'],
self.network['bssid'])
@@ -854,7 +866,8 @@ class WirelessConnectThread(ConnectThread):
if self.network.get('enctype'):
self.SetStatus('validating_authentication')
if not wiface.ValidateAuthentication(time.time()):
if not self.connect_result:
print "connect result is %s" % self.connect_result
if not self.connect_result or self.connect_result == 'Failed':
self.abort_connection('bad_pass')
# Set up gateway, IP address, and DNS servers.
@@ -968,9 +981,10 @@ class Wired(Controller):
if not self.liface: return False
self.connecting_thread = WiredConnectThread(network,
self.wired_interface, self.before_script, self.after_script,
self.disconnect_script, self.global_dns_1, self.global_dns_2,
self.global_dns_3, self.global_dns_dom, self.global_search_dom,
self.liface, debug)
self.pre_disconnect_script, self.post_disconnect_script,
self.global_dns_1, self.global_dns_2, self.global_dns_3,
self.global_dns_dom, self.global_search_dom, self.liface,
debug)
self.connecting_thread.setDaemon(True)
self.connecting_thread.start()
return self.connecting_thread
@@ -994,8 +1008,8 @@ class WiredConnectThread(ConnectThread):
"""
def __init__(self, network, wired, before_script, after_script,
disconnect_script, gdns1, gdns2, gdns3, gdns_dom, gsearch_dom,
liface, debug=False):
pre_disconnect_script, post_disconnect_script, gdns1,
gdns2, gdns3, gdns_dom, gsearch_dom, liface, debug=False):
""" Initialise the thread with network information.
Keyword arguments:
@@ -1004,17 +1018,19 @@ class WiredConnectThread(ConnectThread):
wired -- name of the wired interface
before_script -- script to run before bringing up the interface
after_script -- script to run after bringing up the interface
disconnect_script -- script to run after disconnection
pre_disconnect_script -- script to run before disconnection
post_disconnect_script -- script to run after disconnection
gdns1 -- global DNS server 1
gdns2 -- global DNS server 2
gdns3 -- global DNS server 3
"""
ConnectThread.__init__(self, network, wired, before_script,
after_script, disconnect_script, gdns1, gdns2,
after_script, pre_disconnect_script,
post_disconnect_script, gdns1, gdns2,
gdns3, gdns_dom, gsearch_dom, liface, debug)
def run(self):
def _connect(self):
""" The main function of the connection thread.
This function performs the necessary calls to connect to the
@@ -1063,4 +1079,3 @@ class WiredConnectThread(ConnectThread):
self.connect_result = "Success"
self.is_connecting = False

View File

@@ -1,6 +1,6 @@
#!/usr/bin/python
""" Wicd Preferences Dialog.
""" prefs -- Wicd Preferences Dialog.
Displays the main settings dialog window for wicd and
handles recieving/sendings the settings from/to the daemon.
@@ -8,8 +8,8 @@ handles recieving/sendings the settings from/to the daemon.
"""
#
# Copyright (C) 2007 Adam Blackburn
# Copyright (C) 2007 Dan O'Reilly
# Copyright (C) 2008-2009 Adam Blackburn
# Copyright (C) 2008-2009 Dan O'Reilly
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License Version 2 as
@@ -26,7 +26,7 @@ handles recieving/sendings the settings from/to the daemon.
import gtk
import gobject
import pango
#import pango
import os
import gtk.glade
@@ -41,6 +41,8 @@ wired = None
from translations import language
USER_SETTINGS_DIR = os.path.expanduser('~/.wicd/')
def setup_dbus():
global daemon, wireless, wired
daemon = dbusmanager.get_interface('daemon')
@@ -49,20 +51,18 @@ def setup_dbus():
class PreferencesDialog(object):
""" Class for handling the wicd preferences dialog window. """
def __init__(self, wTree):
def __init__(self, parent, wTree):
setup_dbus()
self.parent = parent
self.wTree = wTree
self.prep_settings_diag()
self.load_preferences_diag()
def _setup_external_app_radios(self, radio_list, get_method, set_method):
""" Generic function for setting up external app radios. """
def set_available(apps):
for app in apps:
app.set_sensitive(daemon.GetAppAvailable(app.get_label()))
# Disable radios for apps that aren't installed.
set_available(radio_list[1:])
for app in radio_list[1:]:
app.set_sensitive(daemon.GetAppAvailable(app.get_label()))
selected_app = get_method()
# Make sure the app we want to select is actually available.
if radio_list[selected_app].get_property("sensitive"):
@@ -82,7 +82,7 @@ class PreferencesDialog(object):
self.preferwiredcheckbox.set_active(daemon.GetPreferWiredNetwork())
dhcp_list = [self.dhcpautoradio, self.dhclientradio, self.dhcpcdradio,
self.pumpradio]
self.pumpradio, self.udhcpcradio]
self._setup_external_app_radios(dhcp_list, daemon.GetDHCPClient,
daemon.SetDHCPClient)
@@ -100,7 +100,7 @@ class PreferencesDialog(object):
sudo_list = [self.sudoautoradio, self.gksudoradio, self.kdesuradio,
self.ktsussradio]
self._setup_external_app_radios(sudo_list, daemon.GetSudoApp,
daemon.SetAudoApp)
daemon.SetSudoApp)
auto_conn_meth = daemon.GetWiredAutoConnectMethod()
if auto_conn_meth == 1:
@@ -144,6 +144,24 @@ class PreferencesDialog(object):
self.backendcombo.set_active(self.backends.index(cur_backend))
except ValueError:
self.backendcombo.set_active(0)
self.notificationscheckbox.set_active(
os.path.exists(
os.path.join(USER_SETTINGS_DIR, 'USE_NOTIFICATIONS')
))
# if pynotify isn't installed disable the option
try:
import pynotify
except ImportError:
self.notificationscheckbox.set_active(False)
self.notificationscheckbox.set_sensitive(False)
# if notifications were disabled with the configure flag
if wpath.no_use_notifications:
self.notificationscheckbox.set_active(False)
self.notificationscheckbox.hide()
self.wTree.get_widget('label2').hide()
self.wTree.get_widget("notebook2").set_current_page(0)
@@ -192,8 +210,10 @@ class PreferencesDialog(object):
dhcp_client = misc.DHCLIENT
elif self.dhcpcdradio.get_active():
dhcp_client = misc.DHCPCD
else:
elif self.pumpradio.get_active():
dhcp_client = misc.PUMP
else:
dhcp_client = misc.UDHCPC
daemon.SetDHCPClient(dhcp_client)
if self.linkautoradio.get_active():
@@ -224,6 +244,19 @@ class PreferencesDialog(object):
[width, height] = self.dialog.get_size()
daemon.WriteWindowSize(width, height, "pref")
not_path = os.path.join(USER_SETTINGS_DIR, 'USE_NOTIFICATIONS')
if self.notificationscheckbox.get_active():
if not os.path.exists(not_path):
open(not_path, 'w')
else:
if os.path.exists(not_path):
os.remove(not_path)
# if this GUI was started by a tray icon,
# instantly change the notifications there
if self.parent.tray:
self.parent.tray.icon_info.use_notify = \
self.notificationscheckbox.get_active()
def set_label(self, glade_str, label):
""" Sets the label for the given widget in wicd.glade. """
@@ -308,11 +341,15 @@ class PreferencesDialog(object):
'use_last_used_profile')
self.notificationscheckbox = setup_label("pref_use_libnotify",
'display_notifications')
# DHCP Clients
self.dhcpautoradio = setup_label("dhcp_auto_radio", "wicd_auto_config")
self.dhclientradio = self.wTree.get_widget("dhclient_radio")
self.pumpradio = self.wTree.get_widget("pump_radio")
self.dhcpcdradio = self.wTree.get_widget("dhcpcd_radio")
self.udhcpcradio = self.wTree.get_widget("udhcpc_radio")
# Wired Link Detection Apps
self.linkautoradio = setup_label("link_auto_radio", 'wicd_auto_config')

View File

@@ -8,8 +8,8 @@ Used for when a laptop enters hibernation/suspension.
"""
#
# Copyright (C) 2007 - 2008 Adam Blackburn
# Copyright (C) 2007 - 2008 Dan O'Reilly
# Copyright (C) 2007 - 2009 Adam Blackburn
# Copyright (C) 2007 - 2009 Dan O'Reilly
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License Version 2 as

View File

@@ -1,6 +1,7 @@
#!/usr/bin/env python
# -* coding: utf-8 -*-
""" translations -- module for handling the translation strings for wicd. """
#
# Copyright (C) 2007 - 2009 Adam Blackburn
# Copyright (C) 2007 - 2009 Dan O'Reilly
@@ -43,19 +44,20 @@ def get_gettext():
lc, encoding = locale.getdefaultlocale(envvars=('LC_MESSAGES',
'LC_ALL', 'LANG',
'LANGUAGE'))
langs += [lc]
except ValueError, e:
print str(e)
print "Default locale unavailable, falling back to en_US"
if (lc):
langs += [lc]
langs += ["en_US"]
lang = gettext.translation('wicd', local_path, languages=langs,
fallback=True)
_ = lang.gettext
return _
# Generated automatically on Sun, 05 Jul 2009 13:51:18 CDT
_ = get_gettext()
language = {}
<<<<<<< TREE
language['connect'] = _('Connect')
language['ip'] = _('IP')
language['netmask'] = _('Netmask')
@@ -234,3 +236,165 @@ language['ok'] = _('OK')
language['cancel'] = _('Cancel')
=======
language['resetting_ip_address'] = _('''Resetting IP address...''')
language['prefs_help'] = _('''Preferences dialog''')
language['no_dhcp_offers'] = _('''Connection Failed: No DHCP offers received.''')
language['more_help'] = _('''For more detailed help, consult the wicd-curses(8) man page.''')
language['bad_pass'] = _('''Connection Failed: Bad password''')
language['cannot_start_daemon'] = _('''Unable to connect to wicd daemon DBus interface. This typically means there was a problem starting the daemon. Check the wicd log for more information.''')
language['verifying_association'] = _('''Verifying access point association...''')
language['wired_always_on'] = _('''Always show wired interface''')
language['could_not_connect'] = _('''Could not connect to wicd's D-Bus interface. Check the wicd log for error messages.''')
language['path_to_pac_file'] = _('''Path to PAC File''')
language['always_switch_to_wired'] = _('''Always switch to wired connection when available''')
language['disconn_help'] = _('''Disconnect from all networks''')
language['wired_networks'] = _('''Wired Networks''')
language['backend_alert'] = _('''Changes to your backend won't occur until the daemon is restarted.''')
language['about_help'] = _('''Stop a network connection in progress''')
language['connecting'] = _('''Connecting''')
language['pre_disconnect_script'] = _('''Run pre-disconnect script''')
language['cannot_edit_scripts_1'] = _('''To avoid various complications, wicd-curses does not support directly editing the scripts directly. However, you can edit them manually. First, (as root)", open the "$A" config file, and look for the section labeled by the $B in question. In this case, this is:''')
language['cannot_edit_scripts_3'] = _('''You can also configure the wireless networks by looking for the "[<ESSID>]" field in the config file.''')
language['cannot_edit_scripts_2'] = _('''Once there, you can adjust (or add) the "beforescript", "afterscript", and "disconnectscript" variables as needed, to change the preconnect, postconnect, and disconnect scripts respectively. Note that you will be specifying the full path to the scripts - not the actual script contents. You will need to add/edit the script contents separately. Refer to the wicd manual page for more information.''')
language['scripts_need_pass'] = _('''You must enter your password to configure scripts''')
language['dns_domain'] = _('''DNS domain''')
language['aborted'] = _('''Connection Cancelled''')
language['scanning_stand_by'] = _('''Scanning networks... stand by...''')
language['password'] = _('''Password''')
language['no_daemon_tooltip'] = _('''Wicd daemon unreachable''')
language['use_static_dns'] = _('''Use Static DNS''')
language['setting_broadcast_address'] = _('''Setting broadcast address...''')
language['choose_wired_profile'] = _('''Select or create a wired profile to connect with''')
language['make_wired_profile'] = _('''To connect to a wired network, you must create a network profile. To create a network profile, type a name that describes this network, and press Add.''')
language['esc_to_cancel'] = _('''Press ESC to cancel''')
language['scanning'] = _('''Scanning''')
language['flushing_routing_table'] = _('''Flushing the routing table...''')
language['brought_to_you'] = _('''Brought to you by:''')
language['refresh_help'] = _('''Refresh network list''')
language['select_hidden_essid'] = _('''Select Hidden Network ESSID''')
language['ext_programs'] = _('''External Programs''')
language['connect'] = _('''Connect''')
language['help_help'] = _('''Display this help dialog''')
language['use_global_dns'] = _('''Use global DNS servers''')
language['enable_encryption'] = _('''This network requires encryption to be enabled.''')
language['use_last_used_profile'] = _('''Use last used profile on wired autoconnect''')
language['preferences'] = _('''Preferences''')
language['dhcp_failed'] = _('''Connection Failed: Unable to Get IP Address''')
language['setting_static_ip'] = _('''Setting static IP addresses...''')
language['connecting_to_daemon'] = _('''Connecting to daemon...''')
language['automatic_connect'] = _('''Automatically connect to this network''')
language['add_new_wired_profile'] = _('''Add a new wired profile''')
language['dhcp_client'] = _('''DHCP Client''')
language['display_type_dialog'] = _('''Use dBm to measure signal strength''')
language['global_settings'] = _('''Use these settings for all networks sharing this essid''')
language['config_help'] = _('''Configure Selected Network''')
language['use_debug_mode'] = _('''Enable debug mode''')
language['removing_old_connection'] = _('''Removing old connection...''')
language['no_sudo_prog'] = _('''Could not find a graphical sudo program. The script editor could not be launched. You'll have to edit scripts directly your configuration file.''')
language['wireless_networks'] = _('''Wireless Networks''')
language['configuring_wired'] = _('''Configuring preferences for wired profile "$A"''')
language['no_wireless_networks_found'] = _('''No wireless networks found.''')
language['madwifi_for_adhoc'] = _('''Check if using madwifi/atheros drivers''')
language['properties'] = _('''Properties''')
language['setting_encryption_info'] = _('''Setting encryption info''')
language['about'] = _('''About Wicd''')
language['ok'] = _('''OK''')
language['adhoc_help'] = _('''Set up Ad-hoc network''')
language['scripts_help'] = _('''Select scripts''')
language['invalid_address'] = _('''Invalid address in $A entry.''')
language['configuring_interface'] = _('''Configuring wireless interface...''')
language['generating_psk'] = _('''Generating PSK...''')
language['validating_authentication'] = _('''Validating authentication...''')
language['essid'] = _('''ESSID''')
language['anonymous_identity'] = _('''Anonymous Identity''')
language['wireless_interface'] = _('''Wireless Interface''')
language['hidden_network'] = _('''Hidden Network''')
language['key'] = _('''Key''')
language['wicd_curses'] = _('''Wicd Curses Interface''')
language['debugging'] = _('''Debugging''')
language['use_encryption'] = _('''Use Encryption''')
language['wpa_supplicant'] = _('''WPA Supplicant''')
language['global_dns_servers'] = _('''Global DNS servers''')
language['not_connected'] = _('''Not connected''')
language['done'] = _('''Done connecting...''')
language['cannot_connect_to_daemon'] = _('''Can't connect to the daemon, trying to start it automatically...''')
language['cancel'] = _('''Cancel''')
language['case_sensitive'] = _('''All controls are case sensitive''')
language['gateway'] = _('''Gateway''')
language['backend'] = _('''Backend''')
language['dbus_fail'] = _('''DBus failure! This is most likely caused by the wicd daemon stopping while wicd-curses is running. Please restart the daemon, and then restart wicd-curses.''')
language['terminated'] = _('''Terminated by user''')
language['wired_detect'] = _('''Wired Link Detection''')
language['add_new_profile'] = _('''Add a new profile''')
language['use_ics'] = _('''Activate Internet Connection Sharing''')
language['create_adhoc_network'] = _('''Create an Ad-Hoc Network''')
language['interface_up'] = _('''Putting interface up...''')
language['global_dns_not_enabled'] = _('''Global DNS has not been enabled in general preferences.''')
language['dns'] = _('''DNS''')
language['advanced_settings'] = _('''Advanced Settings''')
language['username'] = _('''Username''')
language['wicd_auto_config'] = _('''Automatic (recommended)''')
language['wired_network_found'] = _('''Wired connection detected''')
language['netmask'] = _('''Netmask''')
language['select_a_network'] = _('''Choose from the networks below:''')
language['connect_help'] = _('''Connect to selected network''')
language['no_delete_last_profile'] = _('''wicd-curses does not support deleting the last wired profile. Try renaming it ('F2')''')
language['gen_settings'] = _('''General Settings''')
language['connected_to_wireless'] = _('''Connected to $A at $B (IP: $C)''')
language['exception'] = _('''EXCEPTION! Please report this to the maintainer and file a bug report with the backtrace below:''')
language['configuring_wireless'] = _('''Configuring preferences for wireless network "$A" ($B)''')
language['generating_wpa_config'] = _('''Generating WPA configuration file...''')
language['search_domain'] = _('''Search domain''')
language['encrypt_info_missing'] = _('''Required encryption information is missing.''')
language['running_dhcp'] = _('''Obtaining IP address...''')
language['lost_dbus'] = _('''The wicd daemon has shut down. The UI will not function properly until it is restarted.''')
language['wired_network_instructions'] = _('''To connect to a wired network, you must create a network profile. To create a network profile, type a name that describes this network, and press Add.''')
language['setting_static_dns'] = _('''Setting static DNS servers...''')
language['auto_reconnect'] = _('''Automatically reconnect on connection loss''')
language['use_wep_encryption'] = _('''Use Encryption (WEP only)''')
language['wired_autoconnect_settings'] = _('''Wired Autoconnect Settings''')
language['before_script'] = _('''Run script before connect''')
language['always_use_wext'] = _('''You should almost always use wext as the WPA supplicant driver''')
language['network_interfaces'] = _('''Network Interfaces''')
language['use_default_profile'] = _('''Use default profile on wired autoconnect''')
language['scan'] = _('''Scan''')
language['ip'] = _('''IP''')
language['connected_to_wired'] = _('''Connected to wired network (IP: $A)''')
language['wpa_supplicant_driver'] = _('''WPA Supplicant Driver''')
language['access_cards'] = _('''Wicd needs to access your computer's network cards.''')
language['killswitch_enabled'] = _('''Wireless Kill Switch Enabled''')
language['hidden_network_essid'] = _('''Hidden Network ESSID''')
language['secured'] = _('''Secured''')
language['interface_down'] = _('''Putting interface down...''')
language['authentication'] = _('''Authentication''')
language['after_script'] = _('''Run script after connect''')
language['show_wired_list'] = _('''Prompt for profile on wired autoconnect''')
language['channel'] = _('''Channel''')
language['unsecured'] = _('''Unsecured''')
language['rename_wired_profile'] = _('''Rename wired profile''')
language['daemon_unavailable'] = _('''The wicd daemon is unavailable, so your request cannot be completed''')
language['stop_showing_chooser'] = _('''Stop Showing Autoconnect pop-up temporarily''')
language['scan_help'] = _('''Scan for hidden networks''')
language['use_static_ip'] = _('''Use Static IPs''')
language['raw_screen_arg'] = _('''use urwid's raw screen controller''')
language['route_flush'] = _('''Route Table Flushing''')
language['scripts'] = _('''Scripts''')
language['identity'] = _('''Identity''')
language['automatic_reconnection'] = _('''Automatic Reconnection''')
language['wired_interface'] = _('''Wired Interface''')
language['press_to_quit'] = _('''Press F8 or Q to quit.''')
language['default_wired'] = _('''Use as default profile (overwrites any previous default)''')
language['wired_network'] = _('''Wired Network''')
language['dns_server'] = _('''DNS server''')
language['notifications'] = _('''Notifications''')
language['display_notifications'] = _('''Display notifications about connection status''')
language['connection_established'] = _('''Connection established''')
language['disconnected'] = _('''Disconnected''')
language['establishing_connection'] = _('''Establishing connection...''')
language['association_failed'] = _('''Connection failed: Could not contact the wireless access point.''')
language['access_denied'] = _('''Unable to contact the Wicd daemon due to an access denied error from DBus. Please check that your user is in the $A group.''')
language['disconnecting_active'] = _('''Disconnecting active connections...''')
language['access_denied_wc'] = _('''ERROR: wicd-curses was denied access to the wicd daemon: please check that your user is in the "$A" group.''')
language['post_disconnect_script'] = _('''Run post-disconnect script''')
>>>>>>> MERGE-SOURCE

335
wicd/wicd-client.py Executable file → Normal file
View File

@@ -14,14 +14,14 @@ class TrayIcon() -- Parent class of TrayIconGUI and IconConnectionInfo.
class StatusTrayIconGUI() -- Implements the tray icon using a
gtk.StatusIcon.
class EggTrayIconGUI() -- Implements the tray icon using egg.trayicon.
def usage() -- Prints usage information.
def main() -- Runs the wicd frontend main loop.
def usage() -- Prints usage information.
def main() -- Runs the wicd frontend main loop.
"""
#
# Copyright (C) 2007 - 2008 Adam Blackburn
# Copyright (C) 2007 - 2008 Dan O'Reilly
# Copyright (C) 2007 - 2009 Adam Blackburn
# Copyright (C) 2007 - 2009 Dan O'Reilly
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License Version 2 as
@@ -46,12 +46,23 @@ import time
import atexit
from dbus import DBusException
import pygtk
pygtk.require('2.0')
HAS_NOTIFY = True
try:
import pynotify
if not pynotify.init("Wicd"):
HAS_NOTIFY = False
except ImportError:
HAS_NOTIFY = False
# Wicd specific imports
from wicd import wpath
from wicd import misc
from wicd import gui
from wicd import dbusmanager
from wicd.guiutil import error
from wicd.guiutil import error, can_use_notify
from wicd.translations import language
@@ -79,8 +90,9 @@ def catchdbus(func):
try:
return func(*args, **kwargs)
except DBusException, e:
if "DBus.Error.AccessDenied" in e:
error(None, language['access_denied'])
if e.get_dbus_name() != None and "DBus.Error.AccessDenied" in e.get_dbus_name():
error(None, language['access_denied'].replace("$A","<b>"+wpath.wicd_group+"</b>"))
#raise
raise DBusException(e)
else:
print "warning: ignoring exception %s" % e
@@ -112,7 +124,7 @@ class TrayIcon(object):
Base Class for implementing a tray icon to display network status.
"""
def __init__(self, animate):
def __init__(self, animate, displaytray=True):
self.cur_sndbytes = -1
self.cur_rcvbytes = -1
self.last_sndbytes = -1
@@ -125,10 +137,13 @@ class TrayIcon(object):
else:
self.tr = self.StatusTrayIconGUI(self)
self.icon_info = self.TrayConnectionInfo(self, self.tr, animate)
self.tr.icon_info = self.icon_info
print 'displaytray %s' % displaytray
self.tr.visible(displaytray)
def is_embedded(self):
if USE_EGG:
raise NotImplementedError
raise NotImplementedError()
else:
return self.tr.is_embedded()
@@ -152,12 +167,19 @@ class TrayIcon(object):
class TrayConnectionInfo(object):
""" Class for updating the tray icon status. """
def __init__(self, parent, tr, animate=True):
# Initialize variables needed for the icon status methods.
""" Initialize variables needed for the icon status methods. """
self.last_strength = -2
self.still_wired = False
self.network = ''
self.tried_reconnect = False
self.connection_lost_counter = 0
self.tr = tr
self.last_sndbytes = -1
self.last_rcvbytes = -1
self.max_snd_gain = 10000
self.max_rcv_gain = 10000
self.animate = animate
self.parent = parent
self.network_name = '' # SSID
@@ -166,6 +188,12 @@ class TrayIcon(object):
self.network_addr = '0.0.0.0' # IP Address
self.network_br = '' # Bitrate
# keep track of the last state to provide appropriate
# notifications
self._last_bubble = None
self.last_state = None
self.should_notify = True
if DBUS_AVAIL:
self.update_tray_icon()
else:
@@ -198,6 +226,20 @@ class TrayIcon(object):
return True
def _show_notification(self, title, details, image=None):
if self.should_notify:
if not self._last_bubble:
self._last_bubble = pynotify.Notification(title, details,
image)
self._last_bubble.show()
else:
self._last_bubble.clear_actions()
self._last_bubble.clear_hints()
self._last_bubble.update(title, details, image)
self._last_bubble.show()
self.should_notify = False
@catchdbus
def wired_profile_chooser(self):
""" Launch the wired profile chooser. """
@@ -210,14 +252,24 @@ class TrayIcon(object):
self.network_addr = str(info[0])
self.network_type = "wired"
self.tr.set_from_file(os.path.join(wpath.images, "wired.png"))
# status_string = language['connected_to_wired'].replace('$A',
wired_ip)
# self.tr.set_tooltip(status_string)
self._show_notification(language['wired_network'],
language['connection_established'],
'network-wired')
self.update_tooltip()
@catchdbus
def set_wireless_state(self, info):
""" Sets the icon info for a wireless state. """
lock = ''
wireless_ip = info[0]
self.network = info[1]
strength = info[2]
cur_net_id = int(info[3])
sig_string = daemon.FormatSignalForPrinting(str(info[2]))
sig_string = daemon.FormatSignalForPrinting(str(strength))
self.network_type = "wireless"
self.network_addr = str(info[0])
self.network_name = info[1]
@@ -227,31 +279,57 @@ class TrayIcon(object):
if wireless.GetWirelessProperty(cur_net_id, "encryption"):
lock = "-lock"
# status_string = (language['connected_to_wireless']
.replace('$A', self.network)
.replace('$B', sig_string)
.replace('$C', str(wireless_ip)))
#self.tr.set_tooltip(status_string)
self.set_signal_image(int(strength), lock)
self._show_notification(self.network,
language['connection_established'],
'network-wireless')
self.update_tooltip()
def set_connecting_state(self, info):
""" Sets the icon info for a connecting state. """
self.network_type = info[0]
if info[0] == 'wireless':
self.network_name = info[1]
wired = False
if info[0] == 'wired' and len(info) == 1:
cur_network = language['wired_network']
wired = True
else:
cur_network = info[1]
status_string = language['connecting'] + " to " + \
cur_network + "..."
self.update_tooltip()
# self.tr.set_tooltip(status_string)
self.tr.set_from_file(os.path.join(wpath.images, "no-signal.png"))
if wired:
self._show_notification(cur_network,
language['establishing_connection'],
'network-wired')
else:
self._show_notification(cur_network,
language['establishing_connection'],
'network-wireless')
@catchdbus
def set_not_connected_state(self, info=None):
""" Set the icon info for the not connected state. """
self.tr.set_from_file(wpath.images + "no-signal.png")
if not DBUS_AVAIL:
self.network_type = "no_daemon"
status = language['no_daemon_tooltip']
elif wireless.GetKillSwitchEnabled():
self.network_type = "killswitch"
status = (language['not_connected'] + " (" +
language['killswitch_enabled'] + ")")
else:
self.network_type = "none"
status = language['not_connected']
# self.tr.set_tooltip(status)
self._show_notification(language['disconnected'], None, 'stop')
self.update_tooltip()
@catchdbus
def update_tray_icon(self, state=None, info=None):
""" Updates the tray icon and current connection status. """
@@ -259,6 +337,12 @@ class TrayIcon(object):
if not state or not info:
[state, info] = daemon.GetConnectionStatus()
# should this state change display a notification?
self.should_notify = (can_use_notify() and
self.last_state != state)
self.last_state = state
if state == misc.WIRED:
self.set_wired_state(info)
@@ -277,8 +361,7 @@ class TrayIcon(object):
def set_signal_image(self, wireless_signal, lock):
""" Sets the tray icon image for an active wireless connection. """
if self.animate:
TrayIcon.get_bandwidth_bytes(self.parent)
prefix = self.get_bandwidth_activity()
prefix = self.get_bandwidth_state()
else:
prefix = 'idle-'
if daemon.GetSignalDisplayType() == 0:
@@ -304,26 +387,40 @@ class TrayIcon(object):
self.tr.set_from_file(img_file)
@catchdbus
def get_bandwidth_activity(self):
def get_bandwidth_state(self):
""" Determines what network activity state we are in. """
transmitting = False
receiving = False
dev_dir = '/sys/class/net/'
wiface = daemon.GetWirelessInterface()
for fldr in os.listdir(dev_dir):
if fldr == wiface:
dev_dir = dev_dir + fldr + "/statistics/"
break
try:
rcvbytes = int(open(dev_dir + "rx_bytes", "r").read().strip())
sndbytes = int(open(dev_dir + "tx_bytes", "r").read().strip())
except IOError:
sndbytes = None
rcvbytes = None
if not rcvbytes or not sndbytes:
return 'idle-'
# Figure out receiving data info.
activity = self.is_network_active(self.parent.cur_rcvbytes,
self.parent.max_rcv_gain,
self.parent.last_rcvbytes)
activity = self.is_network_active(rcvbytes, self.max_rcv_gain,
self.last_rcvbytes)
receiving = activity[0]
self.parent.max_rcv_gain = activity[1]
self.parent.last_rcvbytes = activity[2]
self.max_rcv_gain = activity[1]
self.last_rcvbytes = activity[2]
# Figure out out transmitting data info.
activity = self.is_network_active(self.parent.cur_sndbytes,
self.parent.max_snd_gain,
self.parent.last_sndbytes)
activity = self.is_network_active(sndbytes, self.max_snd_gain,
self.last_sndbytes)
transmitting = activity[0]
self.parent.max_snd_gain = activity[1]
self.parent.last_sndbytes = activity[2]
self.max_snd_gain = activity[1]
self.last_sndbytes = activity[2]
if transmitting and receiving:
return 'both-'
@@ -369,7 +466,7 @@ class TrayIcon(object):
tray icons.
"""
def __init__(self, parent):
def __init__(self):
menu = """
<ui>
<menubar name="Menubar">
@@ -377,7 +474,6 @@ class TrayIcon(object):
<menu action="Connect">
</menu>
<separator/>
<menuitem action="Info"/>
<menuitem action="About"/>
<menuitem action="Quit"/>
</menu>
@@ -387,9 +483,6 @@ class TrayIcon(object):
actions = [
('Menu', None, 'Menu'),
('Connect', gtk.STOCK_CONNECT, "Connect"),
('Info', gtk.STOCK_INFO, "_Connection Info", None,
'Information about the current connection',
self.on_conn_info),
('About', gtk.STOCK_ABOUT, '_About...', None,
'About wicd-tray-icon', self.on_about),
('Quit',gtk.STOCK_QUIT,'_Quit',None,'Quit wicd-tray-icon',
@@ -408,11 +501,6 @@ class TrayIcon(object):
net_menuitem = self.manager.get_widget("/Menubar/Menu/Connect/")
net_menuitem.connect("activate", self.on_net_menu_activate)
self.parent = parent
self.time = 2 # Time between updates
self.cont = 'Stop'
self.conn_info_txt = ''
def tray_scan_started(self):
""" Callback for when a wireless scan is started. """
if not DBUS_AVAIL: return
@@ -446,96 +534,6 @@ class TrayIcon(object):
dialog.set_website('http://wicd.net')
dialog.run()
dialog.destroy()
def on_conn_info(self, data=None):
""" Opens the Connection Information Dialog """
window = gtk.Dialog("Wicd Connection Info", None, 0, (gtk.STOCK_OK, gtk.RESPONSE_CLOSE))
# Create labels
self.label = gtk.Label()
self.data = gtk.Label()
self.label.show()
self.data.show()
self.list = []
self.list.append(self.data)
self.list.append(self.label)
# Setup table
table = gtk.Table(1,2)
table.set_col_spacings(12)
table.attach(self.label, 0, 1, 0, 1)
table.attach(self.data, 1, 2, 0 ,1)
# Setup Window
content = window.get_content_area()
content.pack_start(table, True, True, 0)
content.show_all()
# Start updates
self.cont = 'Go'
gobject.timeout_add(5000, self.update_conn_info_win, self.list)
self.update_conn_info_win(self.list)
window.run()
# Destroy window and stop updates
window.destroy()
self.cont = 'Stop'
def update_conn_info_win(self, list):
""" Updates the information in the connection summary window """
if (self.cont == "Stop"):
return False
[state, info] = daemon.GetConnectionStatus()
[rx, tx] = self.get_current_bandwidth()
# Choose info for the data
if state == misc.WIRED:
text = (language['conn_info_wired']
.replace('$A', str(info[0])) #IP
.replace('$B', str(rx)) #RX
.replace('$C', str(tx))) #TX
elif state == misc.WIRELESS:
text = (language['conn_info_wireless']
.replace('$A', str(info[1])) #SSID
.replace('$B', str(info[4])) #Speed
.replace('$C', str(info[0])) #IP
.replace('$D', daemon.FormatSignalForPrinting(str(info[2])))
.replace('$E', str(rx))
.replace('$F', str(tx)))
else:
text = ''
# Choose info for the labels
self.list[0].set_text(text)
if state == misc.WIRED:
self.list[1].set_text(language['conn_info_wired_labels'])
elif state == misc.WIRELESS:
self.list[1].set_text(language['conn_info_wireless_labels'])
elif state == misc.CONNECTING:
self.list[1].set_text(language['conn_info_connecting'])
elif state in (misc.SUSPENDED, misc.NOT_CONNECTED):
self.list[1].set_text(language['conn_info_not_connected'])
return True
def get_current_bandwidth(self):
"""
Calculates the current bandwidth based on sent/received bytes
divided over time. Unit is in KB/s
"""
self.parent.get_bandwidth_bytes()
rxb = self.parent.cur_rcvbytes - self.parent.last_rcvbytes
txb = self.parent.cur_sndbytes - self.parent.last_sndbytes
self.parent.last_rcvbytes = self.parent.cur_rcvbytes
self.parent.last_sndbytes = self.parent.cur_sndbytes
rx_rate = float(rxb / (self.time * 1024))
tx_rate = float(txb / (self.time * 1024))
return (rx_rate, tx_rate)
def _add_item_to_menu(self, net_menu, lbl, type_, n_id, is_connecting,
is_active):
@@ -600,29 +598,29 @@ class TrayIcon(object):
signal_img = 'signal-25.png'
return wpath.images + signal_img
@catchdbus
def on_net_menu_activate(self, item):
""" Trigger a background scan to populate the network menu.
Called when the network submenu is moused over. We
sleep briefly, clear pending gtk events, and if
we're still being moused over we trigger a scan.
This is to prevent scans when the user is just
mousing past the menu to select another menu item.
Clear the network menu, and schedule a method to be
called in .8 seconds to trigger a scan if the menu
is still being moused over.
"""
def dummy(x=None): pass
if self._is_scanning:
return True
self.init_network_menu()
time.sleep(.4)
gobject.timeout_add(800, self._trigger_scan_if_needed, item)
@catchdbus
def _trigger_scan_if_needed(self, item):
""" Trigger a scan if the network menu is being hovered over. """
while gtk.events_pending():
gtk.main_iteration()
if item.state != gtk.STATE_PRELIGHT:
return True
return False
wireless.Scan(False)
return False
@catchdbus
def populate_network_menu(self, data=None):
@@ -671,7 +669,7 @@ class TrayIcon(object):
net_menuitem.show()
def init_network_menu(self):
""" Set the right-click menu for to the scanning state. """
""" Set the right-click network menu to the scanning state. """
net_menuitem = self.manager.get_widget("/Menubar/Menu/Connect/")
submenu = net_menuitem.get_submenu()
self._clear_menu(submenu)
@@ -691,7 +689,7 @@ class TrayIcon(object):
def toggle_wicd_gui(self):
""" Toggles the wicd GUI. """
if not self.gui_win:
self.gui_win = gui.appGui()
self.gui_win = gui.appGui(tray=self)
elif not self.gui_win.is_visible:
self.gui_win.show_win()
else:
@@ -708,9 +706,9 @@ class TrayIcon(object):
for machines running versions of GTK < 2.10.
"""
def __init__(self, parent):
def __init__(self):
"""Initializes the tray icon"""
TrayIcon.TrayIconGUI.__init__(self, parent)
TrayIcon.TrayIconGUI.__init__(self)
self.tooltip = gtk.Tooltips()
self.eb = gtk.EventBox()
self.tray = egg.trayicon.TrayIcon("WicdTrayIcon")
@@ -744,6 +742,18 @@ class TrayIcon(object):
"""
self.tooltip.set_tip(self.eb, val)
def visible(self, val):
""" Set if the icon is visible or not.
If val is True, makes the icon visible, if val is False,
hides the tray icon.
"""
if val:
self.tray.show_all()
else:
self.tray.hide_all()
if hasattr(gtk, "StatusIcon"):
class StatusTrayIconGUI(gtk.StatusIcon, TrayIconGUI):
@@ -752,8 +762,8 @@ class TrayIcon(object):
Uses gtk.StatusIcon to implement a tray icon.
"""
def __init__(self, parent):
TrayIcon.TrayIconGUI.__init__(self, parent)
def __init__(self):
TrayIcon.TrayIconGUI.__init__(self)
gtk.StatusIcon.__init__(self)
self.current_icon_path = ''
@@ -774,6 +784,14 @@ class TrayIcon(object):
self.current_icon_path = path
gtk.StatusIcon.set_from_file(self, path)
def visible(self, val):
""" Set if the icon is visible or not.
If val is True, makes the icon visible, if val is False,
hides the tray icon.
"""
self.set_visible(val)
def usage():
""" Print usage information. """
@@ -785,6 +803,7 @@ Arguments:
\t-n\t--no-tray\tRun wicd without the tray icon.
\t-h\t--help\t\tPrint this help information.
\t-a\t--no-animate\tRun the tray without network traffic tray animations.
\t-o\t--only-notifications\tDon't display anything except notifications.
""" % wpath.version
def setup_dbus(force=True):
@@ -798,7 +817,7 @@ def setup_dbus(force=True):
misc.PromptToStartDaemon()
try:
dbusmanager.connect_to_dbus()
except dbusmanager.DBusException:
except DBusException:
error(None, "Could not connect to wicd's D-Bus interface. " +
"Check the wicd log for error messages.")
return False
@@ -820,7 +839,7 @@ def on_exit():
if DBUS_AVAIL:
try:
daemon.SetGUIOpen(False)
except dbusmanager.DBusException:
except DBusException:
pass
def handle_no_dbus():
@@ -842,8 +861,9 @@ def main(argv):
"""
try:
opts, args = getopt.getopt(sys.argv[1:], 'nha', ['help', 'no-tray',
'no-animate'])
opts, args = getopt.getopt(sys.argv[1:], 'nhao', ['help', 'no-tray',
'no-animate',
'only-notifications'])
except getopt.GetoptError:
# Print help information and exit
usage()
@@ -851,6 +871,7 @@ def main(argv):
use_tray = True
animate = True
display_app = True
for opt, a in opts:
if opt in ('-h', '--help'):
usage()
@@ -859,6 +880,10 @@ def main(argv):
use_tray = False
elif opt in ('-a', '--no-animate'):
animate = False
elif opt in ('-o', '--only-notifications'):
print "only displaying notifications"
use_tray = False
display_app = False
else:
usage()
sys.exit(2)
@@ -867,14 +892,14 @@ def main(argv):
setup_dbus()
atexit.register(on_exit)
if not use_tray or not ICON_AVAIL:
if display_app and not use_tray or not ICON_AVAIL:
the_gui = gui.appGui(standalone=True)
mainloop = gobject.MainLoop()
mainloop.run()
sys.exit(0)
# Set up the tray icon GUI and backend
tray_icon = TrayIcon(animate)
tray_icon = TrayIcon(animate, displaytray=display_app)
# Check to see if wired profile chooser was called before icon
# was launched (typically happens on startup or daemon restart).

File diff suppressed because it is too large Load Diff

View File

@@ -6,18 +6,16 @@
This module implements functions to control and obtain information from
network interfaces.
def SetDNS() -- Set the DNS servers of the system.
def GetWirelessInterfaces() -- Get the wireless interfaces available.
class Interface() -- Control a network interface.
class WiredInterface() -- Control a wired network interface.
class WirelessInterface() -- Control a wireless network interface.
class BaseInterface() -- Control a network interface.
class BaseWiredInterface() -- Control a wired network interface.
class BaseWirelessInterface() -- Control a wireless network interface.
"""
#
# Copyright (C) 2007 - 2008 Adam Blackburn
# Copyright (C) 2007 - 2008 Dan O'Reilly
# Copyright (C) 2007 - 2008 Byron Hillis
# Copyright (C) 2007 - 2009 Adam Blackburn
# Copyright (C) 2007 - 2009 Dan O'Reilly
# Copyright (C) 2007 - 2009 Byron Hillis
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License Version 2 as
@@ -43,30 +41,30 @@ import misc
from misc import find_path
# Regular expressions.
__re_mode = (re.I | re.M | re.S)
essid_pattern = re.compile('.*ESSID:"?(.*?)"?\s*\n', __re_mode)
ap_mac_pattern = re.compile('.*Address: (.*?)\n', __re_mode)
channel_pattern = re.compile('.*Channel:? ?(\d\d?)', __re_mode)
strength_pattern = re.compile('.*Quality:?=? ?(\d+)\s*/?\s*(\d*)', __re_mode)
altstrength_pattern = re.compile('.*Signal level:?=? ?(\d+)\s*/?\s*(\d*)', __re_mode)
signaldbm_pattern = re.compile('.*Signal level:?=? ?(-\d\d*)', __re_mode)
bitrates_pattern = re.compile('.*Bit Rates:(.*?)E', __re_mode)
mode_pattern = re.compile('.*Mode:(.*?)\n', __re_mode)
freq_pattern = re.compile('.*Frequency:(.*?)\n', __re_mode)
wep_pattern = re.compile('.*Encryption key:(.*?)\n', __re_mode)
altwpa_pattern = re.compile('(wpa_ie)', __re_mode)
wpa1_pattern = re.compile('(WPA Version 1)', __re_mode)
wpa2_pattern = re.compile('(WPA2)', __re_mode)
_re_mode = (re.I | re.M | re.S)
essid_pattern = re.compile('.*ESSID:"?(.*?)"?\s*\n', _re_mode)
ap_mac_pattern = re.compile('.*Address: (.*?)\n', _re_mode)
channel_pattern = re.compile('.*Channel:?=? ?(\d\d?)', _re_mode)
strength_pattern = re.compile('.*Quality:?=? ?(\d+)\s*/?\s*(\d*)', _re_mode)
altstrength_pattern = re.compile('.*Signal level:?=? ?(\d+)\s*/?\s*(\d*)', _re_mode)
signaldbm_pattern = re.compile('.*Signal level:?=? ?(-\d\d*)', _re_mode)
bitrates_pattern = re.compile('(\d+\s+\S+/s)', _re_mode)
mode_pattern = re.compile('.*Mode:(.*?)\n', _re_mode)
freq_pattern = re.compile('.*Frequency:(.*?)\n', _re_mode)
wep_pattern = re.compile('.*Encryption key:(.*?)\n', _re_mode)
altwpa_pattern = re.compile('(wpa_ie)', _re_mode)
wpa1_pattern = re.compile('(WPA Version 1)', _re_mode)
wpa2_pattern = re.compile('(WPA2)', _re_mode)
#iwconfig-only regular expressions.
ip_pattern = re.compile(r'inet [Aa]d?dr[^.]*:([^.]*\.[^.]*\.[^.]*\.[0-9]*)',re.S)
bssid_pattern = re.compile('.*Access Point: (([0-9A-Z]{2}:){5}[0-9A-Z]{2})', __re_mode)
bitrate_pattern = re.compile('.*Bit Rate=(.*?/s)', __re_mode)
opmode_pattern = re.compile('.*Mode:(.*?) ', __re_mode)
authmethods_pattern = re.compile('.*Authentication capabilities :\n(.*?)Current', __re_mode)
ip_pattern = re.compile(r'inet [Aa]d?dr[^.]*:([^.]*\.[^.]*\.[^.]*\.[0-9]*)', re.S)
bssid_pattern = re.compile('.*Access Point: (([0-9A-Z]{2}:){5}[0-9A-Z]{2})', _re_mode)
bitrate_pattern = re.compile('.*Bit Rate=(.*?/s)', _re_mode)
opmode_pattern = re.compile('.*Mode:(.*?) ', _re_mode)
authmethods_pattern = re.compile('.*Authentication capabilities :\n(.*?)Current', _re_mode)
# Regular expressions for wpa_cli output
auth_pattern = re.compile('.*wpa_state=(.*?)\n', __re_mode)
auth_pattern = re.compile('.*wpa_state=(.*?)\n', _re_mode)
RALINK_DRIVER = 'ralink legacy'
@@ -74,9 +72,6 @@ blacklist_strict = '!"#$%&\'()*+,./:;<=>?@[\\]^`{|}~ '
blacklist_norm = ";`$!*|><&\\"
blank_trans = maketrans("", "")
__all__ = ["GetDefaultGateway", "GetWiredInterfaces",
"GetWirelessInterfaces", "IsValidWpaSuppDriver"]
def _sanitize_string(string):
if string:
return translate(str(string), blank_trans, blacklist_norm)
@@ -88,6 +83,31 @@ def _sanitize_string_strict(string):
return translate(str(string), blank_trans, blacklist_strict)
else:
return string
_cache = {}
def timedcache(duration=5):
""" A caching decorator for use with wnettools methods.
Caches the results of a function for a given number of
seconds (defaults to 5).
"""
def _timedcache(f):
def __timedcache(self, *args, **kwargs):
key = str(args) + str(kwargs) + str(f)
if hasattr(self, 'iface'):
key += self.iface
if (key in _cache and
(time.time() - _cache[key]['time']) < duration):
return _cache[key]['value']
else:
value = f(self, *args, **kwargs)
_cache[key] = { 'time' : time.time(), 'value' : value }
return value
return __timedcache
return _timedcache
def GetDefaultGateway():
""" Attempts to determine the default gateway by parsing route -n. """
@@ -117,18 +137,18 @@ def GetWirelessInterfaces():
"""
dev_dir = '/sys/class/net/'
ifnames = []
ifnames = [iface for iface in os.listdir(dev_dir) if os.path.isdir(dev_dir + iface)
and 'wireless' in os.listdir(dev_dir + iface)]
ifnames = [iface for iface in os.listdir(dev_dir)
if os.path.isdir(dev_dir + iface) and
'wireless' in os.listdir(dev_dir + iface)]
return ifnames
def GetWiredInterfaces():
""" Returns a list of wired interfaces on the system. """
basedir = '/sys/class/net/'
return [iface for iface in os.listdir(basedir) if not 'wireless'
in os.listdir(basedir + iface) and
return [iface for iface in os.listdir(basedir)
if os.path.isdir(basedir + iface) and not 'wireless'
in os.listdir(basedir + iface) and
open(basedir + iface + "/type").readlines()[0].strip() == "1"]
def NeedsExternalCalls():
@@ -139,10 +159,7 @@ def IsValidWpaSuppDriver(driver):
""" Returns True if given string is a valid wpa_supplicant driver. """
output = misc.Run(["wpa_supplicant", "-D%s" % driver, "-iolan19",
"-c/etc/abcd%sdefzz.zconfz" % random.randint(1, 1000)])
if re.match("Unsupported driver", output):
return False
else:
return True
return not "Unsupported driver" in output
def neediface(default_response):
""" A decorator for only running a method if self.iface is defined.
@@ -154,7 +171,8 @@ def neediface(default_response):
"""
def wrapper(func):
def newfunc(self, *args, **kwargs):
if not self.iface:
if not self.iface or \
not os.path.exists('/sys/class/net/%s' % self.iface):
return default_response
return func(self, *args, **kwargs)
newfunc.__dict__ = func.__dict__
@@ -222,15 +240,20 @@ class BaseInterface(object):
"""
def get_client_name(cl):
""" Converts the integer value for a dhcp client to a string. """
if self.dhclient_cmd and cl in [misc.DHCLIENT, misc.AUTO]:
client = "dhclient"
cmd = self.dhclient_cmd
elif self.dhcpcd_cmd and cl in [misc.DHCPCD, misc.AUTO]:
if self.dhcpcd_cmd and cl in [misc.DHCPCD, misc.AUTO]:
client = "dhcpcd"
cmd = self.dhcpcd_cmd
elif self.pump_cmd and cl in [misc.PUMP, misc.AUTO]:
client = "pump"
cmd = self.pump_cmd
elif self.dhclient_cmd and cl in [misc.DHCLIENT, misc.AUTO]:
client = "dhclient"
cmd = self.dhclient_cmd
if self.dhclient_needs_verbose:
cmd += ' -v'
elif self.udhcpc_cmd and cl in [misc.UDHCPC, misc.AUTO]:
client = "udhcpc"
cmd = self.udhcpc_cmd
else:
client = None
cmd = ""
@@ -238,20 +261,25 @@ class BaseInterface(object):
client_dict = {
"dhclient" :
{'connect' : r"%s %s",
'release' : r"%s -r %s",
{'connect' : r"%(cmd)s %(iface)s",
'release' : r"%(cmd)s -r %(iface)s",
'id' : misc.DHCLIENT,
},
"pump" :
{ 'connect' : r"%s -i %s",
'release' : r"%s -r -i %s",
{ 'connect' : r"%(cmd)s -i %(iface)s",
'release' : r"%(cmd)s -r -i %(iface)s",
'id' : misc.PUMP,
},
"dhcpcd" :
{'connect' : r"%s %s",
'release' : r"%s -k %s",
{'connect' : r"%(cmd)s %(iface)s",
'release' : r"%(cmd)s -k %(iface)s",
'id' : misc.DHCPCD,
},
"udhcpc":
{'connect' : r"%(cmd)s -n -i %(iface)s",
'release' : r"killall -SIGUSR2 %(cmd)s",
'id' : misc.UDHCPC,
},
}
(client_name, cmd) = get_client_name(self.DHCP_CLIENT)
if not client_name or not cmd:
@@ -259,9 +287,9 @@ class BaseInterface(object):
return ""
if flavor == "connect":
return client_dict[client_name]['connect'] % (cmd, self.iface)
return client_dict[client_name]['connect'] % {"cmd":cmd, "iface":self.iface}
elif flavor == "release":
return client_dict[client_name]['release'] % (cmd, self.iface)
return client_dict[client_name]['release'] % {"cmd":cmd, "iface":self.iface}
else:
return client_dict[client_name]['id']
@@ -299,8 +327,16 @@ class BaseInterface(object):
"""
self.dhclient_cmd = self._find_program_path("dhclient")
if self.dhclient_cmd != None:
output = misc.Run(self.dhclient_cmd + " --version",
include_stderr=True)
if '4.' in output:
self.dhclient_needs_verbose = True
else:
self.dhclient_needs_verbose = False
self.dhcpcd_cmd = self._find_program_path("dhcpcd")
self.pump_cmd = self._find_program_path("pump")
self.udhcpc_cmd = self._find_program_path("udhcpc")
def CheckWiredTools(self):
""" Check for the existence of ethtool and mii-tool. """
@@ -348,6 +384,14 @@ class BaseInterface(object):
if self.verbose: print cmd
misc.Run(cmd)
return True
@timedcache(2)
@neediface("")
def GetIfconfig(self):
""" Runs ifconfig and returns the output. """
cmd = "ifconfig %s" % self.iface
if self.verbose: print cmd
return misc.Run(cmd)
@neediface("")
def SetAddress(self, ip=None, netmask=None, broadcast=None):
@@ -397,7 +441,7 @@ class BaseInterface(object):
if line == '': # Empty string means dhclient is done.
dhclient_complete = True
else:
print line.strip('\n')
print misc.to_unicode(line.strip('\n'))
if line.startswith('bound'):
dhclient_success = True
dhclient_complete = True
@@ -424,7 +468,7 @@ class BaseInterface(object):
elif line.strip().lower().startswith('Operation failed.'):
pump_success = False
pump_complete = True
print line
print misc.to_unicode(line)
return self._check_dhcp_result(pump_success)
@@ -448,10 +492,34 @@ class BaseInterface(object):
dhcpcd_complete = True
elif line == '':
dhcpcd_complete = True
print line
print misc.to_unicode(line)
return self._check_dhcp_result(dhcpcd_success)
def _parse_udhcpc(self, pipe):
""" Determines if obtaining an IP using udhcpc succeeded.
Keyword arguments:
pipe -- stdout pipe to the dhcpcd process.
Returns:
'success' if successful, an error code string otherwise.
"""
udhcpc_complete = False
udhcpc_success = True
while not udhcpc_complete:
line = pipe.readline()
if line.endswith("failing"):
udhcpc_success = False
udhcpc_complete = True
elif line == '':
udhcpc_complete = True
print line
return self._check_dhcp_result(udhcpc_success)
def _check_dhcp_result(self, success):
""" Print and return the correct DHCP connection result.
@@ -490,6 +558,8 @@ class BaseInterface(object):
return self._parse_pump(pipe)
elif DHCP_CLIENT == misc.DHCPCD:
return self._parse_dhcpcd(pipe)
elif DHCP_CLIENT == misc.UDHCPC:
return self._parse_udhcpc(pipe)
else:
print 'ERROR no dhclient found!'
@@ -595,9 +665,7 @@ class BaseInterface(object):
"""
if not ifconfig:
cmd = 'ifconfig ' + self.iface
if self.verbose: print cmd
output = misc.Run(cmd)
output = self.GetIfconfig()
else:
output = ifconfig
return misc.RunRegex(ip_pattern, output)
@@ -634,9 +702,7 @@ class BaseInterface(object):
def _slow_is_up(self, ifconfig=None):
""" Determine if an interface is up using ifconfig. """
if not ifconfig:
cmd = "ifconfig " + self.iface
if self.verbose: print cmd
output = misc.Run(cmd)
output = self.GetIfconfig()
else:
output = ifconfig
lines = output.split('\n')
@@ -799,6 +865,7 @@ class BaseWirelessInterface(BaseInterface):
return radiostatus
@timedcache(2)
@neediface(False)
def GetIwconfig(self):
""" Returns the output of iwconfig for this interface. """
@@ -964,12 +1031,17 @@ class BaseWirelessInterface(BaseInterface):
"""
cmd = ['iwconfig', self.iface, 'essid', essid]
if channel and str(channel).isdigit():
cmd.extend(['channel', str(channel)])
if bssid:
cmd.extend(['ap', bssid])
if self.verbose: print str(cmd)
misc.Run(cmd)
base = "iwconfig %s" % self.iface
if channel and str(channel).isdigit():
cmd = "%s channel %s" % (base, str(channel))
if self.verbose: print cmd
misc.Run(cmd)
if bssid:
cmd = "%s ap %s" % (base, bssid)
if self.verbose: print cmd
misc.Run(cmd)
def GeneratePSK(self, network):
""" Generate a PSK using wpa_passphrase.
@@ -982,7 +1054,7 @@ class BaseWirelessInterface(BaseInterface):
if not wpa_pass_path: return None
key_pattern = re.compile('network={.*?\spsk=(.*?)\n}.*',
re.I | re.M | re.S)
cmd = [wpa_pass_path, network['essid'], network['key']]
cmd = [wpa_pass_path, network['essid'], str(network['key'])]
if self.verbose: print cmd
return misc.RunRegex(key_pattern, misc.Run(cmd))
@@ -1070,15 +1142,21 @@ class BaseWirelessInterface(BaseInterface):
# An array for the access points
access_points = []
access_points = {}
for cell in networks:
# Only use sections where there is an ESSID.
if 'ESSID:' in cell:
# Add this network to the list of networks
entry = self._ParseAccessPoint(cell, ralink_info)
if entry is not None:
access_points.append(entry)
# Normally we only get duplicate bssids with hidden
# networks. If we hit this, we only want the entry
# with the real essid to be in the network list.
if (entry['bssid'] not in access_points
or not entry['hidden']):
access_points[entry['bssid']] = entry
return access_points
return access_points.values()
def _ParseAccessPoint(self, cell, ralink_info):
""" Parse a single cell from the output of iwlist.
@@ -1099,7 +1177,8 @@ class BaseWirelessInterface(BaseInterface):
except (UnicodeDecodeError, UnicodeEncodeError):
print 'Unicode problem with current network essid, ignoring!!'
return None
if ap['essid'] in ['<hidden>', ""]:
if ap['essid'] in ['<hidden>', "", None]:
print 'hidden'
ap['hidden'] = True
ap['essid'] = "<hidden>"
else:
@@ -1113,9 +1192,9 @@ class BaseWirelessInterface(BaseInterface):
ap['channel'] = self._FreqToChannel(freq)
# Bit Rate
ap['bitrates'] = misc.RunRegex(bitrates_pattern, cell).split('\n')
ap['bitrates'] = '; '.join(m.strip() for m in ap['bitrates']).rstrip('; ')
ap['bitrates'] = misc.RunRegex(bitrates_pattern,
cell.split("Bit Rates")[-1])
# BSSID
ap['bssid'] = misc.RunRegex(ap_mac_pattern, cell)
@@ -1181,6 +1260,7 @@ class BaseWirelessInterface(BaseInterface):
MAX_TIME = 35
MAX_DISCONNECTED_TIME = 3
disconnected_time = 0
forced_rescan = False
while (time.time() - auth_time) < MAX_TIME:
cmd = '%s -i %s status' % (self.wpa_cli_cmd, self.iface)
output = misc.Run(cmd)
@@ -1192,11 +1272,12 @@ class BaseWirelessInterface(BaseInterface):
return False
if result == "COMPLETED":
return True
elif result == "DISCONNECTED":
elif result == "DISCONNECTED" and not forced_rescan:
disconnected_time += 1
if disconnected_time > MAX_DISCONNECTED_TIME:
disconnected_time = 0
# Force a rescan to get wpa_supplicant moving again.
forced_rescan = True
self._ForceSupplicantScan()
MAX_TIME += 5
else:
@@ -1233,9 +1314,7 @@ class BaseWirelessInterface(BaseInterface):
def GetBSSID(self, iwconfig=None):
""" Get the MAC address for the interface. """
if not iwconfig:
cmd = 'iwconfig ' + self.iface
if self.verbose: print cmd
output = misc.Run(cmd)
output = self.GetIwconfig()
else:
output = iwconfig
@@ -1246,9 +1325,7 @@ class BaseWirelessInterface(BaseInterface):
def GetCurrentBitrate(self, iwconfig=None):
""" Get the current bitrate for the interface. """
if not iwconfig:
cmd = 'iwconfig ' + self.iface
if self.verbose: print cmd
output = misc.Run(cmd)
output = self.GetIwconfig()
else:
output = iwconfig
@@ -1259,9 +1336,7 @@ class BaseWirelessInterface(BaseInterface):
def GetOperationalMode(self, iwconfig=None):
""" Get the operational mode for the interface. """
if not iwconfig:
cmd = 'iwconfig ' + self.iface
if self.verbose: print cmd
output = misc.Run(cmd)
output = self.GetIwconfig()
else:
output = iwconfig
@@ -1292,7 +1367,14 @@ class BaseWirelessInterface(BaseInterface):
(strength, max_strength) = (None, None)
if strength in ['', None]:
[(strength, max_strength)] = altstrength_pattern.findall(output)
try:
[(strength, max_strength)] = altstrength_pattern.findall(output)
except ValueError:
# if the pattern was unable to match anything
# we'll return 101, which will allow us to stay
# connected even though we don't know the strength
# it also allows us to tell if
return 101
if strength not in ['', None] and max_strength:
return (100 * int(strength) // int(max_strength))
elif strength not in ["", None]:
@@ -1309,9 +1391,7 @@ class BaseWirelessInterface(BaseInterface):
"""
if not iwconfig:
cmd = 'iwconfig ' + self.iface
if self.verbose: print cmd
output = misc.Run(cmd)
output = self.GetIwconfig()
else:
output = iwconfig
return self._get_link_quality(output)
@@ -1325,9 +1405,7 @@ class BaseWirelessInterface(BaseInterface):
"""
if not iwconfig:
cmd = 'iwconfig ' + self.iface
if self.verbose: print cmd
output = misc.Run(cmd)
output = self.GetIwconfig()
else:
output = iwconfig
signaldbm_pattern = re.compile('.*Signal level:?=? ?(-\d\d*)',
@@ -1344,9 +1422,7 @@ class BaseWirelessInterface(BaseInterface):
"""
if not iwconfig:
cmd = 'iwconfig ' + self.iface
if self.verbose: print cmd
output = misc.Run(cmd)
output = self.GetIwconfig()
else:
output = iwconfig
network = misc.RunRegex(re.compile('.*ESSID:"(.*?)"',