From 59d282ee6e24f6549cabce0947a3cee17c97e000 Mon Sep 17 00:00:00 2001
From: imdano <>
Date: Sat, 6 Sep 2008 16:54:53 +0000
Subject: [PATCH] experimental: - Merge in changes from pluggablebackends.
---
wicd/__init__.py | 0
wicd/backend.py | 97 +++
wicd/backends/be-external.py | 491 ++++++++++++
wicd/backends/be-ioctl.py | 538 ++++++++++++++
wicd/configmanager.py | 102 +++
wicd/configscript.py | 11 +-
wicd/gui.py | 75 +-
wicd/logfile.py | 4 +
wicd/misc.py | 30 +-
wicd/monitor.py | 69 +-
wicd/netentry.py | 99 +--
wicd/networking.py | 144 ++--
wicd/prefs.py | 41 +-
wicd/{wicd.py => wicd-client.py} | 112 +--
wicd/{daemon.py => wicd-daemon.py} | 1111 ++++++++++++++--------------
wicd/wnettools.py | 572 ++------------
wicd/wpath.py | 50 +-
17 files changed, 2217 insertions(+), 1329 deletions(-)
create mode 100644 wicd/__init__.py
create mode 100644 wicd/backend.py
create mode 100644 wicd/backends/be-external.py
create mode 100644 wicd/backends/be-ioctl.py
create mode 100644 wicd/configmanager.py
rename wicd/{wicd.py => wicd-client.py} (89%)
rename wicd/{daemon.py => wicd-daemon.py} (72%)
diff --git a/wicd/__init__.py b/wicd/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/wicd/backend.py b/wicd/backend.py
new file mode 100644
index 0000000..5221dda
--- /dev/null
+++ b/wicd/backend.py
@@ -0,0 +1,97 @@
+#!/usr/bin/env python
+
+""" Backend manager for wicd.
+
+Manages and loads the pluggable backends for wicd.
+
+"""
+
+#
+# Copyright (C) 2007 Adam Blackburn
+# Copyright (C) 2007 Dan O'Reilly
+# Copyright (C) 2007 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
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+#
+
+
+import sys
+import os
+
+import wicd.wpath as wpath
+
+
+class BackendManager(object):
+ def __init__(self):
+ """ Initialize the backend manager. """
+ self.backend_dir = wpath.backends
+ self.__loaded_backend = None
+
+ def _valid_backend_file(self, be_file):
+ """ Make sure the backend file is valid. """
+ return (os.access(be_file, os.F_OK) and
+ os.path.basename(be_file).startswith("be-") and
+ be_file.endswith(".py"))
+
+ def get_current_backend(self):
+ if self.__loaded_backend and not self.__loaded_backend is None:
+ return self.__loaded_backend.NAME
+ else:
+ return None
+
+ def get_available_backends(self):
+ """ Returns a list of all valid backends in the backend directory. """
+ be_list = [""]
+ for f in os.listdir(self.backend_dir):
+ if self._valid_backend_file(os.path.join(self.backend_dir, f)):
+ be_list.append(f[3:-3])
+ return be_list
+
+ def load_backend(self, backend_name):
+ """ Load and return a backend module.
+
+ Given a backend name be-foo, attempt to load a python module
+ in the backends directory called be-foo.py. The module must
+ include a certain set of classes and variables to be considered
+ valid.
+
+ """
+ def fail(backend_name, reason):
+ print "Failed to load backend %s: %s" % (backend_name, reason)
+
+ print 'trying to load backend %s' % backend_name
+ backend_path = os.path.join(self.backend_dir,
+ 'be-' + backend_name + '.py')
+ if self._valid_backend_file(backend_path):
+ sys.path.insert(0, self.backend_dir)
+ backend = __import__('be-' + backend_name)
+ else:
+ fail(backend_name, 'Invalid backend file.')
+ return None
+
+ if not backend.NAME:
+ fail(backend_name, 'Missing NAME declaration.')
+ return None
+
+ if not backend.WiredInterface:
+ fail(backend_name, "Missing WiredInterface class")
+ return None
+
+ if not backend.WirelessInterface:
+ fail(backend_name, "Missing WirelessInterface class")
+ return None
+
+ self.__loaded_backend = backend
+ print 'successfully loaded backend %s' % backend_name
+ return backend
+
diff --git a/wicd/backends/be-external.py b/wicd/backends/be-external.py
new file mode 100644
index 0000000..b1c6fb8
--- /dev/null
+++ b/wicd/backends/be-external.py
@@ -0,0 +1,491 @@
+#!/usr/bin/env python
+
+""" Network interface control tools for wicd.
+
+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.
+
+"""
+
+#
+# Copyright (C) 2007 Adam Blackburn
+# Copyright (C) 2007 Dan O'Reilly
+# Copyright (C) 2007 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
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+#
+
+import wicd.misc as misc
+import wicd.wnettools as wnettools
+
+import re
+import os
+import wicd.wpath as wpath
+import time
+
+
+NAME = "external"
+DESCRIPTION = """External app (slow) backend
+
+This backend uses external program calls like ifconfig and
+iwconfig to query network information. This makes it a bit
+slower and more CPU intensive than the ioctl backend, but
+it doesn't require any thirdy party libraries and may be
+more stable for some set ups.
+"""
+
+# Compile the regex patterns that will be used to search the output of iwlist
+# scan for info these are well tested, should work on most cards
+essid_pattern = re.compile('.*ESSID:"(.*?)"\n', re.I | re.M | re.S)
+ap_mac_pattern = re.compile('.*Address: (.*?)\n', re.I | re.M | re.S)
+channel_pattern = re.compile('.*Channel:? ?(\d\d?)', re.I | re.M | re.S)
+strength_pattern = re.compile('.*Quality:?=? ?(\d+)\s*/?\s*(\d*)', re.I | re.M | re.S)
+# These next two look a lot a like, altstrength is for Signal level = xx/100,
+# which is just an alternate way of displaying link quality, signaldbm is
+# for displaying actual signal strength (-xx dBm).
+altstrength_pattern = re.compile('.*Signal level:?=? ?(\d\d*)', re.I | re.M | re.S)
+signaldbm_pattern = re.compile('.*Signal level:?=? ?(-\d\d*)', re.I | re.M | re.S)
+mode_pattern = re.compile('.*Mode:(.*?)\n', re.I | re.M | re.S)
+freq_pattern = re.compile('.*Frequency:(.*?)\n', re.I | re.M | re.S)
+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.I | re.M | re.S)
+
+wep_pattern = re.compile('.*Encryption key:(.*?)\n', re.I | re.M | re.S)
+altwpa_pattern = re.compile('(wpa_ie)', re.I | re.M | re.S)
+wpa1_pattern = re.compile('(WPA Version 1)', re.I | re.M | re.S)
+wpa2_pattern = re.compile('(WPA2)', re.I | re.M | re.S)
+
+# Patterns for wpa_cli output
+auth_pattern = re.compile('.*wpa_state=(.*?)\n', re.I | re.M | re.S)
+
+RALINK_DRIVER = 'ralink legacy'
+
+
+def SetDNS(dns1=None, dns2=None, dns3=None):
+ return wnettools.SetDNS(dns1, dns2, dns3)
+
+def GetDefaultGateway():
+ return wnettools.GetDefaultGateway()
+
+def StopDHCP():
+ return wnettools.StopDHCP()
+
+def GetWirelessInterfaces():
+ return wnettools.GetWirelessInterfaces()
+
+def GetWiredInterfaces():
+ return wnettools.GetWiredInterfaces()
+
+def NeedsExternalCalls():
+ return True
+
+
+class Interface(wnettools.BaseInterface):
+ """ Control a network interface. """
+ def __init__(self, iface, verbose=False):
+ """ Initialise the object.
+
+ Keyword arguments:
+ iface -- the name of the interface
+ verbose -- whether to print every command run
+
+ """
+ wnettools.BaseInterface.__init__(self, iface, verbose)
+ self.Check()
+
+ def GetIP(self, ifconfig=""):
+ """ Get the IP address of the interface.
+
+ Returns:
+ The IP address of the interface in dotted quad form.
+
+ """
+ if not ifconfig:
+ cmd = 'ifconfig ' + self.iface
+ if self.verbose: print cmd
+ output = misc.Run(cmd)
+ else:
+ output = ifconfig
+ return misc.RunRegex(ip_pattern, output)
+
+ def IsUp(self, ifconfig=None):
+ """ Determines if the interface is up.
+
+ Returns:
+ True if the interface is up, False otherwise.
+
+ """
+ if not ifconfig:
+ cmd = "ifconfig " + self.iface
+ if self.verbose: print cmd
+ output = misc.Run(cmd)
+ else:
+ output = ifconfig
+ lines = output.split('\n')
+ if len(lines) < 5:
+ return False
+
+ for line in lines[1:4]:
+ if line.strip().startswith('UP'):
+ return True
+
+ return False
+
+
+class WiredInterface(Interface, wnettools.BaseWiredInterface):
+ """ Control a wired network interface. """
+ def __init__(self, iface, verbose=False):
+ """ Initialise the wired network interface class.
+
+ Keyword arguments:
+ iface -- name of the interface
+ verbose -- print all commands
+
+ """
+ wnettools.BaseWiredInterface.__init__(self, iface, verbose)
+ Interface.__init__(self, iface, verbose)
+
+ def GetPluggedIn(self):
+ """ Get the current physical connection state.
+
+ The method will first attempt to use ethtool do determine
+ physical connection state. Should ethtool fail to run properly,
+ mii-tool will be used instead.
+
+ Returns:
+ True if a link is detected, False otherwise.
+
+ """
+ if not self.iface:
+ return False
+ if self.ETHTOOL_FOUND and self.link_detect != misc.MIITOOL:
+ return self._eth_get_plugged_in()
+ elif self.MIITOOL_FOUND:
+ return self._mii_get_plugged_in()
+ else:
+ print 'Error: No way of checking for a wired connection. Make \
+ sure that either mii-tool or ethtool is installed.'
+ return False
+
+ def _eth_get_plugged_in(self):
+ """ Use ethtool to determine the physical connection state.
+
+ Returns:
+ True if a link is detected, False otherwise.
+
+ """
+ link_tool = 'ethtool'
+ if not self.IsUp():
+ print 'Wired Interface is down, putting it up'
+ self.Up()
+ time.sleep(6)
+ tool_data = misc.Run(link_tool + ' ' + self.iface, True)
+ if misc.RunRegex(re.compile('(Link detected: yes)', re.I | re.M |
+ re.S), tool_data) is not None:
+ return True
+ else:
+ return False
+
+ def _mii_get_plugged_in(self):
+ """ Use mii-tool to determine the physical connection state.
+
+ Returns:
+ True if a link is detected, False otherwise.
+
+ """
+ link_tool = 'mii-tool'
+ tool_data = misc.Run(link_tool + ' ' + self.iface, True)
+ if misc.RunRegex(re.compile('(Invalid argument)', re.I | re.M | re.S),
+ tool_data) is not None:
+ print 'Wired Interface is down, putting it up'
+ self.Up()
+ time.sleep(4)
+ tool_data = misc.Run(link_tool + ' ' + self.iface, True)
+
+ if misc.RunRegex(re.compile('(link ok)', re.I | re.M | re.S),
+ tool_data) is not None:
+ return True
+ else:
+ return False
+
+
+class WirelessInterface(Interface, wnettools.BaseWirelessInterface):
+ """ Control a wireless network interface. """
+ def __init__(self, iface, verbose=False, wpa_driver='wext'):
+ """ Initialise the wireless network interface class.
+
+ Keyword arguments:
+ iface -- name of the interface
+ verbose -- print all commands
+
+ """
+ wnettools.BaseWirelessInterface.__init__(self, iface, verbose,
+ wpa_driver)
+ Interface.__init__(self, iface, verbose)
+
+ def GetNetworks(self):
+ """ Get a list of available wireless networks.
+
+ Returns:
+ A list containing available wireless networks.
+
+ """
+ cmd = 'iwlist ' + self.iface + ' scan'
+ if self.verbose: print cmd
+ results = misc.Run(cmd)
+
+ # Split the networks apart, using Cell as our split point
+ # this way we can look at only one network at a time.
+ # The spaces around ' Cell ' are to minimize the chance that someone
+ # has an essid named Cell...
+ networks = results.split( ' Cell ' )
+
+ # Get available network info from iwpriv get_site_survey
+ # if we're using a ralink card (needed to get encryption info)
+ if self.wpa_driver == RALINK_DRIVER:
+ ralink_info = self._GetRalinkInfo()
+ else:
+ ralink_info = None
+
+ # An array for the 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)
+
+ return access_points
+
+ def _ParseAccessPoint(self, cell, ralink_info):
+ """ Parse a single cell from the output of iwlist.
+
+ Keyword arguments:
+ cell -- string containing the cell information
+ ralink_info -- string contating network information needed
+ for ralink cards.
+
+ Returns:
+ A dictionary containing the cell networks properties.
+
+ """
+ ap = {}
+ # ESSID - Switch '' to 'Hidden' to remove
+ # brackets that can mix up formatting.
+ ap['essid'] = misc.RunRegex(essid_pattern, cell)
+ try:
+ ap['essid'] = misc.to_unicode(ap['essid'])
+ except (UnicodeDecodeError, UnicodeEncodeError):
+ print 'Unicode problem with current network essid, ignoring!!'
+ return None
+ if ap['essid'] in ['', ""]:
+ ap['essid'] = 'Hidden'
+ ap['hidden'] = True
+ else:
+ ap['hidden'] = False
+
+ # Channel - For cards that don't have a channel number,
+ # convert the frequency.
+ ap['channel'] = misc.RunRegex(channel_pattern, cell)
+ if ap['channel'] == None:
+ freq = misc.RunRegex(freq_pattern, cell)
+ ap['channel'] = self._FreqToChannel(freq)
+
+ # BSSID
+ ap['bssid'] = misc.RunRegex(ap_mac_pattern, cell)
+
+ # Mode
+ ap['mode'] = misc.RunRegex(mode_pattern, cell)
+
+ # Break off here if we're using a ralink card
+ if self.wpa_driver == RALINK_DRIVER:
+ ap = self._ParseRalinkAccessPoint(ap, ralink_info, cell)
+ elif misc.RunRegex(wep_pattern, cell) == 'on':
+ # Encryption - Default to WEP
+ ap['encryption'] = True
+ ap['encryption_method'] = 'WEP'
+
+ if misc.RunRegex(wpa1_pattern, cell) == 'WPA Version 1':
+ ap['encryption_method'] = 'WPA'
+
+ if misc.RunRegex(altwpa_pattern, cell) == 'wpa_ie':
+ ap['encryption_method'] = 'WPA'
+
+ if misc.RunRegex(wpa2_pattern, cell) == 'WPA2':
+ ap['encryption_method'] = 'WPA2'
+ else:
+ ap['encryption'] = False
+
+ # Link Quality
+ # Set strength to -1 if the quality is not found
+
+ # more of the patch from
+ # https://bugs.launchpad.net/wicd/+bug/175104
+ if (strength_pattern.match(cell)):
+ [(strength, max_strength)] = strength_pattern.findall(cell)
+ if max_strength:
+ ap["quality"] = 100 * int(strength) // int(max_strength)
+ else:
+ ap["quality"] = int(strength)
+ elif misc.RunRegex(altstrength_pattern,cell):
+ ap['quality'] = misc.RunRegex(altstrength_pattern, cell)
+ else:
+ ap['quality'] = -1
+
+ # Signal Strength (only used if user doesn't want link
+ # quality displayed or it isn't found)
+ if misc.RunRegex(signaldbm_pattern, cell):
+ ap['strength'] = misc.RunRegex(signaldbm_pattern, cell)
+ elif self.wpa_driver != RALINK_DRIVER: # This is already set for ralink
+ ap['strength'] = -1
+
+ return ap
+
+ def ValidateAuthentication(self, auth_time):
+ """ Validate WPA authentication.
+
+ Validate that the wpa_supplicant authentication
+ process was successful.
+
+ NOTE: It's possible this could return False,
+ though in reality wpa_supplicant just isn't
+ finished yet.
+
+ Keyword arguments:
+ auth_time -- The time at which authentication began.
+
+ Returns:
+ True if wpa_supplicant authenticated succesfully,
+ False otherwise.
+
+ """
+ # Right now there's no way to do this for these drivers
+ if self.wpa_driver == RALINK_DRIVER or not self.WPA_CLI_FOUND:
+ return True
+
+ MAX_TIME = 15
+ MAX_DISCONNECTED_TIME = 3
+ while (time.time() - auth_time) < MAX_TIME:
+ cmd = 'wpa_cli -i ' + self.iface + ' status'
+ output = misc.Run(cmd)
+ result = misc.RunRegex(auth_pattern, output)
+ if self.verbose:
+ print 'WPA_CLI RESULT IS', result
+
+ if not result:
+ return False
+ if result == "COMPLETED":
+ return True
+ elif result == "DISCONNECTED" and \
+ (time.time() - auth_time) > MAX_DISCONNECTED_TIME:
+ # Force a rescan to get wpa_supplicant moving again.
+ self._ForceSupplicantScan()
+ MAX_TIME += 5
+ time.sleep(1)
+
+ print 'wpa_supplicant authentication may have failed.'
+ return False
+
+
+ def _ForceSupplicantScan(self):
+ """ Force wpa_supplicant to rescan available networks.
+
+ This function forces wpa_supplicant to rescan.
+ This works around authentication validation sometimes failing for
+ wpa_supplicant because it remains in a DISCONNECTED state for
+ quite a while, after which a rescan is required, and then
+ attempting to authenticate. This whole process takes a long
+ time, so we manually speed it up if we see it happening.
+
+ """
+ print 'wpa_supplicant rescan forced...'
+ cmd = 'wpa_cli -i' + self.iface + ' scan'
+ misc.Run(cmd)
+
+ 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)
+ else:
+ output = iwconfig
+
+ bssid = misc.RunRegex(bssid_pattern, output)
+ return bssid
+
+ def GetSignalStrength(self, iwconfig=None):
+ """ Get the signal strength of the current network.
+
+ Returns:
+ The signal strength.
+
+ """
+ if not iwconfig:
+ cmd = 'iwconfig ' + self.iface
+ if self.verbose: print cmd
+ output = misc.Run(cmd)
+ else:
+ output = iwconfig
+
+ [(strength, max_strength)] = strength_pattern.findall(output)
+ if max_strength and strength:
+ return 100 * int(strength) // int(max_strength)
+
+ if strength is None:
+ strength = misc.RunRegex(altstrength_pattern, output)
+
+ return strength
+
+ def GetDBMStrength(self, iwconfig=None):
+ """ Get the dBm signal strength of the current network.
+
+ Returns:
+ The dBm signal strength.
+
+ """
+ if not iwconfig:
+ cmd = 'iwconfig ' + self.iface
+ if self.verbose: print cmd
+ output = misc.Run(cmd)
+ else:
+ output = iwconfig
+ dbm_strength = misc.RunRegex(signaldbm_pattern, output)
+ return dbm_strength
+
+ def GetCurrentNetwork(self, iwconfig=None):
+ """ Get the essid of the current network.
+
+ Returns:
+ The current network essid.
+
+ """
+ if not iwconfig:
+ cmd = 'iwconfig ' + self.iface
+ if self.verbose: print cmd
+ output = misc.Run(cmd)
+ else:
+ output = iwconfig
+ network = misc.RunRegex(re.compile('.*ESSID:"(.*?)"',
+ re.I | re.M | re.S), output)
+ if network:
+ network = misc.to_unicode(network)
+ return network
diff --git a/wicd/backends/be-ioctl.py b/wicd/backends/be-ioctl.py
new file mode 100644
index 0000000..3b53db0
--- /dev/null
+++ b/wicd/backends/be-ioctl.py
@@ -0,0 +1,538 @@
+#!/usr/bin/env python
+
+""" ioctl Network interface control tools for wicd.
+
+This module implements functions to control and obtain information from
+network interfaces. It utilizes ioctl calls and python modules to
+obtain this information whenever possible.
+
+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.
+
+"""
+
+#
+# Copyright (C) 2007 Adam Blackburn
+# Copyright (C) 2007 Dan O'Reilly
+# Copyright (C) 2007 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
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+#
+
+import wicd.misc as misc
+import wicd.wnettools as wnettools
+import wicd.wpath as wpath
+
+import iwscan
+import wpactrl
+
+import re
+import os
+import time
+import socket
+import fcntl
+import struct
+import array
+
+
+NAME = "ioctl"
+DESCRIPTION = """IOCTL (fast) backend
+
+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:
+python-wpactrl (http://projects.otaku42.de/wiki/PythonWpaCtrl)
+python-iwscan (http://projects.otaku42.de/browser/python-iwscan/)"""
+
+strength_pattern = re.compile('.*Quality:?=? ?(\d+)\s*/?\s*(\d*)',
+ re.I | re.M | re.S)
+altstrength_pattern = re.compile('.*Signal level:?=? ?(\d\d*)',
+ re.I | re.M | re.S)
+signaldbm_pattern = re.compile('.*Signal level:?=? ?(-\d\d*)',
+ re.I | re.M | re.S)
+wep_pattern = re.compile('.*Encryption key:(.*?)\n', re.I | re.M | re.S)
+
+RALINK_DRIVER = 'ralink legacy'
+
+# Got these from /usr/include/linux/wireless.h
+SIOCGIWESSID = 0x8B1B
+SIOCGIWRANGE = 0x8B0B
+SIOCGIWAP = 0x8B15
+SIOCGIWSTATS = 0x8B0F
+
+# Got these from /usr/include/sockios.h
+SIOCGIFADDR = 0x8915
+SIOCGIFHWADDR = 0x8927
+SIOCGMIIPHY = 0x8947
+SIOCETHTOOL = 0x8946
+SIOCGIFFLAGS = 0x8913
+
+def SetDNS(dns1=None, dns2=None, dns3=None):
+ return wnettools.SetDNS(dns1, dns2, dns3)
+
+def GetDefaultGateway():
+ return wnettools.GetDefaultGateway()
+
+def StopDHCP():
+ return wnettools.StopDHCP()
+
+def GetWirelessInterfaces():
+ return wnettools.GetWirelessInterfaces()
+
+def GetWiredInterfaces():
+ return wnettools.GetWiredInterfaces()
+
+def get_iw_ioctl_result(iface, call):
+ """ Makes the given ioctl call and returns the results.
+
+ Keyword arguments:
+ call -- The ioctl call to make
+
+ Returns:
+ The results of the ioctl call.
+
+ """
+ s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+ buff = array.array('c', '\0' * 32)
+ addr, length = buff.buffer_info()
+ arg = struct.pack('Pi', addr, length)
+ data = (iface + '\0' * 16)[:16] + arg
+ try:
+ result = fcntl.ioctl(s.fileno(), call, data)
+ except IOError:
+ return None
+ except OSError:
+ return None
+ return buff.tostring()
+
+def NeedsExternalCalls():
+ return False
+
+
+class Interface(wnettools.BaseInterface):
+ """ Control a network interface. """
+ def __init__(self, iface, verbose=False):
+ """ Initialise the object.
+
+ Keyword arguments:
+ iface -- the name of the interface
+ verbose -- whether to print every command run
+
+ """
+ wnettools.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
+
+ def GetIP(self, ifconfig=""):
+ """ Get the IP address of the interface.
+
+ Returns:
+ The IP address of the interface in dotted quad form.
+
+ """
+ ifstruct = struct.pack('256s', self.iface)
+ try:
+ raw_ip = fcntl.ioctl(self.sock.fileno(), SIOCGIFADDR, ifstruct)
+ except IOError:
+ return None
+ except OSError:
+ return None
+
+ return socket.inet_ntoa(raw_ip[20:24])
+
+ def IsUp(self):
+ """ Determines if the interface is up.
+
+ Returns:
+ True if the interface is up, False otherwise.
+
+ """
+ if not self.iface: return False
+ data = (self.iface + '\0' * 16)[:18]
+ try:
+ result = fcntl.ioctl(self.sock.fileno(), SIOCGIFFLAGS, data)
+ except IOError, e:
+ if self.verbose:
+ print "SIOCGIFFLAGS failed: " + str(e)
+ return False
+
+ flags, = struct.unpack('H', result[16:18])
+ return bool(flags & 1)
+
+
+class WiredInterface(Interface, wnettools.BaseWiredInterface):
+ """ Control a wired network interface. """
+ def __init__(self, iface, verbose=False):
+ """ Initialise the wired network interface class.
+
+ Keyword arguments:
+ iface -- name of the interface
+ verbose -- print all commands
+
+ """
+ wnettools.BaseWiredInterface.__init__(self, iface, verbose)
+ Interface.__init__(self, iface, verbose)
+
+ def GetPluggedIn(self):
+ """ Get the current physical connection state.
+
+ The method will first attempt to use ethtool do determine
+ physical connection state. Should ethtool fail to run properly,
+ mii-tool will be used instead.
+
+ Returns:
+ True if a link is detected, False otherwise.
+
+ """
+ if not self.iface: return False
+ if self.ETHTOOL_FOUND and self.link_detect != misc.MIITOOL:
+ return self._eth_get_plugged_in()
+ elif self.MIITOOL_FOUND:
+ return self._mii_get_plugged_in()
+ else:
+ print 'Error: No way of checking for a wired connection. Make \
+ sure that either mii-tool or ethtool is installed.'
+ return False
+
+ def _eth_get_plugged_in(self):
+ """ Use ethtool to determine the physical connection state.
+
+ Returns:
+ True if a link is detected, False otherwise.
+
+ """
+ if not self.IsUp():
+ self.Up()
+ time.sleep(5)
+ buff = array.array('i', [0x0000000a, 0x00000000])
+ addr, length = buff.buffer_info()
+ arg = struct.pack('Pi', addr, length)
+ data = (self.iface + '\0' * 16)[:16] + arg
+ try:
+ fcntl.ioctl(self.sock.fileno(), SIOCETHTOOL, data)
+ except IOError, e:
+ if self.verbose:
+ print 'SIOCETHTOOL failed: ' + str(e)
+ return False
+ return bool(buff.tolist()[1])
+
+ def _mii_get_plugged_in(self):
+ """ Use mii-tool to determine the physical connection state.
+
+ Returns:
+ True if a link is detected, False otherwise.
+
+ """
+ if not self.IsUp():
+ self.Up()
+ time.sleep(2.5)
+ buff = struct.pack('16shhhh', (self.iface + '\0' * 16)[:16], 0, 1,
+ 0x0004, 0)
+ try:
+ result = fcntl.ioctl(self.sock.fileno(), SIOCGMIIPHY, buff)
+ except IOError, e:
+ if self.verbose:
+ print 'SIOCGMIIPHY failed: ' + str(e)
+ return False
+ reg = struct.unpack('16shhhh', result)[-1]
+ return bool(reg & 0x0004)
+
+
+class WirelessInterface(Interface, wnettools.BaseWirelessInterface):
+ """ Control a wireless network interface. """
+ def __init__(self, iface, verbose=False, wpa_driver='wext'):
+ """ Initialise the wireless network interface class.
+
+ Keyword arguments:
+ iface -- name of the interface
+ verbose -- print all commands
+
+ """
+ wnettools.BaseWirelessInterface.__init__(self, iface, verbose,
+ wpa_driver)
+ Interface.__init__(self, iface, verbose)
+ self.scan_iface = None
+
+ def GetNetworks(self):
+ """ Get a list of available wireless networks.
+
+ Returns:
+ A list containing available wireless networks.
+
+ """
+ if not self.scan_iface:
+ self.scan_iface = iwscan.WirelessInterface(self.iface)
+ results = self.scan_iface.Scan()
+ return [self._parse_ap(cell) for cell in results]
+
+ def _parse_ap(self, cell):
+ """ Parse a single cell from the python-iwscan list. """
+ ap = {}
+ try:
+ ap['essid'] = misc.to_unicode(cell['essid'])
+ except UnicodeError:
+ print 'Unicode problem with the current network essid, ignoring!!'
+ return None
+
+ if ap['essid'] in [ "", '']:
+ ap['essid'] = 'Hidden'
+ ap['hidden'] = True
+ else:
+ ap['hidden'] = False
+
+ ap["channel"] = True and cell["channel"] or \
+ self._FreqToChannel(cell["frequency"])
+
+ ap["bssid"] = cell["bssid"]
+ ap["mode"] = cell["mode"]
+
+ if cell["enc"]:
+ ap["encryption"] = True
+ if cell["ie"]:
+ if "WPA2" in cell['ie']['type'].upper():
+ ap['encryption_method'] = 'WPA2'
+ elif "WPA" in cell['ie']['type'].upper():
+ ap['encryption_method'] = 'WPA'
+ else:
+ ap['encryption_method'] = 'WEP'
+ else:
+ ap["encryption"] = False
+
+ # Link Quality
+ ap['qual_found'] = True
+ try:
+ [(strength, max_strength)] = strength_pattern.findall(cell["stats"])
+ if max_strength:
+ ap["quality"] = 100 * int(strength) // int(max_strength)
+ else:
+ ap["quality"] = int(strength)
+ except ValueError:
+ ap['quality'] = misc.RunRegex(altstrength_pattern,cell["stats"])
+ if not ap['quality']:
+ ap['qual_found'] = False
+ ap['quality'] = -1
+
+ # Signal Strength (only used if user doesn't want link
+ # quality displayed or it isn't found)
+ if misc.RunRegex(signaldbm_pattern, cell["stats"]):
+ ap['strength'] = misc.RunRegex(signaldbm_pattern, cell["stats"])
+ elif self.wpa_driver != RALINK_DRIVER: # This is already set for ralink
+ ap['strength'] = -1
+
+ return ap
+
+ def ValidateAuthentication(self, auth_time):
+ """ Validate WPA authentication.
+
+ Validate that the wpa_supplicant authentication
+ process was successful.
+
+ NOTE: It's possible this could return False,
+ though in reality wpa_supplicant just isn't
+ finished yet.
+
+ Keyword arguments:
+ auth_time -- The time at which authentication began.
+
+ Returns:
+ True if wpa_supplicant authenticated succesfully,
+ False otherwise.
+
+ """
+ def error():
+ print "Unable to find ctrl_interface for wpa_supplicant. " + \
+ "Could not validate authentication."
+
+ # Right now there's no way to do this for ralink drivers
+ if self.wpa_driver == RALINK_DRIVER:
+ return True
+
+ ctrl_iface = '/var/run/wpa_supplicant'
+ try:
+ socket = [os.path.join(ctrl_iface, s) \
+ for s in os.listdir(ctrl_iface) if s == self.iface][0]
+ except OSError:
+ error()
+ return True
+
+ wpa = wpactrl.WPACtrl(socket)
+
+ MAX_TIME = 15
+ MAX_DISCONNECTED_TIME = 3
+ while (time.time() - auth_time) < MAX_TIME:
+ status = wpa.request("STATUS").split("\n")
+ if self.verbose:
+ print 'wpa_supplicant ctrl_interface status query is %s' % str(status)
+
+ try:
+ [result] = [l for l in status if l.startswith("wpa_state=")]
+ except ValueError:
+ return False
+
+ result = result
+ if result.endswith("COMPLETED"):
+ return True
+ elif result.endswith("DISCONNECTED") and \
+ (time.time() - auth_time) > MAX_DISCONNECTED_TIME:
+ # Force a rescan to get wpa_supplicant moving again.
+ wpa.request("SCAN")
+ MAX_TIME += 5
+ time.sleep(1)
+
+ print 'wpa_supplicant authentication may have failed.'
+ return False
+
+ def _AuthenticateRalinkLegacy(self, network):
+ """ Authenticate with the specified wireless network.
+
+ This function handles Ralink legacy cards that cannot use
+ wpa_supplicant.
+
+ Keyword arguments:
+ network -- dictionary containing network info
+
+ """
+ if network.get('key') != None:
+ lines = self._GetRalinkInfo()
+ for x in lines:
+ info = x.split()
+ if len(info) < 5:
+ break
+ if info[2] == network.get('essid'):
+ if info[5] == 'WEP' or (info[5] == 'OPEN' and \
+ info[4] == 'WEP'):
+ print 'Setting up WEP'
+ cmd = ''.join(['iwconfig ', self.iface, ' key ',
+ network.get('key')])
+ if self.verbose: print cmd
+ misc.Run(cmd)
+ else:
+ if info[5] == 'SHARED' and info[4] == 'WEP':
+ print 'Setting up WEP'
+ auth_mode = 'SHARED'
+ key_name = 'Key1'
+ elif info[5] == 'WPA-PSK':
+ print 'Setting up WPA-PSK'
+ auth_mode = 'WPAPSK'
+ key_name = 'WPAPSK'
+ elif info[5] == 'WPA2-PSK':
+ print 'Setting up WPA2-PSK'
+ auth_mode = 'WPA2PSK'
+ key_name = 'WPAPSK'
+ else:
+ print 'Unknown AuthMode, can\'t complete ' + \
+ 'connection process!'
+ return
+
+ cmd_list = []
+ cmd_list.append('NetworkType=' + info[6])
+ cmd_list.append('AuthMode=' + auth_mode)
+ cmd_list.append('EncrypType=' + info[4])
+ cmd_list.append('SSID=' + info[2])
+ cmd_list.append(key_name + '=' + network.get('key'))
+ if info[5] == 'SHARED' and info[4] == 'WEP':
+ cmd_list.append('DefaultKeyID=1')
+ cmd_list.append('SSID=' + info[2])
+
+ for cmd in cmd_list:
+ cmd = 'iwpriv ' + self.iface + ' '
+ if self.verbose: print cmd
+ misc.Run(cmd)
+
+ def GetBSSID(self):
+ """ Get the MAC address for the interface. """
+ if not self.iface: return ""
+ data = (self.iface + '\0' * 32)[:32]
+ try:
+ result = fcntl.ioctl(self.sock.fileno(), SIOCGIWAP, data)[16:]
+ except IOError, e:
+ if self.verbose:
+ print "SIOCGIWAP failed: " + str(e)
+ return ""
+ raw_addr = struct.unpack("xxBBBBBB", result[:8])
+ return "%02X:%02X:%02X:%02X:%02X:%02X" % raw_addr
+
+ def GetSignalStrength(self, iwconfig=None):
+ """ Get the signal strength of the current network.
+
+ Returns:
+ The signal strength.
+
+ """
+ if not self.iface: return -1
+ buff = get_iw_ioctl_result(self.iface, SIOCGIWSTATS)
+ strength = ord(buff[2])
+ max_strength = self._get_max_strength()
+ if strength and max_strength:
+ return 100 * int(strength) // int(max_strength)
+
+ return strength
+
+ def _get_max_strength(self):
+ """ Gets the maximum possible strength from the wireless driver. """
+ buff = array.array('c', '\0' * 700)
+ addr, length = buff.buffer_info()
+ arg = struct.pack('Pi', addr, length)
+ iwfreq = (self.iface + '\0' * 16)[:16] + arg
+ try:
+ result = fcntl.ioctl(self.sock.fileno(), SIOCGIWRANGE, iwfreq)
+ except IOError, e:
+ if self.verbose:
+ print "SIOCGIWRANGE failed: " + str(e)
+ return None
+ # This defines the iwfreq struct, used to get signal strength.
+ fmt = "iiihb6ii4B4Bi32i2i2i2i2i3h8h2b2bhi8i2b3h2i2ihB17x" + 32 * "ihbb"
+ size = struct.calcsize(fmt)
+ data = buff.tostring()
+ data = data[0:size]
+ values = struct.unpack(fmt, data)
+ return values[12]
+
+ def GetDBMStrength(self, iwconfig=None):
+ """ Get the dBm signal strength of the current network.
+
+ Returns:
+ The dBm signal strength.
+
+ """
+ if not self.iface: return -100
+ buff = misc.get_irwange_ioctl_result(self.iface, SIOCGIWSTATS)
+ if not buff:
+ return None
+
+ return str((ord(buff[3]) - 256))
+
+ def GetCurrentNetwork(self, iwconfig=None):
+ """ Get the essid of the current network.
+
+ Returns:
+ The current network essid.
+
+ """
+ if not self.iface: return ""
+ buff = get_iw_ioctl_result(self.iface, SIOCGIWESSID)
+ if not buff:
+ return None
+
+ return buff.strip('\x00')
+
diff --git a/wicd/configmanager.py b/wicd/configmanager.py
new file mode 100644
index 0000000..c049eae
--- /dev/null
+++ b/wicd/configmanager.py
@@ -0,0 +1,102 @@
+#!/usr/bin/env python
+
+""" Wicd Configuration Manager
+
+Wrapper around ConfigParser for wicd, though it should be
+reusable for other purposes as well.
+
+"""
+
+#
+# Copyright (C) 2007 Adam Blackburn
+# Copyright (C) 2007 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
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+#
+
+from ConfigParser import ConfigParser
+
+from wicd.misc import stringToNone
+
+
+class ConfigManager(ConfigParser):
+ """ A class that can be used to manage a given configuration file. """
+ def __init__(self, path):
+ ConfigParser.__init__(self)
+ self.config_file = path
+ self.read(path)
+
+ def __repr__(self):
+ return self.config_file
+
+ def __str__(self):
+ return self.config_file
+
+ def get_config(self):
+ return self.config_file
+
+ def set_option(self, section, option, value, save=False):
+ """ Wrapper around ConfigParser.set
+
+ Adds the option to write the config file change right away.
+
+ """
+ if not self.has_section(section):
+ self.add_section(section)
+
+ ConfigParser.set(self, section, str(option), str(value))
+ if save:
+ self.write()
+
+ def set(self, *args, **kargs):
+ self.set_option(*args, **kargs)
+
+ def get_option(self, section, option, default=None):
+ """ Wrapper around ConfigParser.get.
+
+ Automatically adds any missing sections, adds the ability
+ to write a default value, and if one is provided prints if
+ the default or a previously saved value is returned.
+
+ """
+ if not self.has_section(section):
+ self.add_section(section)
+
+ if self.has_option(section, option):
+ ret = ConfigParser.get(self, section, option)
+ if default:
+ print ''.join(['found ', option, ' in configuration ', ret])
+ else:
+ print ''.join(['did not find ', option,
+ ' in configuration, setting default ', str(default)])
+ self.set(section, option, str(default), save=True)
+ ret = default
+
+ # Try to intelligently handle the type of the return value.
+ try:
+ ret = int(ret)
+ except ValueError, TypeError:
+ ret = stringToNone(ret)
+ return ret
+
+ def get(self, *args, **kargs):
+ return self.get_option(*args, **kargs)
+
+ def write(self):
+ configfile = open(self.config_file, 'w')
+ ConfigParser.write(self, configfile)
+ configfile.close()
+
+ def remove_section(self,section):
+ if self.has_section(section):
+ ConfigParser.remove_section(self, section)
diff --git a/wicd/configscript.py b/wicd/configscript.py
index 1a9b188..590eb74 100755
--- a/wicd/configscript.py
+++ b/wicd/configscript.py
@@ -58,7 +58,6 @@ except Exception:
wireless = dbus.Interface(proxy_obj, 'org.wicd.daemon.wireless')
wired = dbus.Interface(proxy_obj, 'org.wicd.daemon.wired')
-config = dbus.Interface(proxy_obj, 'org.wicd.daemon.config')
wireless_conf = wpath.etc + 'wireless-settings.conf'
wired_conf = wpath.etc + 'wired-settings.conf'
@@ -132,8 +131,8 @@ def write_scripts(network, network_type, script_info):
con.set(network, "afterscript", script_info["post_entry"])
con.set(network, "disconnectscript", script_info["disconnect_entry"])
con.write(open(wired_conf, "w"))
- config.ReadWiredNetworkProfile(network)
- config.SaveWiredNetworkProfile(network)
+ wired.ReadWiredNetworkProfile(network)
+ wired.SaveWiredNetworkProfile(network)
else:
bssid = wireless.GetWirelessProperty(int(network), "bssid")
con.read(wireless_conf)
@@ -143,8 +142,8 @@ def write_scripts(network, network_type, script_info):
con.set(bssid, "afterscript", script_info["post_entry"])
con.set(bssid, "disconnectscript", script_info["disconnect_entry"])
con.write(open(wireless_conf, "w"))
- config.ReadWirelessNetworkProfile(int(network))
- config.SaveWirelessNetworkProfile(int(network))
+ wireless.ReadWirelessNetworkProfile(int(network))
+ wireless.SaveWirelessNetworkProfile(int(network))
def main (argv):
""" Runs the script configuration dialog. """
@@ -157,7 +156,7 @@ def main (argv):
script_info = get_script_info(network, network_type)
- gladefile = wpath.etc + "wicd.glade"
+ gladefile = wpath.share + "wicd.glade"
wTree = gtk.glade.XML(gladefile)
dialog = wTree.get_widget("configure_script_dialog")
wTree.get_widget("pre_label").set_label(language['before_script'] + ":")
diff --git a/wicd/gui.py b/wicd/gui.py
index 290f562..26e3801 100644
--- a/wicd/gui.py
+++ b/wicd/gui.py
@@ -34,9 +34,9 @@ import gtk.glade
from dbus import DBusException
from dbus import version as dbus_version
-import wicd.misc
-import wicd.wpath
-from wicd.misc import noneToString, noneToBlankString, stringToBoolean, checkboxTextboxToggle
+from wicd import misc
+from wicd import wpath
+from wicd.misc import noneToString
from wicd.netentry import WiredNetworkEntry, WirelessNetworkEntry
from wicd.prefs import PreferencesDialog
from wicd.dbusmanager import DBusManager
@@ -56,12 +56,11 @@ else:
from dbus.mainloop.glib import DBusGMainLoop
DBusGMainLoop(set_as_default=True)
-proxy_obj, daemon, wireless, wired, bus, config = [None for x in
- range(0, 6)]
+proxy_obj, daemon, wireless, wired, bus = [None for x in range(0, 5)]
language = misc.get_language_list_gui()
def setup_dbus(dbus_man=None):
- global bus, daemon, wireless, wired, config, dbus_manager
+ global bus, daemon, wireless, wired, dbus_manager
if dbus_man:
dbus_manager = dbus_man
else:
@@ -83,7 +82,6 @@ def setup_dbus(dbus_man=None):
daemon = dbus_ifaces['daemon']
wireless = dbus_ifaces['wireless']
wired = dbus_ifaces['wired']
- config = dbus_ifaces['config']
return True
@@ -94,6 +92,14 @@ def error(parent, message):
dialog.set_markup(message)
dialog.run()
dialog.destroy()
+
+def alert(parent, message):
+ """ Shows an error dialog """
+ dialog = gtk.MessageDialog(parent, gtk.DIALOG_MODAL, gtk.MESSAGE_WARNING,
+ gtk.BUTTONS_OK)
+ dialog.set_markup(message)
+ dialog.run()
+ dialog.destroy()
########################################
##### GTK EXTENSION CLASSES
@@ -202,7 +208,7 @@ class WiredProfileChooser:
response = dialog.run()
if response == 1:
print 'reading profile ', wired_profiles.get_active_text()
- config.ReadWiredNetworkProfile(wired_profiles.get_active_text())
+ wired.ReadWiredNetworkProfile(wired_profiles.get_active_text())
wired.ConnectWired()
else:
if stoppopcheckbox.get_active():
@@ -217,10 +223,10 @@ class appGui(object):
if not standalone:
setup_dbus(dbus_man)
- gladefile = "data/wicd.glade"
+ gladefile = wpath.share + "wicd.glade"
self.wTree = gtk.glade.XML(gladefile)
- dic = { "refresh_clicked" : self.refresh_networks,
+ dic = { "refresh_clicked" : self.refresh_clicked,
"quit_clicked" : self.exit,
"disconnect_clicked" : self.disconnect_all,
"main_exit" : self.exit,
@@ -258,7 +264,6 @@ class appGui(object):
self.standalone = standalone
self.wpadrivercombo = None
self.connecting = False
- self.fast = True # Use ioctl instead of external program calls
self.prev_state = None
self.refresh_networks(fresh=False)
@@ -274,7 +279,7 @@ class appGui(object):
else:
self.wTree.get_widget("iface_menu_enable_wired").hide()
- size = config.ReadWindowSize("main")
+ size = daemon.ReadWindowSize("main")
width = size[0]
height = size[1]
if width > -1 and height > -1:
@@ -449,7 +454,7 @@ class appGui(object):
if not self.is_visible:
return True
- fast = self.fast
+ fast = not daemon.NeedsExternalCalls()
wired_connecting = wired.CheckIfWiredConnecting()
wireless_connecting = wireless.CheckIfWirelessConnecting()
self.connecting = wired_connecting or wireless_connecting
@@ -467,7 +472,7 @@ class appGui(object):
iwconfig = wireless.GetIwconfig()
else:
iwconfig = ''
- self.set_status(wireless.GetCurrentNetwork(iwconfig, fast) + ': ' +
+ self.set_status(wireless.GetCurrentNetwork(iwconfig) + ': ' +
language[str(wireless.CheckWirelessConnectingMessage())])
if wired_connecting:
self.set_status(language['wired_network'] + ': ' +
@@ -484,14 +489,13 @@ class appGui(object):
self.status_bar.remove(1, self.statusID)
# Determine connection status.
- if self.check_for_wired(wired.GetWiredIP(fast)):
+ if self.check_for_wired(wired.GetWiredIP("")):
return True
if not fast:
iwconfig = wireless.GetIwconfig()
else:
iwconfig = ''
- if self.check_for_wireless(iwconfig,
- wireless.GetWirelessIP(fast)):
+ if self.check_for_wireless(iwconfig, wireless.GetWirelessIP("")):
return True
self.set_status(language['not_connected'])
return True
@@ -510,9 +514,10 @@ class appGui(object):
def check_for_wired(self, wired_ip):
""" Determine if wired is active, and if yes, set the status. """
- if wired_ip and wired.CheckPluggedIn(self.fast):
- self.set_status(language['connected_to_wired'].replace('$A',
- wired_ip))
+ if wired_ip and wired.CheckPluggedIn():
+ self.set_status(
+ language['connected_to_wired'].replace('$A',wired_ip)
+ )
return True
else:
return False
@@ -522,15 +527,15 @@ class appGui(object):
if not wireless_ip:
return False
- network = wireless.GetCurrentNetwork(iwconfig, self.fast)
+ network = wireless.GetCurrentNetwork(iwconfig)
if not network:
return False
network = str(network)
if daemon.GetSignalDisplayType() == 0:
- strength = wireless.GetCurrentSignalStrength(iwconfig, self.fast)
+ strength = wireless.GetCurrentSignalStrength(iwconfig)
else:
- strength = wireless.GetCurrentDBMStrength(iwconfig, self.fast)
+ strength = wireless.GetCurrentDBMStrength(iwconfig)
if strength is None:
return False
@@ -549,15 +554,19 @@ class appGui(object):
def dbus_scan_finished(self):
""" Calls for a non-fresh update of the gui window.
- This method is called after the daemon runs an automatic
- rescan.
+ This method is called after a wireless scan is completed.
"""
if not self.connecting:
self.refresh_networks(fresh=False)
def dbus_scan_started(self):
+ """ Called when a wireless scan starts. """
self.network_list.set_sensitive(False)
+
+ def refresh_clicked(self, widget=None):
+ def dummy(x=None):pass
+ wireless.Scan(reply_handler=dummy, error_handler=dummy)
def refresh_networks(self, widget=None, fresh=True, hidden=None):
""" Refreshes the network list.
@@ -579,7 +588,7 @@ class appGui(object):
z.destroy()
del z
- if wired.CheckPluggedIn(self.fast) or wired.GetAlwaysShowWiredInterface():
+ if wired.CheckPluggedIn() or daemon.GetAlwaysShowWiredInterface():
printLine = True # In this case we print a separator.
wirednet = WiredNetworkEntry(dbus_manager.get_dbus_ifaces())
self.network_list.pack_start(wirednet, False, False)
@@ -691,7 +700,7 @@ class appGui(object):
entry.set_net_prop("dns1", '')
entry.set_net_prop("dns2", '')
entry.set_net_prop("dns3", '')
- config.SaveWiredNetworkProfile(entry.prof_name)
+ wired.SaveWiredNetworkProfile(entry.prof_name)
return True
def save_wireless_settings(self, networkid, entry, netent):
@@ -758,9 +767,9 @@ class appGui(object):
entry.set_net_prop('use_settings_globally', True)
else:
entry.set_net_prop('use_settings_globally', False)
- config.RemoveGlobalEssidEntry(networkid)
+ wireless.RemoveGlobalEssidEntry(networkid)
- config.SaveWirelessNetworkProfile(networkid)
+ wireless.SaveWirelessNetworkProfile(networkid)
return True
def edit_advanced(self, widget, event, ttype, networkid, networkentry):
@@ -864,7 +873,7 @@ class appGui(object):
"""
self.window.hide()
[width, height] = self.window.get_size()
- config.WriteWindowSize(width, height, "main")
+ daemon.WriteWindowSize(width, height, "main")
if self.standalone:
self.window.destroy()
@@ -895,9 +904,9 @@ if __name__ == '__main__':
setup_dbus()
app = appGui(standalone=True)
bus.add_signal_receiver(app.dbus_scan_finished, 'SendEndScanSignal',
- 'org.wicd.daemon')
+ 'org.wicd.daemon.wireless')
bus.add_signal_receiver(app.dbus_scan_started, 'SendStartScanSignal',
- 'org.wicd.daemon')
+ 'org.wicd.daemon.wireless')
bus.add_signal_receiver(app.update_connect_buttons, 'StatusChanged',
- 'org.wicd.daemon')
+ 'org.wicd.daemon')
gtk.main()
diff --git a/wicd/logfile.py b/wicd/logfile.py
index 1dd2622..df9cf7a 100644
--- a/wicd/logfile.py
+++ b/wicd/logfile.py
@@ -23,6 +23,8 @@ import sys
import os
import time
+import wicd.wpath as wpath
+
class SizeError(IOError):
pass
@@ -89,6 +91,8 @@ class ManagedLog(object):
"""
def __init__(self, name, maxsize=360000, maxsave=3):
+ if not os.path.exists(os.path.dirname(name)):
+ os.makedirs(os.path.dirname(name))
self._lf = LogFile(name, "a", maxsize)
self.maxsave = maxsave
diff --git a/wicd/misc.py b/wicd/misc.py
index 1fc10be..26ea78b 100644
--- a/wicd/misc.py
+++ b/wicd/misc.py
@@ -21,12 +21,12 @@ import os
import locale
import gettext
import sys
-from subprocess import Popen, STDOUT, PIPE
-from copy import copy
+from subprocess import Popen, STDOUT, PIPE, call
import subprocess
import commands
-import wicd.wpath as wpath
+# wicd imports
+import wpath
if __name__ == '__main__':
wpath.chdir(__file__)
@@ -76,8 +76,8 @@ def Run(cmd, include_stderr=False, return_pipe=False):
else:
err = None
fds = False
-
- tmpenv = copy(os.environ)
+
+ tmpenv = os.environ.copy()
tmpenv["LC_ALL"] = "C"
tmpenv["LANG"] = "C"
f = Popen(cmd, shell=True, stdout=PIPE, stderr=err, close_fds=fds,
@@ -89,11 +89,15 @@ def Run(cmd, include_stderr=False, return_pipe=False):
return f.communicate()[0]
def LaunchAndWait(cmd):
- """ Launches the given program with the given arguments, then blocks. """
- subprocess.call(cmd)
+ """ Launches the given program with the given arguments, then blocks.
+
+ cmd : A list contained the program name and its arguments.
+
+ """
+ call(cmd)
def IsValidIP(ip):
- """ Make sure an entered IP is valid """
+ """ Make sure an entered IP is valid. """
if ip != None:
if ip.count('.') == 3:
ipNumbers = ip.split('.')
@@ -167,7 +171,7 @@ def ParseEncryption(network):
and creating a config file for it
"""
- enctemplate = open("encryption/templates/" + network["enctype"])
+ enctemplate = open(wpath.encryption + network["enctype"])
template = enctemplate.readlines()
# Set these to nothing so that we can hold them outside the loop
z = "ap_scan=1\n"
@@ -206,7 +210,7 @@ def LoadEncryptionMethods():
encryptionTypes = []
try:
- enctypes = open("encryption/templates/active","r").readlines()
+ enctypes = open(wpath.encryption + "active","r").readlines()
except IOError, e:
print "Fatal Error: template index file is missing."
raise IOError(e)
@@ -215,7 +219,7 @@ def LoadEncryptionMethods():
for x in enctypes:
x = x.strip()
try:
- f = open("encryption/templates/" + x, "r")
+ f = open(wpath.encryption + x, "r")
except IOError:
print 'Failed to load encryption type ' + str(x)
continue
@@ -424,6 +428,8 @@ def get_language_list_gui():
language["dhcp_client"] = _("DHCP Client")
language["wired_detect"] = _("Wired Link Detection")
language["route_flush"] = _("Route Table Flushing")
+ language["backend"] = _("Backend")
+ language["backend_alert"] = _("Changes to your backend won't occur until the daemon is restarted.")
language['0'] = _('0')
language['1'] = _('1')
@@ -467,7 +473,7 @@ def get_language_list_tray():
language['connecting'] = _('Connecting')
language['wired'] = _('Wired Network')
language['scanning'] = _('Scanning')
-
+ language['no_wireless_networks_found'] = _('No wireless networks found.')
return language
def noneToBlankString(text):
diff --git a/wicd/monitor.py b/wicd/monitor.py
index 25da3f3..f49a6bb 100755
--- a/wicd/monitor.py
+++ b/wicd/monitor.py
@@ -41,9 +41,14 @@ misc.RenameProcess("wicd-monitor")
if __name__ == '__main__':
wpath.chdir(__file__)
-proxy_obj = dbus.SystemBus().get_object('org.wicd.daemon', '/org/wicd/daemon')
+bus = dbus.SystemBus()
+proxy_obj = bus.get_object('org.wicd.daemon', '/org/wicd/daemon')
daemon = dbus.Interface(proxy_obj, 'org.wicd.daemon')
+
+proxy_obj = bus.get_object('org.wicd.daemon', '/org/wicd/daemon/wired')
wired = dbus.Interface(proxy_obj, 'org.wicd.daemon.wired')
+
+proxy_obj = bus.get_object('org.wicd.daemon', '/org/wicd/daemon/wireless')
wireless = dbus.Interface(proxy_obj, 'org.wicd.daemon.wireless')
class ConnectionStatus(object):
@@ -61,9 +66,6 @@ class ConnectionStatus(object):
self.reconnect_tries = 0
self.last_reconnect_time = time.time()
self.signal_changed = False
-
- # This determines if we use ioctl or external programs
- self.fast = True
self.iwconfig = ""
def check_for_wired_connection(self, wired_ip):
@@ -74,7 +76,7 @@ class ConnectionStatus(object):
"""
- if wired_ip and wired.CheckPluggedIn(self.fast):
+ if wired_ip and wired.CheckPluggedIn():
# Only change the interface if it's not already set for wired
if not self.still_wired:
daemon.SetCurrentInterface(daemon.GetWiredInterface())
@@ -96,26 +98,15 @@ class ConnectionStatus(object):
# Make sure we have an IP before we do anything else.
if wireless_ip is None:
return False
-
- if self.fast:
- self.iwconfig = ''
- else:
+
+ if daemon.NeedsExternalCalls():
self.iwconfig = wireless.GetIwconfig()
+ else:
+ self.iwconfig = ''
# Reset this, just in case.
self.tried_reconnect = False
- # Try getting signal strength, and default to 0
- # if something goes wrong.
- try:
- if daemon.GetSignalDisplayType() == 0:
- wifi_signal = int(wireless.GetCurrentSignalStrength(self.iwconfig,
- self.fast))
- else:
- wifi_signal = int(wireless.GetCurrentDBMStrength(self.iwconfig,
- self.fast))
- except:
- wifi_signal = 0
-
+ wifi_signal = self._get_printable_sig_strength()
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),
@@ -123,6 +114,7 @@ class ConnectionStatus(object):
self.connection_lost_counter += 1
print self.connection_lost_counter
if self.connection_lost_counter >= 4:
+ wireless.DisconnectWireless()
self.connection_lost_counter = 0
return False
else: # If we have a signal, reset the counter
@@ -131,8 +123,7 @@ class ConnectionStatus(object):
# Only update if the signal strength has changed because doing I/O
# calls is expensive, and the icon flickers.
if (wifi_signal != self.last_strength or
- self.network != wireless.GetCurrentNetwork(self.iwconfig,
- self.fast)):
+ self.network != wireless.GetCurrentNetwork(self.iwconfig)):
self.last_strength = wifi_signal
self.signal_changed = True
daemon.SetCurrentInterface(daemon.GetWirelessInterface())
@@ -159,15 +150,14 @@ class ConnectionStatus(object):
# Determine what our current state is.
# Check for wired.
- wired_ip = wired.GetWiredIP(self.fast)
+ wired_ip = wired.GetWiredIP("")
wired_found = self.check_for_wired_connection(wired_ip)
if wired_found:
self.update_state(misc.WIRED, wired_ip=wired_ip)
return True
# Check for wireless
- wifi_ip = wireless.GetWirelessIP(self.fast)
- #self.iwconfig = wireless.GetIwconfig()
+ wifi_ip = wireless.GetWirelessIP("")
self.signal_changed = False
wireless_found = self.check_for_wireless_connection(wifi_ip)
if wireless_found:
@@ -194,7 +184,6 @@ class ConnectionStatus(object):
""" Set the current connection state. """
# Set our connection state/info.
iwconfig = self.iwconfig
- fast = self.fast
if state == misc.NOT_CONNECTED:
info = [""]
elif state == misc.SUSPENDED:
@@ -203,12 +192,12 @@ class ConnectionStatus(object):
if wired.CheckIfWiredConnecting():
info = ["wired"]
else:
- info = ["wireless", wireless.GetCurrentNetwork(iwconfig, fast)]
+ info = ["wireless", wireless.GetCurrentNetwork(iwconfig)]
elif state == misc.WIRELESS:
self.reconnect_tries = 0
- info = [wifi_ip, wireless.GetCurrentNetwork(iwconfig, fast),
- str(wireless.GetPrintableSignalStrength(iwconfig, fast)),
- str(wireless.GetCurrentNetworkID(iwconfig, fast))]
+ info = [wifi_ip, wireless.GetCurrentNetwork(iwconfig),
+ str(self._get_printable_sig_strength()),
+ str(wireless.GetCurrentNetworkID(iwconfig))]
elif state == misc.WIRED:
self.reconnect_tries = 0
info = [wired_ip]
@@ -223,6 +212,18 @@ class ConnectionStatus(object):
daemon.EmitStatusChanged(state, info)
self.last_state = state
return True
+
+ def _get_printable_sig_strength(self):
+ """ 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))
+ except TypeError:
+ wifi_signal = 0
+
+ return wifi_signal
def auto_reconnect(self, from_wireless=None):
""" Automatically reconnects to a network if needed.
@@ -250,7 +251,7 @@ class ConnectionStatus(object):
# If we just lost a wireless connection, try to connect to that
# network again. Otherwise just call Autoconnect.
- cur_net_id = wireless.GetCurrentNetworkID(self.iwconfig, self.fast)
+ cur_net_id = wireless.GetCurrentNetworkID(self.iwconfig)
if from_wireless and cur_net_id > -1:
print 'Trying to reconnect to last used wireless ' + \
'network'
@@ -278,7 +279,6 @@ def reply_handle():
def err_handle(error):
""" Just a dummy function needed for asynchronous dbus calls. """
pass
-
def main():
""" Starts the connection monitor.
@@ -289,8 +289,7 @@ def main():
"""
monitor = ConnectionStatus()
- gobject.timeout_add(2000, monitor.update_connection_status)
- #gobject.timeout_add(120000, monitor.rescan_networks)
+ gobject.timeout_add(2500, monitor.update_connection_status)
mainloop = gobject.MainLoop()
mainloop.run()
diff --git a/wicd/netentry.py b/wicd/netentry.py
index d0fece6..57ff513 100644
--- a/wicd/netentry.py
+++ b/wicd/netentry.py
@@ -16,15 +16,18 @@
#
import gtk
+import os
-import wicd.misc as misc
-from wicd.misc import noneToString, stringToNone, noneToBlankString, stringToBoolean
-import wicd.wpath as wpath
+import misc
+from misc import noneToString, stringToNone, noneToBlankString, stringToBoolean
+import wpath
language = misc.get_language_list_gui()
# These get set when a NetworkEntry is instantiated.
-daemon, wireless, wired, vpn_session, config = [None for x in range(0, 5)]
+daemon = None
+wired = None
+wireless = None
def error(parent, message):
""" Shows an error dialog """
@@ -219,7 +222,7 @@ class AdvancedSettingsDialog(gtk.Dialog):
self.txt_dns_2.set_sensitive(not self.chkbox_global_dns.get_active())
self.txt_dns_3.set_sensitive(not self.chkbox_global_dns.get_active())
- def destroy_called(self):
+ def destroy_called(self, *args):
""" Clean up everything.
This might look excessive, but it was the only way to prevent
@@ -264,7 +267,7 @@ class WiredSettingsDialog(AdvancedSettingsDialog):
""" Helper method to fetch and format wired properties. """
return noneToBlankString(wired.GetWiredProperty(label))
- def destroy_called(self):
+ def destroy_called(self, *args):
""" Clean up everything.
This might look excessive, but it was the only way to prevent
@@ -326,7 +329,7 @@ class WirelessSettingsDialog(AdvancedSettingsDialog):
self.combo_encryption.connect("changed", self.change_encrypt_method)
self.des = self.connect("destroy", self.destroy_called)
- def destroy_called(self):
+ def destroy_called(self, *args):
""" Clean up everything.
This might look excessive, but it was the only way to prevent
@@ -435,11 +438,10 @@ class NetworkEntry(gtk.HBox):
WirelessNetworkEntry classes.
"""
- global daemon, wired, wireless, config
+ global daemon, wired, wireless
daemon = dbus_ifaces["daemon"]
wired = dbus_ifaces["wired"]
wireless = dbus_ifaces["wireless"]
- config = dbus_ifaces["config"]
gtk.HBox.__init__(self, False, 2)
self.expander = gtk.Expander()
self.image = gtk.Image()
@@ -541,7 +543,7 @@ class WiredNetworkEntry(NetworkEntry):
# Build the profile list.
self.combo_profile_names = gtk.combo_box_entry_new_text()
- self.profile_list = config.GetWiredProfileList()
+ self.profile_list = wired.GetWiredProfileList()
if self.profile_list:
for x in self.profile_list:
self.combo_profile_names.append_text(x)
@@ -582,7 +584,7 @@ class WiredNetworkEntry(NetworkEntry):
# Display the default profile if it exists.
if self.profile_list is not None:
- prof = config.GetDefaultWiredNetwork()
+ prof = wired.GetDefaultWiredNetwork()
if prof != None: # Make sure the default profile gets displayed.
i = 0
while self.combo_profile_names.get_active_text() != prof:
@@ -624,22 +626,26 @@ class WiredNetworkEntry(NetworkEntry):
def edit_scripts(self, widget=None, event=None):
""" Launch the script editting dialog. """
profile = self.combo_profile_names.get_active_text()
- try:
- sudo_prog = misc.choose_sudo_prog()
- msg = "You must enter your password to configure scripts"
- if sudo_prog.endswith("gksu") or sudo_prog.endswith("ktsuss"):
- msg_flag = "-m"
- else:
- msg_flag = "--caption"
- misc.LaunchAndWait([sudo_prog, msg_flag, msg, "./configscript.py",
- profile, "wired"])
- except misc.WicdError:
- error("Could not find a graphical sudo program." + \
- " Script editor could not be launched.")
+ if os.getuid() != 0:
+ try:
+ sudo_prog = misc.choose_sudo_prog()
+ msg = "You must enter your password to configure scripts"
+ if sudo_prog.endswith("gksu") or sudo_prog.endswith("ktsuss"):
+ msg_flag = "-m"
+ else:
+ msg_flag = "--caption"
+ misc.LaunchAndWait([sudo_prog, msg_flag, msg,
+ wpath.lib + "configscript.py", profile,
+ "wired"])
+ except misc.WicdError:
+ error(None, "Could not find a graphical sudo program." + \
+ " Script editor could not be launched.")
+ else:
+ misc.LaunchAndWait([wpath.lib + "configscript.py", profile, "wired"])
def check_enable(self):
""" Disable objects if the profile list is empty. """
- profile_list = config.GetWiredProfileList()
+ profile_list = wired.GetWiredProfileList()
if profile_list == None:
self.button_delete.set_sensitive(False)
self.connect_button.set_sensitive(False)
@@ -659,13 +665,13 @@ class WiredNetworkEntry(NetworkEntry):
""" Add a profile to the profile list. """
print "adding profile"
profile_name = self.combo_profile_names.get_active_text()
- profile_list = config.GetWiredProfileList()
+ profile_list = wired.GetWiredProfileList()
if profile_list:
if profile_name in profile_list:
return False
if profile_name != "":
self.profile_help.hide()
- config.CreateWiredNetworkProfile(profile_name)
+ wired.CreateWiredNetworkProfile(profile_name)
self.combo_profile_names.prepend_text(profile_name)
self.combo_profile_names.set_active(0)
self.advanced_dialog.prof_name = profile_name
@@ -679,12 +685,12 @@ class WiredNetworkEntry(NetworkEntry):
""" Remove a profile from the profile list. """
print "removing profile"
profile_name = self.combo_profile_names.get_active_text()
- config.DeleteWiredNetworkProfile(profile_name)
+ wired.DeleteWiredNetworkProfile(profile_name)
self.combo_profile_names.remove_text(self.combo_profile_names.
get_active())
self.combo_profile_names.set_active(0)
self.advanced_dialog.prof_name = self.combo_profile_names.get_active_text()
- if not config.GetWiredProfileList():
+ if not wired.GetWiredProfileList():
self.profile_help.show()
entry = self.combo_profile_names.child
entry.set_text("")
@@ -700,10 +706,10 @@ class WiredNetworkEntry(NetworkEntry):
""" Change the default profile. """
if self.chkbox_default_profile.get_active():
# Make sure there is only one default profile at a time
- config.UnsetWiredDefault()
+ wired.UnsetWiredDefault()
wired.SetWiredProperty("default",
self.chkbox_default_profile.get_active())
- config.SaveWiredNetworkProfile(self.combo_profile_names.get_active_text())
+ wired.SaveWiredNetworkProfile(self.combo_profile_names.get_active_text())
def change_profile(self, widget):
""" Called when a new profile is chosen from the list. """
@@ -713,7 +719,7 @@ class WiredNetworkEntry(NetworkEntry):
return
profile_name = self.combo_profile_names.get_active_text()
- config.ReadWiredNetworkProfile(profile_name)
+ wired.ReadWiredNetworkProfile(profile_name)
self.advanced_dialog.txt_ip.set_text(self.format_entry("ip"))
self.advanced_dialog.txt_netmask.set_text(self.format_entry("netmask"))
@@ -906,22 +912,27 @@ class WirelessNetworkEntry(NetworkEntry):
def edit_scripts(self, widget=None, event=None):
""" Launch the script editting dialog. """
- try:
- sudo_prog = misc.choose_sudo_prog()
- msg = "You must enter your password to configure scripts"
- if sudo_prog.endswith("gksu") or sudo_prog.endswith("ktsuss"):
- msg_flag = "-m"
- else:
- msg_flag = "--caption"
- misc.LaunchAndWait([sudo_prog, msg_flag, msg, "./configscript.py",
- str(self.networkID), "wireless"])
- except IOError:
- error("Could not find a graphical sudo program." + \
- " Script editor could no be launched.")
+ if os.getuid() != 0:
+ try:
+ sudo_prog = misc.choose_sudo_prog()
+ msg = "You must enter your password to configure scripts"
+ if sudo_prog.endswith("gksu") or sudo_prog.endswith("ktsuss"):
+ msg_flag = "-m"
+ else:
+ msg_flag = "--caption"
+ misc.LaunchAndWait([sudo_prog, msg_flag, msg,
+ wpath.lib + "configscript.py",
+ str(self.networkID), "wireless"])
+ except IOError:
+ error(None, "Could not find a graphical sudo program." + \
+ " Script editor could no be launched.")
+ else:
+ misc.LaunchAndWait(["./configscript.py", str(self.networkID),
+ "wireless"])
def update_autoconnect(self, widget=None):
""" Called when the autoconnect checkbox is toggled. """
wireless.SetWirelessProperty(self.networkID, "automatic",
noneToString(self.chkbox_autoconnect.
get_active()))
- config.SaveWirelessNetworkProperty(self.networkID, "automatic")
+ wireless.SaveWirelessNetworkProperty(self.networkID, "automatic")
diff --git a/wicd/networking.py b/wicd/networking.py
index 9d67c4e..1783fd2 100644
--- a/wicd/networking.py
+++ b/wicd/networking.py
@@ -42,18 +42,33 @@ class WiredConnectThread() -- Connection thread for wired
#
import re
+import time
import threading
import thread
-import time
-import wicd.misc as misc
-import wicd.wnettools as wnettools
-import wicd.wpath as wpath
+# wicd imports
+import misc
+import wpath
+from backend import BackendManager
if __name__ == '__main__':
wpath.chdir(__file__)
+BACKEND = None
+BACKEND_MGR = BackendManager()
+def get_backend_list():
+ if not BACKEND_MGR:
+ return [""]
+ else:
+ return BACKEND_MGR.get_available_backends()
+
+def get_current_backend():
+ if not BACKEND_MGR:
+ return None
+ else:
+ return BACKEND_MGR.get_current_backend()
+
class Controller(object):
""" Parent class for the different interface types. """
def __init__(self):
@@ -66,6 +81,7 @@ class Controller(object):
self._dhcp_client = None
self._flush_tool = None
self._debug = None
+ self._backend = None
self.connecting_thread = None
self.before_script = None
self.after_script = None
@@ -73,6 +89,7 @@ class Controller(object):
self.driver = None
self.wiface = None
self.liface = None
+ self.backend_manager = BackendManager()
def set_wireless_iface(self, value):
self._wireless_interface = value
@@ -127,6 +144,21 @@ class Controller(object):
debug = property(get_debug, set_debug)
flush_tool = property(get_flush_tool, set_flush_tool)
dhcp_client = property(get_dhcp_client, set_dhcp_client)
+
+ def LoadBackend(self, backend_name):
+ """ Load the given networking backend. """
+ global BACKEND
+ if backend_name == self._backend:
+ return
+ self._backend = BACKEND_MGR.load_backend(backend_name)
+ BACKEND = self._backend
+
+ def NeedsExternalCalls(self):
+ """ Returns true if the loaded backend needs external calls. """
+ if self._backend:
+ return self._backend.NeedsExternalCalls()
+ else:
+ return True
class ConnectThread(threading.Thread):
@@ -169,7 +201,7 @@ class ConnectThread(threading.Thread):
self.before_script = before_script
self.after_script = after_script
self.disconnect_script = disconnect_script
- self.should_die = False
+ self._should_die = False
self.abort_reason = ""
self.global_dns_1 = gdns1
@@ -183,6 +215,15 @@ class ConnectThread(threading.Thread):
self.debug = debug
self.SetStatus('interface_down')
+
+ def get_should_die(self):
+ return self._should_die
+
+ def set_should_die(self, val):
+ self.lock.acquire()
+ self._should_die = val
+
+ should_die = property(should_die, get_should_die, set_should_die)
def SetStatus(self, status):
@@ -286,14 +327,15 @@ class ConnectThread(threading.Thread):
"""
if self.network.get('use_global_dns'):
- wnettools.SetDNS(misc.Noneify(self.global_dns_1),
+ BACKEND.SetDNS(misc.Noneify(self.global_dns_1),
misc.Noneify(self.global_dns_2),
misc.Noneify(self.global_dns_3))
elif self.network.get('use_static_dns') and (self.network.get('dns1') or
self.network.get('dns2') or self.network.get('dns3')):
self.SetStatus('setting_static_dns')
- wnettools.SetDNS(self.network.get('dns1'), self.network.get('dns2'),
- self.network.get('dns3'))
+ BACKEND.SetDNS(self.network.get('dns1'),
+ self.network.get('dns2'),
+ self.network.get('dns3'))
def connect_aborted(self, reason):
""" Sets the thread status to aborted in a thread-safe way.
@@ -325,13 +367,18 @@ class ConnectThread(threading.Thread):
""" Stop and running DHCP clients, as well as wpa_supplicant. """
print 'Stopping wpa_supplicant and any DHCP clients'
iface.StopWPA()
- wnettools.StopDHCP()
+ BACKEND.StopDHCP()
def abort_if_needed(self):
""" Abort the thread is it has been requested. """
- if self.should_die:
- self.connect_aborted('aborted')
- thread.exit()
+ self.lock.acquire()
+ try:
+ if self._should_die:
+ self.connect_aborted('aborted')
+ self.lock.release()
+ thread.exit()
+ finally:
+ self.lock.release()
def put_iface_up(self, iface):
""" Bring up given interface. """
@@ -347,8 +394,6 @@ class Wireless(Controller):
""" Initialize the class. """
Controller.__init__(self)
self._wpa_driver = None
- self.wiface = wnettools.WirelessInterface(self.wireless_interface,
- self.debug, self.wpa_driver)
def set_wpa_driver(self, value):
self._wpa_driver = value
@@ -359,13 +404,11 @@ class Wireless(Controller):
wpa_driver = property(get_wpa_driver, set_wpa_driver)
-
- #def LoadInterfaces(self, dhcp_client, flush_tool):
- # """ Load the wnettools controls for the wired/wireless interfaces. """
- # #self.wiface = wnettools.WirelessInterface(self.wireless_interface,
- # # self.debug, self.wpa_driver)
- # self.dhcp_client = dhcp_client
- # self.flush_tool = flush_tool
+ def LoadBackend(self, backend):
+ Controller.LoadBackend(self, backend)
+ if self._backend:
+ self.wiface = self._backend.WirelessInterface(self.wireless_interface,
+ self.debug, self.wpa_driver)
def Scan(self, essid=None):
""" Scan for available wireless networks.
@@ -431,43 +474,43 @@ class Wireless(Controller):
self.connecting_thread.start()
return True
- def GetSignalStrength(self, iwconfig=None, fast=False):
+ def GetSignalStrength(self, iwconfig=""):
""" Get signal strength of the current network.
Returns:
The current signal strength.
"""
- return self.wiface.GetSignalStrength(iwconfig, fast)
+ return self.wiface.GetSignalStrength(iwconfig)
- def GetDBMStrength(self, iwconfig=None, fast=False):
+ def GetDBMStrength(self, iwconfig=""):
""" Get the dBm signal strength of the current network.
Returns:
The current dBm signal strength.
"""
- return self.wiface.GetDBMStrength(iwconfig, fast)
+ return self.wiface.GetDBMStrength(iwconfig)
- def GetCurrentNetwork(self, iwconfig=None, fast=False):
+ def GetCurrentNetwork(self, iwconfig=""):
""" Get current network name.
Returns:
The name of the currently connected network.
"""
- return self.wiface.GetCurrentNetwork(iwconfig, fast)
+ return self.wiface.GetCurrentNetwork(iwconfig)
- def GetIP(self, fast=False):
+ def GetIP(self, ifconfig=""):
""" Get the IP of the interface.
Returns:
The IP address of the interface in dotted notation.
"""
- return self.wiface.GetIP(fast)
+ return self.wiface.GetIP(ifconfig)
- def GetBSSID(self, fast=True):
+ def GetBSSID(self):
""" Get the BSSID of the current access point.
Returns:
@@ -475,7 +518,7 @@ class Wireless(Controller):
None the BSSID can't be found.
"""
- return self.wiface.GetBSSID(fast)
+ return self.wiface.GetBSSID()
def GetIwconfig(self):
""" Get the out of iwconfig. """
@@ -507,7 +550,7 @@ class Wireless(Controller):
wiface = self.wiface
print 'Creating ad-hoc network'
print 'Killing dhclient and wpa_supplicant'
- wnettools.StopDHCP()
+ BACKEND.StopDHCP()
wiface.StopWPA()
print 'Putting wireless interface down'
wiface.Down()
@@ -556,7 +599,7 @@ class Wireless(Controller):
The first available wireless interface.
"""
- return wnettools.GetWirelessInterfaces()
+ return BACKEND.GetWirelessInterfaces()
def GetKillSwitchStatus(self):
""" Get the current status of the Killswitch.
@@ -645,7 +688,6 @@ class WirelessConnectThread(ConnectThread):
wiface = self.wiface
liface = self.liface
self.is_connecting = True
- self.is_fast = True
# Run pre-connection script.
self.abort_if_needed()
@@ -684,8 +726,7 @@ class WirelessConnectThread(ConnectThread):
# Validate Authentication.
if self.network.get('enctype'):
self.SetStatus('validating_authentication')
- if not wiface.ValidateAuthentication(time.time(),
- fast=self.is_fast):
+ if not wiface.ValidateAuthentication(time.time()):
self.abort_connection('bad_pass')
self.abort_if_needed()
@@ -702,7 +743,7 @@ class WirelessConnectThread(ConnectThread):
self.SetStatus('done')
print 'Connecting thread exiting.'
if self.debug:
- print "IP Address is: " + str(wiface.GetIP(fast=self.is_fast))
+ print "IP Address is: " + str(wiface.GetIP())
self.is_connecting = False
def generate_psk_and_authenticate(self, wiface):
@@ -756,7 +797,6 @@ class Wired(Controller):
Controller.__init__(self)
self.wpa_driver = None
self._link_detect = None
- self.liface = wnettools.WiredInterface(self.wired_interface, self.debug)
def set_link_detect(self, value):
self._link_detect = value
@@ -766,22 +806,22 @@ class Wired(Controller):
def get_link_detect(self): return self._link_detect
link_detect = property(get_link_detect, set_link_detect)
-
- #def LoadInterfaces(self, dhcp_client, link_tool, flush_tool):
- # """ Load the wnettools controls for the wired/wireless interfaces. """
- # #self.liface = wnettools.WiredInterface(self.wired_interface, self.debug)
- # self.dhcp_client = dhcp_client
- # self.link_detect = link_tool
- # self.flush_tool = flush_tool
+
+ def LoadBackend(self, backend):
+ """ Load the backend up. """
+ Controller.LoadBackend(self, backend)
+ if self._backend:
+ self.liface = self._backend.WiredInterface(self.wired_interface,
+ self.debug)
- def CheckPluggedIn(self, fast=False):
+ def CheckPluggedIn(self):
""" Check whether the wired connection is plugged in.
Returns:
The status of the physical connection link.
"""
- return self.liface.GetPluggedIn(fast)
+ return self.liface.GetPluggedIn()
def Connect(self, network, debug=False):
""" Spawn a connection thread to connect to the network.
@@ -804,18 +844,18 @@ class Wired(Controller):
def DetectWiredInterface(self):
""" Attempts to automatically detect a wired interface. """
try:
- return wnettools.GetWiredInterfaces()[0]
+ return BACKEND.GetWiredInterfaces()[0]
except IndexError:
return None
- def GetIP(self, fast=False):
+ def GetIP(self, ifconfig=""):
""" Get the IP of the interface.
Returns:
The IP address of the interface in dotted notation.
"""
- return self.liface.GetIP(fast)
+ return self.liface.GetIP(ifconfig)
def Disconnect(self):
""" Disconnect from the network. """
@@ -903,8 +943,6 @@ class WiredConnectThread(ConnectThread):
liface = self.liface
self.is_connecting = True
- #TODO pass is_fast in.
- self.is_fast = True
# Run pre-connection script.
self.abort_if_needed()
@@ -936,5 +974,5 @@ class WiredConnectThread(ConnectThread):
self.SetStatus('done')
print 'Connecting thread exiting.'
if self.debug:
- print "IP Address is: " + str(liface.GetIP(fast=self.is_fast))
+ print "IP Address is: " + str(liface.GetIP())
self.is_connecting = False
diff --git a/wicd/prefs.py b/wicd/prefs.py
index f472470..57834ec 100644
--- a/wicd/prefs.py
+++ b/wicd/prefs.py
@@ -27,23 +27,22 @@ import gtk
import gobject
import pango
-import wicd.misc
+from wicd import misc
+from wicd import gui
from wicd.misc import checkboxTextboxToggle, noneToBlankString
daemon = None
wireless = None
wired = None
-config = None
language = misc.get_language_list_gui()
class PreferencesDialog(object):
def __init__(self, wTree, dbus):
- global daemon, wireless, wired, config
+ global daemon, wireless, wired
daemon = dbus['daemon']
wireless = dbus['wireless']
wired = dbus['wired']
- config = dbus['config']
self.wTree = wTree
self.prep_settings_diag()
self.build_preferences_diag()
@@ -68,7 +67,7 @@ class PreferencesDialog(object):
self.dialog = self.wTree.get_widget("pref_dialog")
self.dialog.set_title(language['preferences'])
- size = config.ReadWindowSize("pref")
+ size = daemon.ReadWindowSize("pref")
width = size[0]
height = size[1]
if width > -1 and height > -1:
@@ -76,7 +75,7 @@ class PreferencesDialog(object):
self.wiredcheckbox = setup_label("pref_always_check",
'wired_always_on')
- self.wiredcheckbox.set_active(wired.GetAlwaysShowWiredInterface())
+ self.wiredcheckbox.set_active(daemon.GetAlwaysShowWiredInterface())
self.reconnectcheckbox = setup_label("pref_auto_check",
'auto_reconnect')
self.reconnectcheckbox.set_active(daemon.GetAutoReconnect())
@@ -180,6 +179,25 @@ class PreferencesDialog(object):
self.dns1Entry.set_sensitive(False)
self.dns2Entry.set_sensitive(False)
self.dns3Entry.set_sensitive(False)
+
+ # Load backend combobox
+ self.backendcombo = build_combobox("pref_backend_combobox")
+ self.backends = daemon.GetBackendList()
+ # "" is included as a hack for DBus limitations, so we remove it.
+ self.backends.remove("")
+ found = False
+ cur_backend = daemon.GetSavedBackend()
+ for i, x in enumerate(self.backends):
+ if x == cur_backend:
+ found = True
+ backend_index = i
+ self.backendcombo.remove_text(i)
+ self.backendcombo.append_text(x)
+
+ if found:
+ self.backendcombo.set_active(backend_index)
+ else:
+ self.backendcombo.set_active(0)
self.wTree.get_widget("notebook2").set_current_page(0)
@@ -199,10 +217,10 @@ class PreferencesDialog(object):
daemon.SetWirelessInterface(self.entryWirelessInterface.get_text())
daemon.SetWiredInterface(self.entryWiredInterface.get_text())
daemon.SetWPADriver(self.wpadrivers[self.wpadrivercombo.get_active()])
- wired.SetAlwaysShowWiredInterface(self.wiredcheckbox.get_active())
+ daemon.SetAlwaysShowWiredInterface(self.wiredcheckbox.get_active())
daemon.SetAutoReconnect(self.reconnectcheckbox.get_active())
daemon.SetDebugMode(self.debugmodecheckbox.get_active())
- daemon.SetSignalDisplayType(self.displaytypecheckbox.get_active())
+ wireless.SetSignalDisplayType(self.displaytypecheckbox.get_active())
if self.showlistradiobutton.get_active():
wired.SetWiredAutoConnectMethod(2)
elif self.lastusedradiobutton.get_active():
@@ -210,6 +228,10 @@ class PreferencesDialog(object):
else:
wired.SetWiredAutoConnectMethod(1)
+ if self.backends[self.backendcombo.get_active()] != daemon.GetSavedBackend():
+ gui.alert(self.dialog, language["backend_alert"])
+ daemon.SetBackend(self.backends[self.backendcombo.get_active()])
+
# External Programs Tab
if self.dhcpautoradio.get_active():
dhcp_client = misc.AUTO
@@ -238,7 +260,7 @@ class PreferencesDialog(object):
daemon.SetFlushTool(flush_tool)
[width, height] = self.dialog.get_size()
- config.WriteWindowSize(width, height, "pref")
+ daemon.WriteWindowSize(width, height, "pref")
def set_label(self, glade_str, label):
""" Sets the label for the given widget in wicd.glade. """
@@ -252,6 +274,7 @@ class PreferencesDialog(object):
self.wTree.get_widget("dhcp_client_label").set_label(language["dhcp_client"])
self.wTree.get_widget("wired_detect_label").set_label(language["wired_detect"])
self.wTree.get_widget("route_flush_label").set_label(language["route_flush"])
+ self.wTree.get_widget("pref_backend_label").set_label(language["backend"] + ":")
entryWiredAutoMethod = self.wTree.get_widget("pref_wired_auto_label")
entryWiredAutoMethod.set_label('Wired Autoconnect Setting:')
diff --git a/wicd/wicd.py b/wicd/wicd-client.py
similarity index 89%
rename from wicd/wicd.py
rename to wicd/wicd-client.py
index f116fd2..2a460af 100755
--- a/wicd/wicd.py
+++ b/wicd/wicd-client.py
@@ -42,13 +42,14 @@ import gobject
import getopt
import os
import pango
+import time
from dbus import DBusException
from dbus import version as dbus_version
# Wicd specific imports
-import wicd.wpath as wpath
-import wicd.misc as misc
-import wicd.gui as gui
+from wicd import wpath
+from wicd import misc
+from wicd import gui
from wicd.dbusmanager import DBusManager
# Import egg.trayicon if we're using an older gtk version
@@ -78,7 +79,6 @@ daemon = None
wireless = None
wired = None
wired = None
-config = None
language = misc.get_language_list_tray()
@@ -203,7 +203,7 @@ class TrayIcon:
if self.animate:
prefix = self.get_bandwidth_state()
else:
- prefix = ''
+ prefix = 'idle-'
if daemon.GetSignalDisplayType() == 0:
if wireless_signal > 75:
signal_img = "high-signal"
@@ -298,7 +298,7 @@ class TrayIcon:
return (active, max_gain, last_bytes)
- class TrayIconGUI:
+ class TrayIconGUI(object):
""" Base Tray Icon UI class.
Implements methods and variables used by both egg/StatusIcon
@@ -336,16 +336,24 @@ class TrayIcon:
props.parent)
self.gui_win = None
self.current_icon_path = None
- self.dbus_available = True
self.use_tray = use_tray
-
+ self._is_scanning = False
+ net_menuitem = self.manager.get_widget("/Menubar/Menu/Connect/")
+ net_menuitem.connect("activate", self.on_net_menu_activate)
+
+ def tray_scan_started(self):
+ """ Callback for when a wireless scan is started. """
+ self._is_scanning = True
+ self.init_network_menu()
+
+ def tray_scan_ended(self):
+ """ Callback for when a wireless scan finishes. """
+ self._is_scanning = False
+ self.populate_network_menu()
+
def on_activate(self, data=None):
""" Opens the wicd GUI. """
- try:
- self.toggle_wicd_gui()
- except dbus.DBusException:
- self.dbus_available = False
- gui.error(None, "Could not connect to wicd daemon. Unable to load GUI")
+ self.toggle_wicd_gui()
def on_quit(self, widget=None):
""" Closes the tray icon. """
@@ -361,8 +369,8 @@ class TrayIcon:
dialog.run()
dialog.destroy()
- def _add_item_to_menu(self, net_menu, lbl, type_,
- n_id, is_connecting, is_active):
+ def _add_item_to_menu(self, net_menu, lbl, type_, n_id, is_connecting,
+ is_active):
""" Add an item to the network list submenu. """
def network_selected(widget, net_type, net_id):
""" Callback method for a menu item selection. """
@@ -423,6 +431,29 @@ class TrayIcon:
signal_img = 'signal-25.png'
return wpath.images + signal_img
+ 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.
+
+ """
+ def dummy(x=None): pass
+
+ if self._is_scanning:
+ return True
+
+ self.init_network_menu()
+ time.sleep(.4)
+ while gtk.events_pending():
+ gtk.main_iteration()
+ if item.state != gtk.STATE_PRELIGHT:
+ return True
+ wireless.Scan(reply_handler=dummy, error_handler=dummy)
+
def populate_network_menu(self, data=None):
""" Populates the network list submenu. """
def get_prop(net_id, prop):
@@ -436,14 +467,14 @@ class TrayIcon:
num_networks = wireless.GetNumberOfNetworks()
[status, info] = daemon.GetConnectionStatus()
- if wired.GetAlwaysShowWiredInterface() or \
- wired.CheckPluggedIn(True):
+ if daemon.GetAlwaysShowWiredInterface() or \
+ wired.CheckPluggedIn():
if status == misc.WIRED:
is_active = True
else:
is_active = False
- self._add_item_to_menu(submenu, "Wired Network", "__wired__",
- 0, is_connecting, is_active)
+ self._add_item_to_menu(submenu, "Wired Network", "__wired__", 0,
+ is_connecting, is_active)
sep = gtk.SeparatorMenuItem()
submenu.append(sep)
sep.show()
@@ -457,10 +488,16 @@ class TrayIcon:
is_active = False
self._add_item_to_menu(submenu, essid, "wifi", x,
is_connecting, is_active)
+ else:
+ no_nets_item = gtk.MenuItem(language['no_wireless_networks_found'])
+ no_nets_item.set_sensitive(False)
+ no_nets_item.show()
+ submenu.append(no_nets_item)
net_menuitem.show()
def init_network_menu(self):
+ """ Set the right-click menu for to the scanning state. """
net_menuitem = self.manager.get_widget("/Menubar/Menu/Connect/")
submenu = net_menuitem.get_submenu()
self._clear_menu(submenu)
@@ -469,10 +506,10 @@ class TrayIcon:
loading_item.set_sensitive(False)
loading_item.show()
submenu.append(loading_item)
- #net_menuitem.set_submenu(net_menu)
net_menuitem.show()
def _clear_menu(self, menu):
+ """ Clear the right-click menu. """
for item in menu.get_children():
menu.remove(item)
item.destroy()
@@ -483,11 +520,11 @@ class TrayIcon:
self.gui_win = gui.appGui(dbus_manager)
bus = dbus_manager.get_bus()
bus.add_signal_receiver(self.gui_win.dbus_scan_finished,
- 'SendEndScanSignal',
- 'org.wicd.daemon')
+ 'SendEndScanSignal',
+ 'org.wicd.daemon.wireless')
bus.add_signal_receiver(self.gui_win.dbus_scan_started,
'SendStartScanSignal',
- 'org.wicd.daemon')
+ 'org.wicd.daemon.wireless')
bus.add_signal_receiver(self.gui_win.update_connect_buttons,
'StatusChanged', 'org.wicd.daemon')
elif not self.gui_win.is_visible:
@@ -530,7 +567,7 @@ class TrayIcon:
if event.button == 1:
self.toggle_wicd_gui()
elif event.button == 3:
- self.populate_network_menu()
+ self.init_network_menu()
self.menu.popup(None, None, None, event.button, event.time)
def set_from_file(self, val=None):
@@ -574,8 +611,6 @@ class TrayIcon:
def on_popup_menu(self, status, button, timestamp):
""" Opens the right click menu for the tray icon. """
self.init_network_menu()
- wireless.Scan(reply_handler=self.populate_network_menu,
- error_handler=lambda x: x)
self.menu.popup(None, None, None, button, timestamp)
def set_from_file(self, path = None):
@@ -599,7 +634,7 @@ Arguments:
"""
def setup_dbus():
- global bus, daemon, wireless, wired, config, dbus_manager
+ global bus, daemon, wireless, wired, dbus_manager
dbus_manager = DBusManager()
try:
@@ -617,7 +652,6 @@ def setup_dbus():
daemon = dbus_ifaces['daemon']
wireless = dbus_ifaces['wireless']
wired = dbus_ifaces['wired']
- config = dbus_ifaces['config']
return True
def main(argv):
@@ -674,23 +708,13 @@ def main(argv):
'LaunchChooser', 'org.wicd.daemon')
bus.add_signal_receiver(tray_icon.icon_info.update_tray_icon,
'StatusChanged', 'org.wicd.daemon')
+ bus.add_signal_receiver(tray_icon.tr.tray_scan_ended, 'SendEndScanSignal',
+ 'org.wicd.daemon.wireless')
+ bus.add_signal_receiver(tray_icon.tr.tray_scan_started,
+ 'SendStartScanSignal', 'org.wicd.daemon.wireless')
print 'Done.'
-
- while 1:
- mainloop = gobject.MainLoop()
- try:
- mainloop.run()
- except DBusException:
- print 'Warning. Caught a D-Bus exception! Connection to daemon lost.'
- print 'Trying to reconnect...'
- sleep(10)
- try:
- setup_dbus()
- except:
- pass
-
-
-
+ mainloop = gobject.MainLoop()
+ mainloop.run()
if __name__ == '__main__':
diff --git a/wicd/daemon.py b/wicd/wicd-daemon.py
similarity index 72%
rename from wicd/daemon.py
rename to wicd/wicd-daemon.py
index c3b24a6..58e585e 100644
--- a/wicd/daemon.py
+++ b/wicd/wicd-daemon.py
@@ -17,9 +17,9 @@ def main() -- The wicd daemon main loop.
"""
#
-# Copyright (C) 2007 Adam Blackburn
-# Copyright (C) 2007 Dan O'Reilly
-# Copyright (C) 2007 Byron Hillis
+# Copyright (C) 2007 - 2008 Adam Blackburn
+# Copyright (C) 2007 - 2008 Dan O'Reilly
+# Copyright (C) 2007 - 2008 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
@@ -52,28 +52,29 @@ else:
DBusGMainLoop(set_as_default=True)
# wicd specific libraries
-import wicd.wpath as wpath
-import wicd.networking as networking
-import wicd.misc as misc
+from wicd import wpath
+from wicd import networking
+from wicd import misc
from wicd.logfile import ManagedStdio
+from wicd.configmanager import ConfigManager
if __name__ == '__main__':
wpath.chdir(__file__)
-misc.RenameProcess("wicd-daemon")
+misc.RenameProcess("wicd")
-class ConnectionWizard(dbus.service.Object):
- def __init__(self, bus_name, object_path='/org/wicd/daemon',
+class WicdDaemon(dbus.service.Object):
+ def __init__(self, bus_name, object_path="/org/wicd/daemon",
auto_connect=True):
- dbus.service.Object.__init__(self, bus_name, object_path)
-
- self.app_conf = wpath.etc + 'manager-settings.conf'
- self.wireless_conf = wpath.etc + 'wireless-settings.conf'
- self.wired_conf = wpath.etc + 'wired-settings.conf'
- self.hidden_essid = None
+ dbus.service.Object.__init__(self, bus_name=bus_name,
+ object_path=object_path)
self.wifi = networking.Wireless()
self.wired = networking.Wired()
+ self.config = ConfigManager(wpath.etc + "manager-settings.conf")
+ self.wired_bus= WiredDaemon(bus_name, wired=self.wired, wifi=self.wifi)
+ self.wireless_bus = WirelessDaemon(bus_name, wired=self.wired,
+ wifi=self.wifi)
self.forced_disconnect = False
self.need_profile_chooser = False
self.current_interface = None
@@ -107,13 +108,10 @@ class ConnectionWizard(dbus.service.Object):
print "autoconnecting...", str(self.GetWirelessInterface())
self.AutoConnect(True)
else:
- self.Scan()
+ self.wireless_bus.Scan()
#self.SetForcedDisconnect(True)
print "--no-scan detected, not autoconnecting..."
-
- ########## DAEMON FUNCTIONS
- #################################
-
+
@dbus.service.method('org.wicd.daemon')
def Hello(self):
""" Returns the version number.
@@ -124,8 +122,7 @@ class ConnectionWizard(dbus.service.Object):
anything >= 0. This number is effective starting wicd v1.2.0.
"""
- version = '1.5.0'
- print 'returned version number', version
+ version = '1.6.0'
return version
@dbus.service.method('org.wicd.daemon')
@@ -134,7 +131,7 @@ class ConnectionWizard(dbus.service.Object):
print "setting wired interface %s" % (str(interface))
self.wired.wired_interface = interface
self.wifi.wired_interface = interface
- self.set_option("Settings", "wired_interface", interface)
+ self.config.set("Settings", "wired_interface", interface, True)
@dbus.service.method('org.wicd.daemon')
def SetWirelessInterface(self, interface):
@@ -142,21 +139,21 @@ class ConnectionWizard(dbus.service.Object):
print "setting wireless interface %s" % (str(interface))
self.wifi.wireless_interface = interface
self.wired.wireless_interface = interface
- self.set_option("Settings", "wireless_interface", interface)
+ self.config.set("Settings", "wireless_interface", interface, True)
@dbus.service.method('org.wicd.daemon')
def SetWPADriver(self, driver):
""" Sets the wpa driver the wpa_supplicant will use. """
print "setting wpa driver", str(driver)
self.wifi.wpa_driver = driver
- self.set_option("Settings", "wpa_driver", driver)
+ self.config.set("Settings", "wpa_driver", driver, True)
@dbus.service.method('org.wicd.daemon')
def SetUseGlobalDNS(self, use):
""" Sets a boolean which determines if global DNS is enabled. """
print 'setting use global dns to', use
use = misc.to_bool(use)
- self.set_option("Settings", "use_global_dns", use)
+ self.config.set("Settings", "use_global_dns", use, True)
self.use_global_dns = use
self.wifi.use_global_dns = use
self.wired.use_global_dns = use
@@ -165,19 +162,44 @@ class ConnectionWizard(dbus.service.Object):
def SetGlobalDNS(self, dns1=None, dns2=None, dns3=None):
""" Sets the global dns addresses. """
print "setting global dns"
- self.set_option("Settings", "global_dns_1", misc.noneToString(dns1))
+ self.config.set("Settings", "global_dns_1", misc.noneToString(dns1), True)
self.dns1 = dns1
self.wifi.global_dns_1 = dns1
self.wired.global_dns_1 = dns1
- self.set_option("Settings", "global_dns_2", misc.noneToString(dns2))
+ self.config.set("Settings", "global_dns_2", misc.noneToString(dns2), True)
self.dns2 = dns2
self.wifi.global_dns_2 = dns2
self.wired.global_dns_2 = dns2
- self.set_option("Settings", "global_dns_3", misc.noneToString(dns3))
+ self.config.set("Settings", "global_dns_3", misc.noneToString(dns3), True)
self.dns3 = dns3
self.wifi.global_dns_3 = dns3
self.wired.global_dns_3 = dns3
print 'global dns servers are', dns1, dns2, dns3
+
+ @dbus.service.method('org.wicd.daemon')
+ def SetBackend(self, backend):
+ """ Sets a new backend. """
+ print "setting backend to %s" % backend
+ self.config.set("Settings", "backend", backend, True)
+ if self.GetCurrentBackend():
+ return
+ self.wifi.LoadBackend(backend)
+ self.wired.LoadBackend(backend)
+
+ @dbus.service.method('org.wicd.daemon')
+ def GetCurrentBackend(self):
+ """ Returns the currently loaded backend. """
+ return networking.get_current_backend()
+
+ @dbus.service.method('org.wicd.daemon')
+ def GetSavedBackend(self):
+ """ Returns the backend saved to disk. """
+ return self.config.get("Settings", "backend")
+
+ @dbus.service.method('org.wicd.daemon')
+ def GetBackendList(self):
+ """ Returns a list of all backends available. """
+ return networking.get_backend_list()
@dbus.service.method('org.wicd.daemon')
def GetUseGlobalDNS(self):
@@ -198,14 +220,26 @@ class ConnectionWizard(dbus.service.Object):
def GetWirelessInterface(self):
""" Returns the wireless interface the daemon is using. """
return str(self.wifi.wireless_interface)
+
+ @dbus.service.method('org.wicd.daemon')
+ def NeedsExternalCalls(self):
+ """ Returns true if the loaded backend needs external calls. """
+ if self.wifi:
+ return self.wifi.NeedsExternalCalls()
+ elif self.wired:
+ return self.wired.NeedsExternalCalls()
+ else:
+ return True
@dbus.service.method('org.wicd.daemon')
def SetDebugMode(self, debug):
""" Sets if debugging mode is on or off. """
- self.set_option("Settings", "debug_mode", debug)
+ self.config.set("Settings", "debug_mode", debug, True)
self.debug_mode = misc.to_bool(debug)
self.wifi.debug = self.debug_mode
self.wired.debug = self.debug_mode
+ self.wireless_bus.debug_mode = debug
+ self.wired_bus.debug_mode = debug
@dbus.service.method('org.wicd.daemon')
def GetDebugMode(self):
@@ -219,23 +253,6 @@ class ConnectionWizard(dbus.service.Object):
self.wifi.Disconnect()
self.wired.Disconnect()
- @dbus.service.method('org.wicd.daemon')
- def GetSignalDisplayType(self):
- """ Returns the signal display type.
-
- Returns either 0 or 1.
- 0 for signal strength as a percentage
- 1 for signal strength measured in dBm
-
- """
- return int(self.signal_display_type)
-
- @dbus.service.method('org.wicd.daemon')
- def SetSignalDisplayType(self, value):
- """ Sets the signal display type and writes it the wicd config file. """
- self.set_option("Settings", "signal_display_type", value)
- self.signal_display_type = int(value)
-
@dbus.service.method('org.wicd.daemon')
def FormatSignalForPrinting(self, signal):
""" Returns the suffix to display after the signal strength number. """
@@ -265,80 +282,11 @@ class ConnectionWizard(dbus.service.Object):
"""
if fresh:
- self.Scan()
- if self.CheckPluggedIn(True):
- self._wired_autoconnect()
+ self.wireless_bus.Scan()
+ if self.wired_bus.CheckPluggedIn():
+ self.wired_bus._wired_autoconnect()
else:
- self._wireless_autoconnect()
-
- def _wired_autoconnect(self):
- """ Attempts to autoconnect to a wired network. """
- if self.GetWiredAutoConnectMethod() == 3 and \
- not self.GetNeedWiredProfileChooser():
- # attempt to smartly connect to a wired network
- # by using various wireless networks detected
- # and by using plugged in USB devices
- print self.LastScan
- if self.GetWiredAutoConnectMethod() == 2 and \
- not self.GetNeedWiredProfileChooser():
- self.LaunchChooser()
- return
-
- # Default Profile.
- elif self.GetWiredAutoConnectMethod() == 1:
- network = self.GetDefaultWiredNetwork()
- if not network:
- print "Couldn't find a default wired connection," + \
- " wired autoconnect failed."
- self._wireless_autoconnect()
- return
-
- # Last-Used.
- else:
- network = self.GetLastUsedWiredNetwork()
- if not network:
- print "no previous wired profile available, wired " + \
- "autoconnect failed."
- self._wireless_autoconnect()
- return
-
- self.ReadWiredNetworkProfile(network)
- self.ConnectWired()
- print "Attempting to autoconnect with wired interface..."
- self.auto_connecting = True
- time.sleep(1.5)
- gobject.timeout_add(3000, self._monitor_wired_autoconnect)
-
- def _wireless_autoconnect(self):
- """ Attempts to autoconnect to a wireless network. """
- print "No wired connection present, attempting to autoconnect" + \
- "to wireless network"
- if self.GetWirelessInterface() is None:
- print 'Autoconnect failed because wireless interface returned None'
- return
-
- for x, network in enumerate(self.LastScan):
- if bool(network["has_profile"]):
- if self.debug_mode:
- print network["essid"] + ' has profile'
- if bool(network.get('automatic')):
- print 'trying to automatically connect to...' + \
- network["essid"]
- self.ConnectWireless(x)
- time.sleep(1)
- return
- print "Unable to autoconnect, you'll have to manually connect"
-
- def _monitor_wired_autoconnect(self):
- if self.CheckIfWiredConnecting():
- return True
- elif self.GetWiredIP():
- self.auto_connecting = False
- return False
- elif not self.CheckIfWirelessConnecting():
- self._wireless_autoconnect()
- self.auto_connecting = False
- return False
+ self.wireless_bus._wireless_autoconnect()
@dbus.service.method('org.wicd.daemon')
def GetAutoReconnect(self):
@@ -357,7 +305,7 @@ class ConnectionWizard(dbus.service.Object):
"""
print 'setting automatically reconnect when connection drops'
- self.set_option("Settings", "auto_reconnect", misc.to_bool(value))
+ self.config.set("Settings", "auto_reconnect", misc.to_bool(value), True)
self.auto_reconnect = misc.to_bool(value)
@dbus.service.method('org.wicd.daemon')
@@ -369,7 +317,8 @@ class ConnectionWizard(dbus.service.Object):
@dbus.service.method('org.wicd.daemon')
def CheckIfConnecting(self):
""" Returns if a network connection is being made. """
- if self.CheckIfWiredConnecting() or self.CheckIfWirelessConnecting():
+ if self.wired_bus.CheckIfWiredConnecting() or \
+ self.wireless_bus.CheckIfWirelessConnecting():
return True
else:
return False
@@ -418,7 +367,9 @@ class ConnectionWizard(dbus.service.Object):
@dbus.service.method('org.wicd.daemon')
def GetForcedDisconnect(self):
""" Returns the forced_disconnect status. See SetForcedDisconnect. """
- return bool(self.forced_disconnect)
+ return (bool(self.forced_disconnect) or
+ bool(self.wireless_bus.GetForcedDisconnect()) or
+ bool(self.wired_bus.GetForcedDisconnect()))
@dbus.service.method('org.wicd.daemon')
def SetForcedDisconnect(self, value):
@@ -430,6 +381,26 @@ class ConnectionWizard(dbus.service.Object):
"""
self.forced_disconnect = bool(value)
+ self.wireless_bus.SetForcedDisconnect(bool(value))
+ self.wired_bus.SetForcedDisconnect(bool(value))
+
+ @dbus.service.method('org.wicd.daemon')
+ def GetSignalDisplayType(self):
+ """ Returns the signal display type.
+
+ Returns either 0 or 1.
+ 0 for signal strength as a percentage
+ 1 for signal strength measured in dBm
+
+ """
+ return int(self.signal_display_type)
+
+
+ @dbus.service.method('org.wicd.daemon')
+ def SetSignalDisplayType(self, value):
+ """ Sets the signal display type and writes it the wicd config file. """
+ self.config.set("Settings", "signal_display_type", value, True)
+ self.signal_display_type = int(value)
@dbus.service.method('org.wicd.daemon')
def GetGUIOpen(self):
@@ -454,6 +425,18 @@ class ConnectionWizard(dbus.service.Object):
""" Sets the value of gui_open. """
self.gui_open = bool(val)
+ @dbus.service.method('org.wicd.daemon')
+ def SetAlwaysShowWiredInterface(self, value):
+ """ Sets always_show_wired_interface to the given value. """
+ self.config.set("Settings", "always_show_wired_interface",
+ misc.to_bool(value), True)
+ self.always_show_wired_interface = misc.to_bool(value)
+
+ @dbus.service.method('org.wicd.daemon')
+ def GetAlwaysShowWiredInterface(self):
+ """ Returns always_show_wired_interface """
+ return bool(self.always_show_wired_interface)
+
@dbus.service.method('org.wicd.daemon')
def SetConnectionStatus(self, state, info):
""" Sets the connection status.
@@ -505,18 +488,17 @@ class ConnectionWizard(dbus.service.Object):
self.dhcp_client = int(client)
self.wifi.dhcp_client = int(client)
self.wired.dhcp_client = int(client)
- self.set_option("Settings", "dhcp_client", client)
+ self.config.set("Settings", "dhcp_client", client, True)
@dbus.service.method('org.wicd.daemon')
def GetLinkDetectionTool(self):
return self.link_detect_tool
-
@dbus.service.method('org.wicd.daemon')
def SetLinkDetectionTool(self, link_tool):
self.link_detect_tool = int(link_tool)
self.wired.link_tool = int(link_tool)
- self.set_option("Settings", "link_detect_tool", link_tool)
+ self.config.set("Settings", "link_detect_tool", link_tool, True)
@dbus.service.method('org.wicd.daemon')
def GetFlushTool(self):
@@ -527,7 +509,49 @@ class ConnectionWizard(dbus.service.Object):
self.flush_tool = int(flush_tool)
self.wired.flush_tool = int(flush_tool)
self.wifi.flush_tool = int(flush_tool)
- self.set_option("Settings", "flush_tool", flush_tool)
+ self.config.set("Settings", "flush_tool", flush_tool, True)
+
+ @dbus.service.method('org.wicd.daemon')
+ def WriteWindowSize(self, width, height, win_name):
+ """Write the desired default window size"""
+ if win_name == "main":
+ height_str = "window_height"
+ width_str = "window_width"
+ else:
+ height_str = "pref_height"
+ width_str = "pref_width"
+
+ self.config.set("Settings", width_str, width)
+ self.config.set("Settings", height_str, height)
+ self.config.write()
+
+ @dbus.service.method('org.wicd.daemon')
+ def ReadWindowSize(self, win_name):
+ """Returns a list containing the desired default window size
+
+ Attempts to read the default size from the config file,
+ and if that fails, returns a default of 605 x 400.
+
+ """
+ if win_name == "main":
+ default_width = 605
+ default_height = 400
+ width_str = "window_width"
+ height_str = "window_height"
+ else:
+ default_width = 125
+ default_height = 500
+ width_str = "pref_width"
+ height_str = "pref_height"
+
+ width = self.config.get("Settings", width_str, default=default_width)
+ height = self.config.get("Settings", height_str, default=default_height)
+ self.config.write()
+
+ size = []
+ size.append(int(width))
+ size.append(int(height))
+ return size
@dbus.service.signal(dbus_interface='org.wicd.daemon', signature='')
def LaunchChooser(self):
@@ -548,22 +572,106 @@ class ConnectionWizard(dbus.service.Object):
"""
pass
- @dbus.service.method('org.wicd.daemon')
- @dbus.service.signal(dbus_interface='org.wicd.daemon', signature='')
- def SendStartScanSignal(self):
- """ Emits a signal announcing a scan has started. """
- pass
-
+ def __printReturn(self, text, value):
+ """prints the specified text and value, then returns the value"""
+ if self.debug_mode:
+ print ''.join([text, " ", str(value)])
+ return value
- @dbus.service.method('org.wicd.daemon')
- @dbus.service.signal(dbus_interface='org.wicd.daemon', signature='')
- def SendEndScanSignal(self):
- """ Emits a signal announcing a scan has finished. """
- pass
+ def ReadConfig(self):
+ """ Reads the manager-settings.conf file.
+
+ Reads the manager-settings.conf file and loads the stored
+ values into memory.
+
+ """
+ b_wired = self.wired_bus
+ b_wifi = self.wireless_bus
+ app_conf= self.config
+ verbose = True
+ # Load the backend.
+ be_def = 'external'
+ self.SetBackend(app_conf.get("Settings", "backend", default=be_def))
+
+ # Load network interfaces.
+ iface = self.wireless_bus.DetectWirelessInterface()
+ if not iface: iface = 'wlan0'
+ self.SetWirelessInterface(app_conf.get("Settings", "wireless_interface",
+ default=iface))
+ iface = self.wired_bus.DetectWiredInterface()
+ if not iface: iface = 'eth0'
+ self.SetWiredInterface(app_conf.get("Settings", "wired_interface",
+ default=iface))
+
+ self.SetWPADriver(app_conf.get("Settings", "wpa_driver", default="wext"))
+ self.SetAlwaysShowWiredInterface(app_conf.get("Settings",
+ "always_show_wired_interface",
+ default=False))
+ self.SetUseGlobalDNS(app_conf.get("Settings", "use_global_dns",
+ default=False))
+ dns1 = app_conf.get("Settings", "global_dns_1", default='None')
+ dns2 = app_conf.get("Settings", "global_dns_2", default='None')
+ dns3 = app_conf.get("Settings", "global_dns_3", default='None')
+ self.SetGlobalDNS(dns1, dns2, dns3)
+ self.SetAutoReconnect(app_conf.get("Settings", "auto_reconnect",
+ default=True))
+ self.SetDebugMode(app_conf.get("Settings", "debug_mode", default=False))
+ b_wired.SetWiredAutoConnectMethod(app_conf.get("Settings",
+ "wired_connect_mode",
+ default=1))
+ self.SetSignalDisplayType(app_conf.get("Settings",
+ "signal_display_type",
+ default=0))
+ self.SetDHCPClient(app_conf.get("Settings", "dhcp_client", default=0))
+ self.SetLinkDetectionTool(app_conf.get("Settings", "link_detect_tool",
+ default=0))
+ self.SetFlushTool(app_conf.get("Settings", "flush_tool", default=0))
+ app_conf.write()
- ########## WIRELESS FUNCTIONS
- #################################
+ if os.path.isfile(wireless_conf):
+ print "Wireless configuration file found..."
+ else:
+ print "Wireless configuration file not found, creating..."
+ open(wireless_conf, "w").close()
+ if os.path.isfile(wired_conf):
+ print "Wired configuration file found..."
+ else:
+ print "Wired configuration file not found, creating a default..."
+ # Create the file and a default profile
+ open(wired_conf, "w").close()
+ b_wired.CreateWiredNetworkProfile("wired-default", default=True)
+
+ # Hide the files, so the keys aren't exposed.
+ print "chmoding configuration files 0600..."
+ os.chmod(app_conf.get_config(), 0600)
+ os.chmod(wireless_conf, 0600)
+ os.chmod(wired_conf, 0600)
+
+ # Make root own them
+ print "chowning configuration files root:root..."
+ os.chown(app_conf.get_config(), 0, 0)
+ os.chown(wireless_conf, 0, 0)
+ os.chown(wired_conf, 0, 0)
+
+ print "Using wireless interface..." + self.GetWirelessInterface()
+ print "Using wired interface..." + self.GetWiredInterface()
+
+##############################
+###### Wireless Daemon #######
+##############################
+
+class WirelessDaemon(dbus.service.Object):
+ def __init__(self, bus_name, wired=None, wifi=None, debug=False):
+ dbus.service.Object.__init__(self, bus_name=bus_name,
+ object_path='/org/wicd/daemon/wireless')
+ self.hidden_essid = None
+ self.wired = wired
+ self.wifi = wifi
+ self.debug_mode = debug
+ self.forced_disconnect = False
+ self.config = ConfigManager(wpath.etc + "wireless-settings.conf")
+
@dbus.service.method('org.wicd.daemon.wireless')
def SetHiddenNetworkESSID(self, essid):
""" Sets the ESSID of a hidden network for use with Scan(). """
@@ -581,7 +689,7 @@ class ConnectionWizard(dbus.service.Object):
print 'scanning start'
self.SendStartScanSignal()
time.sleep(.2)
- scan = self.wifi.Scan(str(self.hidden_essid), fast=True)
+ scan = self.wifi.Scan(str(self.hidden_essid))
self.LastScan = scan
if self.debug_mode:
print 'scanning done'
@@ -653,6 +761,22 @@ class ConnectionWizard(dbus.service.Object):
""" Disconnects the wireless network. """
self.SetForcedDisconnect(True)
self.wifi.Disconnect()
+
+ @dbus.service.method('org.wicd.daemon.wireless')
+ def GetForcedDisconnect(self):
+ """ Returns the forced_disconnect status. See SetForcedDisconnect. """
+ return bool(self.forced_disconnect)
+
+ @dbus.service.method('org.wicd.daemon.wireless')
+ def SetForcedDisconnect(self, value):
+ """ Sets the forced_disconnect status.
+
+ Set to True when a user manually disconnects or cancels a connection.
+ It gets set to False as soon as the connection process is manually
+ started.
+
+ """
+ self.forced_disconnect = bool(value)
@dbus.service.method('org.wicd.daemon.wireless')
def IsWirelessUp(self):
@@ -660,48 +784,33 @@ class ConnectionWizard(dbus.service.Object):
return self.wifi.IsUp()
@dbus.service.method('org.wicd.daemon.wireless')
- def GetPrintableSignalStrength(self, iwconfig=None, fast=False):
- """ Assigns a signal strength appropriate for display
-
- This is used separately from the raw signal strength retrieving
- functions as a way to simply the strength polling process for
- the GUI and tray icon, by returning the strength that the user
- has requested to be displayed in wicd preferences.
-
- """
- if self.GetSignalDisplayType() == 0:
- return self.GetCurrentSignalStrength(iwconfig, fast)
- else:
- return self.GetCurrentDBMStrength(iwconfig, fast)
-
- @dbus.service.method('org.wicd.daemon.wireless')
- def GetCurrentSignalStrength(self, iwconfig=None, fast=False):
+ def GetCurrentSignalStrength(self, iwconfig=None):
""" Returns the current signal strength. """
try:
- strength = int(self.wifi.GetSignalStrength(iwconfig, fast))
+ strength = int(self.wifi.GetSignalStrength(iwconfig))
except:
strength = 0
return strength
@dbus.service.method('org.wicd.daemon.wireless')
- def GetCurrentDBMStrength(self, iwconfig=None, fast=False):
+ def GetCurrentDBMStrength(self, iwconfig=None):
""" Returns the current dbm signal strength. """
try:
- dbm_strength = int(self.wifi.GetDBMStrength(iwconfig, fast))
+ dbm_strength = int(self.wifi.GetDBMStrength(iwconfig))
except:
dbm_strength = 0
return dbm_strength
@dbus.service.method('org.wicd.daemon.wireless')
- def GetCurrentNetwork(self, iwconfig=None, fast=False):
+ def GetCurrentNetwork(self, iwconfig=None):
""" Returns the current network. """
- current_network = str(self.wifi.GetCurrentNetwork(iwconfig, fast))
+ current_network = str(self.wifi.GetCurrentNetwork(iwconfig))
return current_network
@dbus.service.method('org.wicd.daemon.wireless')
- def GetCurrentNetworkID(self, iwconfig=None, fast=False):
+ def GetCurrentNetworkID(self, iwconfig=None):
""" Returns the id of the current network, or -1 if its not found. """
- currentESSID = self.GetCurrentNetwork(iwconfig, fast)
+ currentESSID = self.GetCurrentNetwork(iwconfig)
for x in xrange(0, len(self.LastScan)):
if self.LastScan[x]['essid'] == currentESSID:
return x
@@ -744,11 +853,9 @@ class ConnectionWizard(dbus.service.Object):
return False
@dbus.service.method('org.wicd.daemon.wireless')
- def GetWirelessIP(self, fast=False):
+ def GetWirelessIP(self, ifconfig=""):
""" Returns the IP associated with the wireless interface. """
- ip = self.wifi.GetIP(fast)
- #if self.debug_mode == 1:
- #print 'returning wireless ip', ip
+ ip = self.wifi.GetIP(ifconfig)
return ip
@dbus.service.method('org.wicd.daemon.wireless')
@@ -759,14 +866,147 @@ class ConnectionWizard(dbus.service.Object):
return stat
else:
return False
+
+ @dbus.service.method('org.wicd.daemon.wireless')
+ def ReadWirelessNetworkProfile(self, id):
+ """ Reads in wireless profile as the active network """
+ cur_network = self.LastScan[id]
+ essid_key = "essid:" + cur_network["essid"]
+ bssid_key = cur_network["bssid"]
+ if self.debug_mode:
+ print bssid_key
+
+ if self.config.get(essid_key, 'use_settings_globally'):
+ return self._read_wireless_profile(cur_network, essid_key)
+ elif self.config.has_section(bssid_key):
+ return self._read_wireless_profile(cur_network, bssid_key)
+ else:
+ cur_network["has_profile"] = False
+ return "500: Profile Not Found"
+
+ def _read_wireless_profile(self, cur_network, section):
+ cur_network["has_profile"] = True
- ########## WIRED FUNCTIONS
- #################################
+ # Read the essid because we be needing to name those hidden
+ # wireless networks now - but only read it if it is hidden.
+ if cur_network["hidden"]:
+ cur_network["essid"] = misc.Noneify(self.config.get(section,
+ "essid"))
+ for x in self.config.options(section):
+ if not cur_network.has_key(x) or x.endswith("script"):
+ cur_network[x] = misc.Noneify(self.config.get(section, x))
+ for option in ['use_static_dns', 'use_global_dns', 'encryption',
+ 'use_settings_globally']:
+ cur_network[option] = bool(cur_network.get(option))
+ return "100: Loaded Profile"
+
+ @dbus.service.method('org.wicd.daemon.wireless')
+ def SaveWirelessNetworkProfile(self, id):
+ """ Writes a wireless profile to disk. """
+ def write_script_ent(prof, script):
+ self.config.set(prof, script, None)
+ cur_network = self.LastScan[id]
+ bssid_key = cur_network["bssid"]
+ essid_key = "essid:" + cur_network["essid"]
+
+ self.config.remove_section(bssid_key)
+ self.config.add_section(bssid_key)
+
+ # We want to write the essid in addition to bssid
+ # sections if global settings are enabled.
+ if cur_network["use_settings_globally"]:
+ self.config.remove_section(essid_key)
+ self.config.add_section(essid_key)
+
+ for x in cur_network:
+ self.config.set(bssid_key, x, cur_network[x])
+ if cur_network["use_settings_globally"]:
+ self.config.set(essid_key, x, cur_network[x])
+
+ write_script_ent(bssid_key, "beforescript")
+ write_script_ent(bssid_key, "afterscript")
+ write_script_ent(bssid_key, "disconnect")
+
+ if cur_network["use_settings_globally"]:
+ write_script_ent(essid_key, "beforescript")
+ write_script_ent(essid_key, "afterscript")
+ write_script_ent(essid_key, "disconnect")
+
+ self.config.write()
+
+ @dbus.service.method('org.wicd.daemon.wireless')
+ def SaveWirelessNetworkProperty(self, id, option):
+ """ Writes a particular wireless property to disk. """
+ if (option.strip()).endswith("script"):
+ print 'You cannot save script information to disk through ' + \
+ 'the daemon.'
+ return
+ config = self.config
+ cur_network = self.LastScan[id]
+ essid_key = "essid:" + cur_network["essid"]
+
+ config.set(cur_network["bssid"], option, str(cur_network[option]))
+
+ # Write the global section as well, if required.
+ if config.get(essid_key, 'use_settings_globally'):
+ config.set(essid_key, option, str(cur_network[option]))
+ config.write()
+
+ @dbus.service.method('org.wicd.daemon.wireless')
+ def RemoveGlobalEssidEntry(self, networkid):
+ """ Removes the global entry for the networkid provided. """
+ essid_key = "essid:" + str(self.LastScan[networkid])
+ self.config.remove_section(essid_key)
+
+ @dbus.service.signal(dbus_interface='org.wicd.daemon.wireless', signature='')
+ def SendStartScanSignal(self):
+ """ Emits a signal announcing a scan has started. """
+ pass
+
+ @dbus.service.signal(dbus_interface='org.wicd.daemon.wireless', signature='')
+ def SendEndScanSignal(self):
+ """ Emits a signal announcing a scan has finished. """
+ pass
+
+ def _wireless_autoconnect(self):
+ """ Attempts to autoconnect to a wireless network. """
+ print "No wired connection present, attempting to autoconnect" + \
+ "to wireless network"
+ if self.wifi.wireless_interface is None:
+ print 'Autoconnect failed because wireless interface returned None'
+ return
+
+ for x, network in enumerate(self.LastScan):
+ if bool(network["has_profile"]):
+ if self.debug_mode:
+ print network["essid"] + ' has profile'
+ if bool(network.get('automatic')):
+ print 'trying to automatically connect to...' + \
+ network["essid"]
+ self.ConnectWireless(x)
+ time.sleep(1)
+ return
+ print "Unable to autoconnect, you'll have to manually connect"
+
+###########################
+###### Wired Daemon #######
+###########################
+
+class WiredDaemon(dbus.service.Object):
+ def __init__(self, bus_name, wired=None, wifi=None, debug=False):
+ dbus.service.Object.__init__(self, bus_name=bus_name,
+ object_path="/org/wicd/daemon/wired")
+ self.wired = wired
+ self.wifi = wifi
+ self.debug_mode = debug
+ self.forced_disconnect = False
+ self.config = ConfigManager(wpath.etc + "wired-settings")
+
@dbus.service.method('org.wicd.daemon.wired')
- def GetWiredIP(self, fast=False):
+ def GetWiredIP(self, ifconfig=""):
""" Returns the wired interface's ip address. """
- ip = self.wired.GetIP(True)
+ ip = self.wired.GetIP(ifconfig)
return ip
@dbus.service.method('org.wicd.daemon.wired')
@@ -783,7 +1023,7 @@ class ConnectionWizard(dbus.service.Object):
# 1 = default profile
# 2 = show list
# 3 = last used profile
- self.set_option("Settings","wired_connect_mode", int(method))
+ self.config.set("Settings","wired_connect_mode", int(method), True)
self.wired_connect_mode = int(method)
@dbus.service.method('org.wicd.daemon.wired')
@@ -848,22 +1088,10 @@ class ConnectionWizard(dbus.service.Object):
self.wired.Disconnect()
@dbus.service.method('org.wicd.daemon.wired')
- def SetAlwaysShowWiredInterface(self, value):
- """ Sets always_show_wired_interface to the given value. """
- self.set_option("Settings", "always_show_wired_interface",
- misc.to_bool(value))
- self.always_show_wired_interface = misc.to_bool(value)
-
- @dbus.service.method('org.wicd.daemon.wired')
- def GetAlwaysShowWiredInterface(self):
- """ Returns always_show_wired_interface """
- return bool(self.always_show_wired_interface)
-
- @dbus.service.method('org.wicd.daemon.wired')
- def CheckPluggedIn(self, fast=False):
+ def CheckPluggedIn(self):
""" Returns True if a ethernet cable is present, False otherwise. """
if self.wired.wired_interface and self.wired.wired_interface != "None":
- return self.wired.CheckPluggedIn(fast)
+ return self.wired.CheckPluggedIn()
else:
return None
@@ -882,6 +1110,22 @@ class ConnectionWizard(dbus.service.Object):
""" Calls a method to disable the wired interface. """
return self.wired.DisableInterface()
+ @dbus.service.method('org.wicd.daemon.wired')
+ def GetForcedDisconnect(self):
+ """ Returns the forced_disconnect status. See SetForcedDisconnect. """
+ return bool(self.forced_disconnect)
+
+ @dbus.service.method('org.wicd.daemon.wired')
+ def SetForcedDisconnect(self, value):
+ """ Sets the forced_disconnect status.
+
+ Set to True when a user manually disconnects or cancels a connection.
+ It gets set to False as soon as the connection process is manually
+ started.
+
+ """
+ self.forced_disconnect = bool(value)
+
@dbus.service.method('org.wicd.daemon.wired')
def ConnectWired(self):
""" Connects to a wired network. """
@@ -890,142 +1134,100 @@ class ConnectionWizard(dbus.service.Object):
self.wired.after_script = self.GetWiredProperty("afterscript")
self.wired.disconnect_script = self.GetWiredProperty("disconnectscript")
self.wired.Connect(self.WiredNetwork, debug=self.debug_mode)
-
- ########## LOG FILE STUFF
- #################################
-
- @dbus.service.method('org.wicd.daemon.config')
- def DisableLogging(self):
- global logging_enabled
- logging_enabled = False
-
- @dbus.service.method('org.wicd.daemon.config')
- def EnableLogging(self):
- global logging_enabled
- logging_enabled = True
-
- ########## CONFIGURATION FILE FUNCTIONS
- #################################
-
- @dbus.service.method('org.wicd.daemon.config')
+
+ @dbus.service.method('org.wicd.daemon.wired')
def CreateWiredNetworkProfile(self, profilename, default=False):
""" Creates a wired network profile. """
profilename = misc.to_unicode(profilename)
print "Creating wired profile for " + profilename
- config = ConfigParser.ConfigParser()
- config.read(self.wired_conf)
- if config.has_section(profilename):
+ if self.config.has_section(profilename):
return False
- config.add_section(profilename)
- config.set(profilename, "ip", None)
- config.set(profilename, "broadcast", None)
- config.set(profilename, "netmask", None)
- config.set(profilename, "gateway", None)
- config.set(profilename, "dns1", None)
- config.set(profilename, "dns2", None)
- config.set(profilename, "dns3", None)
- config.set(profilename, "beforescript", None)
- config.set(profilename, "afterscript", None)
- config.set(profilename, "disconnectscript", None)
- config.set(profilename, "default", default)
- config.write(open(self.wired_conf, "w"))
+
+ for option in ["ip", "broadcast", "netmask","gateway", "dns1", "dns2",
+ "dns3", "beforescript", "afterscript",
+ "disconnectscript"]:
+ self.config.set(profilename, option, None)
+ self.config.set(profilename, "default", default)
+ self.config.write()
return True
- @dbus.service.method('org.wicd.daemon.config')
+ @dbus.service.method('org.wicd.daemon.wired')
def UnsetWiredLastUsed(self):
""" Finds the previous lastused network, and sets lastused to False. """
- config = ConfigParser.ConfigParser()
- config.read(self.wired_conf)
- profileList = config.sections()
+ profileList = self.config.sections()
for profile in profileList:
- if config.has_option(profile, "lastused"):
- if misc.to_bool(config.get(profile, "lastused")):
- config.set(profile, "lastused", False)
+ if self.config.has_option(profile, "lastused"):
+ if misc.to_bool(self.config.get(profile, "lastused")):
+ self.config.set(profile, "lastused", False)
self.SaveWiredNetworkProfile(profile)
- @dbus.service.method('org.wicd.daemon.config')
+ @dbus.service.method('org.wicd.daemon.wired')
def UnsetWiredDefault(self):
""" Unsets the default option in the current default wired profile. """
- config = ConfigParser.ConfigParser()
- config.read(self.wired_conf)
- profileList = config.sections()
+ profileList = self.config.sections()
for profile in profileList:
- if config.has_option(profile, "default"):
- if misc.to_bool(config.get(profile, "default")):
- config.set(profile, "default", False)
+ if self.config.has_option(profile, "default"):
+ if misc.to_bool(self.config.get(profile, "default")):
+ self.config.set(profile, "default", False)
self.SaveWiredNetworkProfile(profile)
- @dbus.service.method('org.wicd.daemon.config')
+ @dbus.service.method('org.wicd.daemon.wired')
def GetDefaultWiredNetwork(self):
""" Returns the current default wired network. """
- config = ConfigParser.ConfigParser()
- config.read(self.wired_conf)
- profileList = config.sections()
+ profileList = self.config.sections()
for profile in profileList:
- if config.has_option(profile, "default"):
- if misc.to_bool(config.get(profile, "default")):
+ if self.config.has_option(profile, "default"):
+ if misc.to_bool(self.config.get(profile, "default")):
return profile
return None
- @dbus.service.method('org.wicd.daemon.config')
+ @dbus.service.method('org.wicd.daemon.wired')
def GetLastUsedWiredNetwork(self):
""" Returns the profile of the last used wired network. """
- config = ConfigParser.ConfigParser()
- config.read(self.wired_conf)
- profileList = config.sections()
+ profileList = self.config.sections()
for profile in profileList:
- if config.has_option(profile,"lastused"):
- if misc.to_bool(config.get(profile,"lastused")):
+ if self.config.has_option(profile, "lastused"):
+ if misc.to_bool(self.config.get(profile, "lastused")):
return profile
return None
- @dbus.service.method('org.wicd.daemon.config')
+ @dbus.service.method('org.wicd.daemon.wired')
def DeleteWiredNetworkProfile(self, profilename):
""" Deletes a wired network profile. """
profilename = misc.to_unicode(profilename)
print "Deleting wired profile for " + str(profilename)
- config = ConfigParser.ConfigParser()
- config.read(self.wired_conf)
- if config.has_section(profilename):
- config.remove_section(profilename)
- else:
- return "500: Profile does not exist"
- config.write(open(self.wired_conf, "w"))
- return "100: Profile Deleted"
+ self.config.remove_section(profilename)
+ self.config.write()
- @dbus.service.method('org.wicd.daemon.config')
+ @dbus.service.method('org.wicd.daemon.wired')
def SaveWiredNetworkProfile(self, profilename):
""" Writes a wired network profile to disk. """
- def write_script_ent(prof, conf, script):
- if not conf.has_option(prof, script):
- conf.set(prof, script, None)
+ def write_script_ent(prof, script):
+ if not self.config.has_option(prof, script):
+ self.config.set(prof, script, None)
+
if profilename == "":
return "500: Bad Profile name"
profilename = misc.to_unicode(profilename)
- config = ConfigParser.ConfigParser()
- config.read(self.wired_conf)
- if config.has_section(profilename):
- config.remove_section(profilename)
- config.add_section(profilename)
+ self.config.remove_section(profilename)
+ self.config.add_section(profilename)
for x in self.WiredNetwork:
- config.set(profilename, x, self.WiredNetwork[x])
+ self.config.set(profilename, x, self.WiredNetwork[x])
- write_script_ent(profilename, config, "beforescript")
- write_script_ent(profilename, config, "afterscript")
- write_script_ent(profilename, config, "disconnectscript")
- config.write(open(self.wired_conf, "w"))
+ write_script_ent(profilename, "beforescript")
+ write_script_ent(profilename, "afterscript")
+ write_script_ent(profilename, "disconnectscript")
+ self.config.write()
return "100: Profile Written"
- @dbus.service.method('org.wicd.daemon.config')
+ @dbus.service.method('org.wicd.daemon.wired')
def ReadWiredNetworkProfile(self, profilename):
""" Reads a wired network profile in as the currently active profile """
profile = {}
profilename = misc.to_unicode(profilename)
- config = ConfigParser.ConfigParser()
- config.read(self.wired_conf)
- if config.has_section(profilename):
- for x in config.options(profilename):
- profile[x] = misc.Noneify(config.get(profilename, x))
+ if self.config.has_section(profilename):
+ for x in self.config.options(profilename):
+ profile[x] = misc.Noneify(self.config.get(profilename, x))
profile['use_global_dns'] = bool(profile.get('use_global_dns'))
profile['use_static_dns'] = bool(profile.get('use_static_dns'))
self.WiredNetwork = profile
@@ -1034,289 +1236,59 @@ class ConnectionWizard(dbus.service.Object):
self.WiredNetwork = None
return "500: Profile Not Found"
- @dbus.service.method('org.wicd.daemon.config')
+ @dbus.service.method('org.wicd.daemon.wired')
def GetWiredProfileList(self):
""" Returns a list of all wired profiles in wired-settings.conf. """
- config = ConfigParser.ConfigParser()
- config.read(self.wired_conf)
- if config.sections():
- return config.sections()
- else:
- return None
-
- @dbus.service.method('org.wicd.daemon.config')
- def SaveWirelessNetworkProfile(self, id):
- """ Writes a wireless profile to disk. """
- def write_script_ent(prof, conf, script):
- if not conf.has_option(prof, script):
- conf.set(prof, script, None)
-
- config = ConfigParser.ConfigParser()
- config.read(self.wireless_conf)
- cur_network = self.LastScan[id]
- bssid_key = cur_network["bssid"]
- essid_key = "essid:" + cur_network["essid"]
-
- if config.has_section(bssid_key):
- config.remove_section(bssid_key)
- config.add_section(bssid_key)
-
- # We want to write the essid in addition to bssid
- # sections if global settings are enabled.
- if cur_network["use_settings_globally"]:
- if config.has_section(essid_key):
- config.remove_section(essid_key)
- config.add_section(essid_key)
-
- for x in cur_network:
- config.set(bssid_key, x, cur_network[x])
- if cur_network["use_settings_globally"]:
- config.set(essid_key, x, cur_network[x])
-
- write_script_ent(bssid_key, config, "beforescript")
- write_script_ent(bssid_key, config, "afterscript")
- write_script_ent(bssid_key, config, "disconnect")
-
- if cur_network["use_settings_globally"]:
- write_script_ent(essid_key, config, "beforescript")
- write_script_ent(essid_key, config, "afterscript")
- write_script_ent(essid_key, config, "disconnect")
-
- config.write(open(self.wireless_conf, "w"))
-
- @dbus.service.method('org.wicd.daemon.config')
- def SaveWirelessNetworkProperty(self, id, option):
- """ Writes a particular wireless property to disk. """
- if (option.strip()).endswith("script"):
- print 'You cannot save script information to disk through ' + \
- 'the daemon.'
+ return self.config.sections()
+
+ def _wired_autoconnect(self):
+ """ Attempts to autoconnect to a wired network. """
+ if self.GetWiredAutoConnectMethod() == 3 and \
+ not self.GetNeedWiredProfileChooser():
+ # attempt to smartly connect to a wired network
+ # by using various wireless networks detected
+ # and by using plugged in USB devices
+ print self.LastScan
+ if self.GetWiredAutoConnectMethod() == 2 and \
+ not self.GetNeedWiredProfileChooser():
+ self.LaunchChooser()
return
- cur_network = self.LastScan[id]
- essid_key = "essid:" + cur_network["essid"]
- config = ConfigParser.ConfigParser()
- config.read(self.wireless_conf)
- if config.has_section(cur_network["bssid"]):
- config.set(cur_network["bssid"], option,
- str(cur_network[option]))
+ # Default Profile.
+ elif self.GetWiredAutoConnectMethod() == 1:
+ network = self.GetDefaultWiredNetwork()
+ if not network:
+ print "Couldn't find a default wired connection," + \
+ " wired autoconnect failed."
+ self._wireless_autoconnect()
+ return
- # Write the global section as well, if required.
- if config.has_section(essid_key):
- if config.get(essid_key, 'use_settings_globally'):
- config.set(essid_key, option, str(cur_network[option]))
-
- config.write(open(self.wireless_conf, "w"))
-
- @dbus.service.method('org.wicd.daemon.config')
- def RemoveGlobalEssidEntry(self, networkid):
- """ Removes the global entry for the networkid provided. """
- config = ConfigParser.ConfigParser()
- config.read(self.wireless_conf)
- cur_network = self.LastScan[networkid]
- essid_key = "essid:" + cur_network["essid"]
- if config.has_section(essid_key):
- config.remove_section(essid_key)
-
- @dbus.service.method('org.wicd.daemon.config')
- def ReadWirelessNetworkProfile(self, id):
- """ Reads in wireless profile as the active network """
- config = ConfigParser.ConfigParser()
- config.read(self.wireless_conf)
- cur_network = self.LastScan[id]
- essid_key = "essid:" + cur_network["essid"]
- bssid_key = cur_network["bssid"]
- if self.debug_mode:
- print bssid_key
- if config.has_section(essid_key):
- if config.get(essid_key, 'use_settings_globally'):
- return self._read_wireless_profile(config, cur_network,
- essid_key)
- elif config.has_section(bssid_key):
- return self._read_wireless_profile(config, cur_network, bssid_key)
+ # Last-Used.
else:
- cur_network["has_profile"] = False
- return "500: Profile Not Found"
-
- def _read_wireless_profile(self, config, cur_network, section):
- cur_network["has_profile"] = True
+ network = self.GetLastUsedWiredNetwork()
+ if not network:
+ print "no previous wired profile available, wired " + \
+ "autoconnect failed."
+ self._wireless_autoconnect()
+ return
- # Read the essid because we be needing to name those hidden
- # wireless networks now - but only read it if it is hidden.
- if cur_network["hidden"]:
- cur_network["essid"] = misc.Noneify(config.get(section,
- "essid"))
- for x in config.options(section):
- if not cur_network.has_key(x) or x.endswith("script"):
- cur_network[x] = misc.Noneify(config.get(section,
- x))
- for option in ['use_static_dns', 'use_global_dns', 'encryption',
- 'use_settings_globally']:
- cur_network[option] = bool(cur_network.get(option))
- return "100: Loaded Profile"
+ self.ReadWiredNetworkProfile(network)
+ self.ConnectWired()
+ print "Attempting to autoconnect with wired interface..."
+ self.auto_connecting = True
+ time.sleep(1.5)
+ gobject.timeout_add(3000, self._monitor_wired_autoconnect)
- @dbus.service.method('org.wicd.daemon.config')
- def WriteWindowSize(self, width, height, win_name):
- """Write the desired default window size"""
- if win_name == "main":
- height_str = "window_height"
- width_str = "window_width"
- else:
- height_str = "pref_height"
- width_str = "pref_width"
- config = ConfigParser.ConfigParser()
- config.read(self.app_conf)
- if config.has_section("Settings"):
- config.set("Settings", width_str, width)
- config.set("Settings", height_str, height)
- config.write(open(self.app_conf, "w"))
-
- @dbus.service.method('org.wicd.daemon.config')
- def ReadWindowSize(self, win_name):
- """Returns a list containing the desired default window size
-
- Attempts to read the default size from the config file,
- and if that fails, returns a default of 605 x 400.
-
- """
- if win_name == "main":
- default_width = 605
- default_height = 400
- width_str = "window_width"
- height_str = "window_height"
- else:
- default_width = 125
- default_height = 590
- width_str = "pref_width"
- height_str = "pref_height"
-
- width = self.get_option("Settings", width_str, default_width)
- height = self.get_option("Settings", height_str, default_height)
-
- size = []
- size.append(int(width))
- size.append(int(height))
- return size
-
- #############################################
- ########## INTERNAL FUNCTIONS ###############
- #############################################
- # so don't touch the stuff below #
- # it read/writes the configuration files #
- # and shouldn't need to be changed #
- # unless you add a new property... #
- # then be SURE YOU CHANGE IT #
- #############################################
-
- def __printReturn(self, text, value):
- """prints the specified text and value, then returns the value"""
- if self.debug_mode:
- print ''.join([text, " ", str(value)])
- return value
-
- def set_option(self, section, option, value):
- """ Sets the given option to the given value. """
- config = ConfigParser.ConfigParser()
- config.read(self.app_conf)
- config.set(section, option, value)
- configfile = open(self.app_conf, "w")
- config.write(configfile)
-
- def get_option(self, section, option, default=None):
- """ Method for returning an option from manager-settings.conf.
-
- This method will return a given option from a given section
-
- """
- config = ConfigParser.ConfigParser()
- config.read(self.app_conf)
- if not config.has_section(section):
- config.add_section(section)
-
- if config.has_option(section, option):
- ret = config.get(section, option)
- print ''.join(['found ', option, ' in configuration ', ret])
- else:
- config.set(section, option, default)
- ret = default
- config.write(open(self.app_conf, "w"))
- return ret
-
- def ReadConfig(self):
- """ Reads the manager-settings.conf file.
-
- Reads the manager-settings.conf file and loads the stored
- values into memory.
-
- """
- iface = self.DetectWirelessInterface()
- if not iface: iface = 'wlan0'
- self.SetWirelessInterface(self.get_option("Settings",
- "wireless_interface",
- default=iface))
-
- iface = self.DetectWiredInterface()
- if not iface: iface = 'eth0'
- self.SetWiredInterface(self.get_option("Settings", "wired_interface",
- default=iface))
-
- self.SetWPADriver(self.get_option("Settings", "wpa_driver",
- default="wext"))
- self.SetAlwaysShowWiredInterface(self.get_option("Settings",
- "always_show_wired_interface",
- default=False))
- self.SetUseGlobalDNS(self.get_option("Settings", "use_global_dns",
- default=False))
- dns1 = self.get_option("Settings", "global_dns_1", default='None')
- dns2 = self.get_option("Settings", "global_dns_2", default='None')
- dns3 = self.get_option("Settings", "global_dns_3", default='None')
- self.SetGlobalDNS(dns1, dns2, dns3)
- self.SetAutoReconnect(self.get_option("Settings", "auto_reconnect",
- default=True))
- self.SetDebugMode(self.get_option("Settings", "debug_mode",
- default=False))
-
- self.SetWiredAutoConnectMethod(self.get_option("Settings",
- "wired_connect_mode",
- default=1))
- self.SetSignalDisplayType(self.get_option("Settings",
- "signal_display_type",
- default=0))
- self.SetDHCPClient(self.get_option("Settings", "dhcp_client",
- default=0))
- self.SetLinkDetectionTool(self.get_option("Settings",
- "link_detect_tool",
- default=0))
- self.SetFlushTool(self.get_option("Settings", "flush_tool", default=0))
-
- if os.path.isfile(self.wireless_conf):
- print "Wireless configuration file found..."
- else:
- print "Wireless configuration file not found, creating..."
- open(self.wireless_conf, "w").close()
-
- if os.path.isfile(self.wired_conf):
- print "Wired configuration file found..."
- else:
- print "Wired configuration file not found, creating a default..."
- # Create the file and a default profile
- open(self.wired_conf, "w").close()
- self.CreateWiredNetworkProfile("wired-default", default=True)
-
- # Hide the files, so the keys aren't exposed.
- print "chmoding configuration files 0600..."
- os.chmod(self.app_conf, 0600)
- os.chmod(self.wireless_conf, 0600)
- os.chmod(self.wired_conf, 0600)
-
- # Make root own them
- print "chowning configuration files root:root..."
- os.chown(self.app_conf, 0, 0)
- os.chown(self.wireless_conf, 0, 0)
- os.chown(self.wired_conf, 0, 0)
-
- print "Using wireless interface..." + self.GetWirelessInterface()
- print "Using wired interface..." + self.GetWiredInterface()
-
+ def _monitor_wired_autoconnect(self):
+ if self.CheckIfWiredConnecting():
+ return True
+ elif self.GetWiredIP():
+ self.auto_connecting = False
+ return False
+ elif not self.CheckIfWirelessConnecting():
+ self._wireless_autoconnect()
+ self.auto_connecting = False
+ return False
def usage():
print """
@@ -1362,7 +1334,13 @@ def daemonize():
try:
pid = os.fork()
if pid > 0:
- print "wicd daemon: pid " + str(pid)
+ print wpath.pidfile
+ dirname = os.path.dirname(wpath.pidfile)
+ if not os.path.exists(dirname):
+ os.makedirs(dirname)
+ pidfile = open(wpath.pidfile, 'w')
+ pidfile.write(str(pid) + '\n')
+ pidfile.close()
sys.exit(0)
except OSError, e:
print >> sys.stderr, "Fork #2 failed: %d (%s)" % (e.errno, e.strerror)
@@ -1378,7 +1356,6 @@ def daemonize():
sys.stdin = open('/dev/null', 'r')
-
def main(argv):
""" The main daemon program.
@@ -1390,17 +1367,17 @@ def main(argv):
do_daemonize = True
redirect_stderr = True
redirect_stdout = True
- auto_scan = True
+ auto_connect = True
try:
- opts, args = getopt.getopt(sys.argv[1:], 'fenoah:',
+ opts, args = getopt.getopt(sys.argv[1:], 'fenoah',
['help', 'no-daemon', 'no-poll', 'no-stderr', 'no-stdout',
'no-autoconnect'])
except getopt.GetoptError:
# Print help information and exit
usage()
sys.exit(2)
-
+
no_poll = False
for o, a in opts:
if o in ('-h', '--help'):
@@ -1413,13 +1390,20 @@ def main(argv):
if o in ('-f', '--no-daemon'):
do_daemonize = False
if o in ('-a', '--no-autoconnect'):
- auto_scan = False
+ auto_connect = False
if o in ('-n', '--no-poll'):
no_poll = True
if do_daemonize: daemonize()
- if redirect_stderr or redirect_stdout: output = ManagedStdio(wpath.log + 'wicd.log')
+ if redirect_stderr or redirect_stdout:
+ logpath = os.path.join(wpath.log, 'wicd.log')
+ output = ManagedStdio(logpath)
+ if os.path.exists(logpath):
+ try:
+ os.chmod(logpath, 0600)
+ except:
+ print 'unable to chmod log file to 0600'
if redirect_stdout: sys.stdout = output
if redirect_stderr: sys.stderr = output
@@ -1428,13 +1412,13 @@ def main(argv):
print '---------------------------'
# Open the DBUS session
-
- d_bus_name = dbus.service.BusName('org.wicd.daemon', bus=dbus.SystemBus())
- obj = ConnectionWizard(d_bus_name, auto_connect=auto_scan)
+ bus = dbus.SystemBus()
+ wicd_bus = dbus.service.BusName('org.wicd.daemon', bus=bus)
+ daemon = WicdDaemon(wicd_bus, auto_connect=auto_scan)
gobject.threads_init()
if not no_poll:
- (child_pid, x, x, x) = gobject.spawn_async([wpath.bin + "monitor.py"],
+ (child_pid, x, x, x) = gobject.spawn_async([wpath.lib + "monitor.py"],
flags=gobject.SPAWN_CHILD_INHERITS_STDIN)
signal.signal(signal.SIGTERM, sigterm_caught)
@@ -1447,6 +1431,9 @@ def sigterm_caught(sig, frame):
global child_pid
print 'SIGTERM caught, killing wicd-monitor...'
os.kill(child_pid, signal.SIGTERM)
+ print 'Removing PID file...'
+ if os.path.exists(wpath.pidfile):
+ os.remove(wpath.pidfile)
print 'Shutting down...'
sys.exit(0)
diff --git a/wicd/wnettools.py b/wicd/wnettools.py
index 5674784..3f1035e 100644
--- a/wicd/wnettools.py
+++ b/wicd/wnettools.py
@@ -31,59 +31,23 @@ class WirelessInterface() -- Control a wireless network interface.
# along with this program. If not, see .
#
-import re
import os
import time
-import socket
-import fcntl
-import struct
-import array
+import re
-import wicd.wpath as wpath
-import wicd.misc as misc
-
-# Compile the regex patterns that will be used to search the output of iwlist
-# scan for info these are well tested, should work on most cards
-essid_pattern = re.compile('.*ESSID:"(.*?)"\n', re.I | re.M | re.S)
-ap_mac_pattern = re.compile('.*Address: (.*?)\n', re.I | re.M | re.S)
-channel_pattern = re.compile('.*Channel:? ?(\d\d?)', re.I | re.M | re.S)
-strength_pattern = re.compile('.*Quality:?=? ?(\d+)\s*/?\s*(\d*)', re.I | re.M | re.S)
-# These next two look a lot a like, altstrength is for Signal level = xx/100,
-# which is just an alternate way of displaying link quality, signaldbm is
-# for displaying actual signal strength (-xx dBm).
-altstrength_pattern = re.compile('.*Signal level:?=? ?(\d\d*)', re.I | re.M | re.S)
-signaldbm_pattern = re.compile('.*Signal level:?=? ?(-\d\d*)', re.I | re.M | re.S)
-mode_pattern = re.compile('.*Mode:(.*?)\n', re.I | re.M | re.S)
-freq_pattern = re.compile('.*Frequency:(.*?)\n', re.I | re.M | re.S)
-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.I | re.M | re.S)
-
-wep_pattern = re.compile('.*Encryption key:(.*?)\n', re.I | re.M | re.S)
-altwpa_pattern = re.compile('(wpa_ie)', re.I | re.M | re.S)
-wpa1_pattern = re.compile('(WPA Version 1)', re.I | re.M | re.S)
-wpa2_pattern = re.compile('(WPA2)', re.I | re.M | re.S)
-
-# Patterns for wpa_cli output
-auth_pattern = re.compile('.*wpa_state=(.*?)\n', re.I | re.M | re.S)
+import wpath
+import misc
RALINK_DRIVER = 'ralink legacy'
-SIOCGIWESSID = 0x8B1B
-SIOCGIFADDR = 0x8915
-SIOCGIWSTATS = 0x8B0F
-SIOCGIFHWADDR = 0x8927
-SIOCGMIIPHY = 0x8947
-SIOCGETHTOOL = 0x8946
-SIOCGIFFLAGS = 0x8913
-SIOCGIWRANGE = 0x8B0B
-SIOCGIWAP = 0x8B15
+
def _sanitize_string(string):
blacklist = [';', '`', '$', '!', '*', '|', '>', '<']
new_string = []
-
+
if not string:
return string
-
+
for c in string:
if c in blacklist:
new_string.append("\\" + c)
@@ -102,7 +66,7 @@ def SetDNS(dns1=None, dns2=None, dns3=None):
dns3 -- IP address of DNS server 1
"""
- resolv = open("/etc/resolv.conf","w")
+ resolv = open("/etc/resolv.conf", "w")
for dns in [dns1, dns2, dns3]:
if dns:
if misc.IsValidIP(dns):
@@ -147,42 +111,24 @@ def GetWirelessInterfaces():
dev_dir = '/sys/class/net/'
ifnames = []
- ifnames = [iface for iface in os.listdir(dev_dir) if os.path.isdir(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 bool(ifnames) and ifnames[0] or None
def GetWiredInterfaces():
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 not 'wireless'
+ in os.listdir(basedir + iface) and
open(basedir + iface + "/type").readlines()[0].strip() == "1"]
+def NeedsExternalCalls():
+ print ("NeedsExternalCalls: returning default of True. You should " +
+ "implement this yourself.")
+ return True
-def get_iw_ioctl_result(iface, call):
- """ Makes the given ioctl call and returns the results.
-
- Keyword arguments:
- call -- The ioctl call to make
-
- Returns:
- The results of the ioctl call.
-
- """
- s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
- buff = array.array('c', '\0' * 32)
- addr, length = buff.buffer_info()
- arg = struct.pack('Pi', addr, length)
- data = (iface + '\0' * 16)[:16] + arg
- try:
- result = fcntl.ioctl(s.fileno(), call, data)
- except IOError:
- return None
- except OSError:
- return None
- return buff.tostring()
-class Interface(object):
+class BaseInterface(object):
""" Control a network interface. """
def __init__(self, iface, verbose=False):
""" Initialise the object.
@@ -201,10 +147,8 @@ class Interface(object):
self.ETHTOOL_FOUND = False
self.IP_FOUND = False
self.flush_tool = None
- self.link_detect = None
- self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
- self.Check()
-
+ self.link_detect = None
+
def SetDebugMode(self, value):
""" If True, verbose output is enabled. """
self.verbose = value
@@ -548,7 +492,7 @@ class Interface(object):
gw -- gateway of the default route in dotted quad form
"""
- if not self.iface: return
+ if not self.iface: return
if not misc.IsValidIP(gw):
print 'WARNING: Invalid gateway found. Aborting!'
return False
@@ -556,77 +500,28 @@ class Interface(object):
if self.verbose: print cmd
misc.Run(cmd)
- def GetIP(self, fast=False):
+ def GetIP(self, ifconfig=""):
""" Get the IP address of the interface.
Returns:
The IP address of the interface in dotted quad form.
"""
- if not self.iface: return False
- if fast:
- return self._fast_get_ip()
- cmd = 'ifconfig ' + self.iface
- if self.verbose: print cmd
- output = misc.Run(cmd)
- return misc.RunRegex(ip_pattern, output)
+ print 'Implement this in a derived class!'
+ pass
- def _fast_get_ip(self):
- """ Gets the IP Address of the interface using ioctl.
-
- Using ioctl calls to get the IP Address info is MUCH faster
- than calling ifconfig and paring it's output. It's less
- portable though, so there may be problems with it on some
- systems.
-
- """
- ifstruct = struct.pack('256s', self.iface)
- try:
- raw_ip = fcntl.ioctl(self.sock.fileno(), SIOCGIFADDR, ifstruct)
- except IOError:
- return None
- except OSError:
- return None
-
- return socket.inet_ntoa(raw_ip[20:24])
-
- def IsUp(self, fast=True):
+ def IsUp(self):
""" Determines if the interface is up.
Returns:
True if the interface is up, False otherwise.
"""
- if not self.iface: return False
- if fast:
- return self._fast_is_up()
- cmd = "ifconfig " + self.iface
- output = misc.Run(cmd)
- lines = output.split('\n')
- if len(lines) < 5:
- return False
-
- for line in lines[1:4]:
- if line.strip().startswith('UP'):
- return True
-
- return False
-
- def _fast_is_up(self):
- """ Determines if the interfae is up using an ioctl call. """
- data = (self.iface + '\0' * 16)[:18]
- try:
- result = fcntl.ioctl(self.sock.fileno(), SIOCGIFFLAGS, data)
- except IOError, e:
- if self.verbose:
- print "SIOCGIFFLAGS failed: " + str(e)
- return False
-
- flags, = struct.unpack('H', result[16:18])
- return bool(flags & 1)
+ print 'Implement this in a derived class!'
+ pass
-class WiredInterface(Interface):
+class BaseWiredInterface(BaseInterface):
""" Control a wired network interface. """
def __init__(self, iface, verbose=False):
""" Initialise the wired network interface class.
@@ -636,9 +531,9 @@ class WiredInterface(Interface):
verbose -- print all commands
"""
- Interface.__init__(self, iface, verbose)
+ BaseInterface.__init__(self, iface, verbose)
- def GetPluggedIn(self, fast=False):
+ def GetPluggedIn(self):
""" Get the current physical connection state.
The method will first attempt to use ethtool do determine
@@ -649,104 +544,11 @@ class WiredInterface(Interface):
True if a link is detected, False otherwise.
"""
- if not self.iface: return False
- if self.ETHTOOL_FOUND and self.link_detect != misc.MIITOOL:
- return self._eth_get_plugged_in(fast)
- elif self.MIITOOL_FOUND:
- return self._mii_get_plugged_in(fast)
- else:
- print 'Error: No way of checking for a wired connection. Make \
- sure that either mii-tool or ethtool is installed.'
- return False
-
- def _eth_get_plugged_in(self, fast):
- """ Use ethtool to determine the physical connection state.
-
- Returns:
- True if a link is detected, False otherwise.
-
- """
- if fast:
- self._fast_eth_get_plugged_in()
- link_tool = 'ethtool'
- if not self.IsUp():
- print 'Wired Interface is down, putting it up'
- self.Up()
- time.sleep(6)
- tool_data = misc.Run(link_tool + ' ' + self.iface, True)
- if misc.RunRegex(re.compile('(Link detected: yes)', re.I | re.M |
- re.S), tool_data) is not None:
- return True
- else:
- return False
-
- def _fast_eth_get_plugged_in(self):
- """ Determines link connection status using an ioctl call.
-
- Uses the SIOCGETHTOOL ioctl call to determine link status.
-
- Returns:
- True if a wire is plugged in, False otherwise.
-
- """
- if not self.IsUp():
- self.Up()
- time.sleep(5)
- buff = array.array('i', [0x0000000a, 0x00000000])
- addr, length = buff.buffer_info()
- arg = struct.pack('Pi', addr, length)
- data = (self.iface + '\0' * 16)[:16] + arg
- try:
- fcntl.ioctl(self.sock.fileno(), SIOCGETHTOOL, data)
- except IOError, e:
- if self.verbose:
- print 'SIOCGETHTOOL failed: ' + str(e)
- return False
- return bool(buff.tolist()[1])
-
-
- def _mii_get_plugged_in(self, fast):
- """ Use mii-tool to determine the physical connection state.
-
- Returns:
- True if a link is detected, False otherwise.
-
- """
- if fast:
- return self._fast_mii_get_plugged_in()
- link_tool = 'mii-tool'
- tool_data = misc.Run(link_tool + ' ' + self.iface, True)
- if misc.RunRegex(re.compile('(Invalid argument)', re.I | re.M | re.S),
- tool_data) is not None:
- print 'Wired Interface is down, putting it up'
- self.Up()
- time.sleep(4)
- tool_data = misc.Run(link_tool + ' ' + self.iface, True)
-
- if misc.RunRegex(re.compile('(link ok)', re.I | re.M | re.S),
- tool_data) is not None:
- return True
- else:
- return False
-
- def _fast_mii_get_plugged_in(self):
- """ Get link status using the SIOCGMIIPHY ioctl call. """
- if not self.IsUp():
- self.Up()
- time.sleep(2.5)
- buff = struct.pack('16shhhh', (self.iface + '\0' * 16)[:16], 0, 1,
- 0x0004, 0)
- try:
- result = fcntl.ioctl(self.sock.fileno(), SIOCGMIIPHY, buff)
- except IOError, e:
- if self.verbose:
- print 'SIOCGMIIPHY failed: ' + str(e)
- return False
- reg = struct.unpack('16shhhh', result)[-1]
- return bool(reg & 0x0004)
+ print 'Implement this in a derived class!'
+ pass
-class WirelessInterface(Interface):
+class BaseWirelessInterface(BaseInterface):
""" Control a wireless network interface. """
def __init__(self, iface, verbose=False, wpa_driver='wext'):
""" Initialise the wireless network interface class.
@@ -756,7 +558,7 @@ class WirelessInterface(Interface):
verbose -- print all commands
"""
- Interface.__init__(self, iface, verbose)
+ BaseInterface.__init__(self, iface, verbose)
self.wpa_driver = wpa_driver
self.scan_iface = None
@@ -790,7 +592,7 @@ class WirelessInterface(Interface):
"""
if not self.iface: return False
- output = misc.Run("iwconfig " + self.iface)
+ output = self.GetIwconfig()
killswitch_pattern = re.compile('.*radio off', re.I | re.M | re.S)
if killswitch_pattern.search(output):
@@ -803,43 +605,9 @@ class WirelessInterface(Interface):
def GetIwconfig(self):
""" Returns the output of iwconfig for this interface. """
if not self.iface: return ""
- return misc.Run("iwconfig " + self.iface)
-
- def GetNetworks(self):
- """ Get a list of available wireless networks.
-
- Returns:
- A list containing available wireless networks.
-
- """
- cmd = 'iwlist ' + self.iface + ' scan'
+ cmd = "iwconfig " + self.iface
if self.verbose: print cmd
- results = misc.Run(cmd)
-
- # Split the networks apart, using Cell as our split point
- # this way we can look at only one network at a time.
- # The spaces around ' Cell ' are to minimize the chance that someone
- # has an essid named Cell...
- networks = results.split( ' Cell ' )
-
- # Get available network info from iwpriv get_site_survey
- # if we're using a ralink card (needed to get encryption info)
- if self.wpa_driver == RALINK_DRIVER:
- ralink_info = self._GetRalinkInfo()
- else:
- ralink_info = None
-
- # An array for the 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)
-
- return access_points
+ return misc.Run(cmd)
def _FreqToChannel(self, freq):
""" Translate the specified frequency to a channel.
@@ -880,90 +648,6 @@ class WirelessInterface(Interface):
lines = lines[2:]
return lines
- def _ParseAccessPoint(self, cell, ralink_info):
- """ Parse a single cell from the output of iwlist.
-
- Keyword arguments:
- cell -- string containing the cell information
- ralink_info -- string contating network information needed
- for ralink cards.
-
- Returns:
- A dictionary containing the cell networks properties.
-
- """
- ap = {}
- # ESSID - Switch '' to 'Hidden' to remove
- # brackets that can mix up formatting.
- ap['essid'] = misc.RunRegex(essid_pattern, cell)
- try:
- ap['essid'] = misc.to_unicode(ap['essid'])
- except (UnicodeDecodeError, UnicodeEncodeError):
- print 'Unicode problem with current network essid, ignoring!!'
- return None
- if ap['essid'] in ['', ""]:
- ap['essid'] = 'Hidden'
- ap['hidden'] = True
- else:
- ap['hidden'] = False
-
- # Channel - For cards that don't have a channel number,
- # convert the frequency.
- ap['channel'] = misc.RunRegex(channel_pattern, cell)
- if ap['channel'] == None:
- freq = misc.RunRegex(freq_pattern, cell)
- ap['channel'] = self._FreqToChannel(freq)
-
- # BSSID
- ap['bssid'] = misc.RunRegex(ap_mac_pattern, cell)
-
- # Mode
- ap['mode'] = misc.RunRegex(mode_pattern, cell)
-
- # Break off here if we're using a ralink card
- if self.wpa_driver == RALINK_DRIVER:
- ap = self._ParseRalinkAccessPoint(ap, ralink_info, cell)
- elif misc.RunRegex(wep_pattern, cell) == 'on':
- # Encryption - Default to WEP
- ap['encryption'] = True
- ap['encryption_method'] = 'WEP'
-
- if misc.RunRegex(wpa1_pattern, cell) == 'WPA Version 1':
- ap['encryption_method'] = 'WPA'
-
- if misc.RunRegex(altwpa_pattern, cell) == 'wpa_ie':
- ap['encryption_method'] = 'WPA'
-
- if misc.RunRegex(wpa2_pattern, cell) == 'WPA2':
- ap['encryption_method'] = 'WPA2'
- else:
- ap['encryption'] = False
-
- # Link Quality
- # Set strength to -1 if the quality is not found
-
- # more of the patch from
- # https://bugs.launchpad.net/wicd/+bug/175104
- if (strength_pattern.match(cell)):
- [(strength, max_strength)] = strength_pattern.findall(cell)
- if max_strength:
- ap["quality"] = 100 * int(strength) // int(max_strength)
- else:
- ap["quality"] = int(strength)
- elif misc.RunRegex(altstrength_pattern,cell):
- ap['quality'] = misc.RunRegex(altstrength_pattern, cell)
- else:
- ap['quality'] = -1
-
- # Signal Strength (only used if user doesn't want link
- # quality displayed or it isn't found)
- if misc.RunRegex(signaldbm_pattern, cell):
- ap['strength'] = misc.RunRegex(signaldbm_pattern, cell)
- elif self.wpa_driver != RALINK_DRIVER: # This is already set for ralink
- ap['strength'] = -1
-
- return ap
-
def _ParseRalinkAccessPoint(self, ap, ralink_info, cell):
""" Parse encryption and signal strength info for ralink cards
@@ -1101,52 +785,8 @@ class WirelessInterface(Interface):
False otherwise.
"""
- # Right now there's no way to do this for ralink drivers
- if self.wpa_driver == RALINK_DRIVER or not self.WPA_CLI_FOUND:
- return True
-
- MAX_TIME = 15
- MAX_DISCONNECTED_TIME = 3
- while (time.time() - auth_time) < MAX_TIME:
- cmd = 'wpa_cli -i ' + self.iface + ' status'
- output = misc.Run(cmd)
- result = misc.RunRegex(auth_pattern, output)
- if self.verbose:
- print 'WPA_CLI RESULT IS', result
-
- if not result:
- print "WARNING: Received an unexpected result from wpa_cli!" + \
- "\nMake sure you're using the right wpa_supplicant " + \
- "driver (you probably want wext).\nIf the problem " + \
- "persists, please file a bug report."
- return False
- if result == "COMPLETED":
- return True
- elif result == "DISCONNECTED" and \
- (time.time() - auth_time) > MAX_DISCONNECTED_TIME:
- # Force a rescan to get wpa_supplicant moving again.
- self._ForceSupplicantScan()
- MAX_TIME += 5
- time.sleep(1)
-
- print 'wpa_supplicant authentication may have failed.'
- return False
-
-
- def _ForceSupplicantScan(self):
- """ Force wpa_supplicant to rescan available networks.
-
- This function forces wpa_supplicant to rescan.
- This works around authentication validation sometimes failing for
- wpa_supplicant because it remains in a DISCONNECTED state for
- quite a while, after which a rescan is required, and then
- attempting to authenticate. This whole process takes a long
- time, so we manually speed it up if we see it happening.
-
- """
- print 'wpa_supplicant rescan forced...'
- cmd = 'wpa_cli -i' + self.iface + ' scan'
- misc.Run(cmd)
+ print 'Implement this in a derived class!'
+ pass
def _AuthenticateRalinkLegacy(self, network):
""" Authenticate with the specified wireless network.
@@ -1205,154 +845,38 @@ class WirelessInterface(Interface):
if self.verbose: print cmd
misc.Run(cmd)
- def GetBSSID(self, iwconfig="", fast=True):
+ def GetBSSID(self, iwconfig=None):
""" Get the MAC address for the interface. """
- if not self.iface: return ""
- if fast:
- return self._fast_get_bssid()
- else:
- if not iwconfig:
- cmd = 'iwconfig ' + self.iface
- if self.verbose: print cmd
- output = misc.Run(cmd)
- else:
- output = iwconfig
-
- bssid = misc.RunRegex(bssid_pattern, output)
- return bssid
-
- def _fast_get_bssid(self):
- """ Gets the MAC address for the connected AP using ioctl calls. """
- data = (self.iface + '\0' * 32)[:32]
- try:
- result = fcntl.ioctl(self.sock.fileno(), SIOCGIWAP, data)[16:]
- except IOError, e:
- if self.verbose:
- print "SIOCGIWAP failed: " + str(e)
- return ""
- raw_addr = struct.unpack("xxBBBBBB", result[:8])
- return "%02X:%02X:%02X:%02X:%02X:%02X" % raw_addr
-
+ print 'Implement this in a derived class!'
+ pass
-
- def GetSignalStrength(self, iwconfig=None, fast=False):
+ def GetSignalStrength(self, iwconfig=None):
""" Get the signal strength of the current network.
Returns:
The signal strength.
"""
- if not self.iface: return -1
- if fast:
- return self._get_signal_strength_fast()
-
- if not iwconfig:
- cmd = 'iwconfig ' + self.iface
- if self.verbose: print cmd
- output = misc.Run(cmd)
- else:
- output = iwconfig
-
- [(strength, max_strength)] = strength_pattern.findall(output)
- if max_strength and strength:
- return 100 * int(strength) // int(max_strength)
-
- if strength is None:
- strength = misc.RunRegex(altstrength_pattern, output)
-
- return strength
+ print 'Implement this in a derived class!'
+ pass
- def _get_signal_strength_fast(self):
- """ Get the link quality using ioctl calls. """
- buff = get_iw_ioctl_result(self.iface, SIOCGIWSTATS)
- strength = ord(buff[2])
- max_strength = self._get_max_strength_fast()
- if strength and max_strength:
- return 100 * int(strength) // int(max_strength)
-
- return strength
-
- def _get_max_strength_fast(self):
- """ Gets the maximum possible strength from the wireless driver. """
- buff = array.array('c', '\0' * 700)
- addr, length = buff.buffer_info()
- arg = struct.pack('Pi', addr, length)
- iwfreq = (self.iface + '\0' * 16)[:16] + arg
- try:
- result = fcntl.ioctl(self.sock.fileno(), SIOCGIWRANGE, iwfreq)
- except IOError, e:
- if self.verbose:
- print "SIOCGIWRANGE failed: " + str(e)
- return None
- # This defines the iwfreq struct, used to get signal strength.
- fmt = "iiihb6ii4B4Bi32i2i2i2i2i3h8h2b2bhi8i2b3h2i2ihB17x" + 32 * "ihbb"
- size = struct.calcsize(fmt)
- data = buff.tostring()
- data = data[0:size]
- values = struct.unpack(fmt, data)
- return values[12]
-
- def GetDBMStrength(self, iwconfig=None, fast=False):
+ def GetDBMStrength(self, iwconfig=None):
""" Get the dBm signal strength of the current network.
Returns:
The dBm signal strength.
"""
- if not self.iface: return -100
- if fast:
- return self._get_dbm_strength_fast()
- if iwconfig:
- cmd = 'iwconfig ' + self.iface
- if self.verbose: print cmd
- output = misc.Run(cmd)
- else:
- output = iwconfig
- dbm_strength = misc.RunRegex(signaldbm_pattern, output)
- return dbm_strength
-
- def _get_dbm_strength_fast(self):
- """ Uses the SIOCGIWSTATS ioctl call to get dbm signal strength.
-
- Returns:
- The dBm signal strength or None if it can't be found.
-
- """
- buff = misc.get_irwange_ioctl_result(self.iface, SIOCGIWSTATS)
- if not buff:
- return None
+ print 'Implement this in a derived class!'
+ pass
- return str((ord(buff[3]) - 256))
-
-
- def GetCurrentNetwork(self, iwconfig=None, fast=False):
+ def GetCurrentNetwork(self, iwconfig=None):
""" Get the essid of the current network.
Returns:
The current network essid.
"""
- if not self.iface: return ""
- if fast:
- return self._get_essid_fast()
-
- if not iwconfig:
- cmd = 'iwconfig ' + self.iface
- if self.verbose: print cmd
- output = misc.Run(cmd)
- else:
- output = iwconfig
- network = misc.RunRegex(re.compile('.*ESSID:"(.*?)"',
- re.I | re.M | re.S), output)
- if network:
- network = misc.to_unicode(network)
- return network
-
- def _get_essid_fast(self):
- """ Get the current essid using ioctl. """
- buff = get_iw_ioctl_result(self.iface, SIOCGIWESSID)
- if not buff:
- return None
-
- return buff.strip('\x00')
+ print 'Implement this in a derived class!'
+ pass
diff --git a/wicd/wpath.py b/wicd/wpath.py
index 6c5bd31..d519a50 100644
--- a/wicd/wpath.py
+++ b/wicd/wpath.py
@@ -12,13 +12,49 @@ current = os.path.dirname(os.path.realpath(__file__)) + '/'
# These paths can easily be modified to handle system wide installs, or
# they can be left as is if all files remain with the source directory
# layout.
-lib = current
-images = lib + 'images/'
-encryption = lib + 'encryption/templates/'
-bin = current
-etc = current + 'data/'
-networks = lib + 'encryption/configurations/'
-log = current + 'data/'
+
+# These paths are replaced when setup.py configure is run
+
+# All of these paths *MUST* end in a /
+# except the python one, of course as it is an executable
+
+lib = '/usr/lib/wicd/'
+share = '/usr/share/wicd/'
+etc = '/etc/wicd/'
+images = '/usr/share/pixmaps/wicd/'
+encryption = '/etc/wicd/encryption/templates/'
+bin = '/usr/bin/'
+networks = '/var/lib/wicd/configurations/'
+log = '/var/log/wicd/'
+backends = '/usr/lib/wicd/backends/'
+
+# other, less useful entries
+resume = '/etc/acpi/resume.d/'
+suspend = '/etc/acpi/suspend.d/'
+sbin = '/usr/sbin/'
+dbus = '/etc/dbus-1/system.d/'
+desktop = '/usr/share/applications/'
+translations = '/usr/share/locale/'
+icons = '/usr/share/icons/hicolor/'
+autostart = '/etc/xdg/autostart/'
+init = '/etc/init.d/'
+docdir = '/usr/share/doc/wicd/'
+mandir = '/usr/share/man/'
+kdedir = '/usr/share/autostart/'
+
+python = '/usr/bin/python'
+pidfile = '/var/run/wicd/wicd.pid'
+# stores something like other/wicd
+# really only used in the install
+initfile = 'init/debian/wicd'
+# stores only the file name, i.e. wicd
+initfilename = 'wicd'
+no_install_init = False
+no_install_man = False
+no_install_kde = False
+no_install_acpi = False
+no_install_install = False
+no_install_license = False
def chdir(file):
"""Change directory to the location of the specified file.