mirror of
https://github.com/gryf/wicd.git
synced 2025-12-22 05:48:03 +01:00
experimental:
- Merge in changes from pluggablebackends.
This commit is contained in:
0
wicd/__init__.py
Normal file
0
wicd/__init__.py
Normal file
97
wicd/backend.py
Normal file
97
wicd/backend.py
Normal file
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
|
||||
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
|
||||
|
||||
491
wicd/backends/be-external.py
Normal file
491
wicd/backends/be-external.py
Normal file
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
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 '<hidden>' 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 ['<hidden>', ""]:
|
||||
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
|
||||
538
wicd/backends/be-ioctl.py
Normal file
538
wicd/backends/be-ioctl.py
Normal file
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
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 [ "", '<hidden>']:
|
||||
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')
|
||||
|
||||
102
wicd/configmanager.py
Normal file
102
wicd/configmanager.py
Normal file
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
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)
|
||||
@@ -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'] + ":")
|
||||
|
||||
73
wicd/gui.py
73
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
|
||||
|
||||
|
||||
@@ -95,6 +93,14 @@ def error(parent, 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,16 +554,20 @@ 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')
|
||||
gtk.main()
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
28
wicd/misc.py
28
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__)
|
||||
@@ -77,7 +77,7 @@ def Run(cmd, include_stderr=False, return_pipe=False):
|
||||
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):
|
||||
|
||||
@@ -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())
|
||||
@@ -97,25 +99,14 @@ class ConnectionStatus(object):
|
||||
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]
|
||||
@@ -224,6 +213,18 @@ class ConnectionStatus(object):
|
||||
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'
|
||||
@@ -279,7 +280,6 @@ 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()
|
||||
|
||||
@@ -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,6 +626,7 @@ class WiredNetworkEntry(NetworkEntry):
|
||||
def edit_scripts(self, widget=None, event=None):
|
||||
""" Launch the script editting dialog. """
|
||||
profile = self.combo_profile_names.get_active_text()
|
||||
if os.getuid() != 0:
|
||||
try:
|
||||
sudo_prog = misc.choose_sudo_prog()
|
||||
msg = "You must enter your password to configure scripts"
|
||||
@@ -631,15 +634,18 @@ class WiredNetworkEntry(NetworkEntry):
|
||||
msg_flag = "-m"
|
||||
else:
|
||||
msg_flag = "--caption"
|
||||
misc.LaunchAndWait([sudo_prog, msg_flag, msg, "./configscript.py",
|
||||
profile, "wired"])
|
||||
misc.LaunchAndWait([sudo_prog, msg_flag, msg,
|
||||
wpath.lib + "configscript.py", profile,
|
||||
"wired"])
|
||||
except misc.WicdError:
|
||||
error("Could not find a graphical sudo program." + \
|
||||
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,6 +912,7 @@ class WirelessNetworkEntry(NetworkEntry):
|
||||
|
||||
def edit_scripts(self, widget=None, event=None):
|
||||
""" Launch the script editting dialog. """
|
||||
if os.getuid() != 0:
|
||||
try:
|
||||
sudo_prog = misc.choose_sudo_prog()
|
||||
msg = "You must enter your password to configure scripts"
|
||||
@@ -913,15 +920,19 @@ class WirelessNetworkEntry(NetworkEntry):
|
||||
msg_flag = "-m"
|
||||
else:
|
||||
msg_flag = "--caption"
|
||||
misc.LaunchAndWait([sudo_prog, msg_flag, msg, "./configscript.py",
|
||||
misc.LaunchAndWait([sudo_prog, msg_flag, msg,
|
||||
wpath.lib + "configscript.py",
|
||||
str(self.networkID), "wireless"])
|
||||
except IOError:
|
||||
error("Could not find a graphical sudo program." + \
|
||||
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")
|
||||
|
||||
@@ -42,17 +42,32 @@ 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. """
|
||||
@@ -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
|
||||
@@ -128,6 +145,21 @@ class Controller(object):
|
||||
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):
|
||||
""" A class to perform network connections in a multi-threaded way.
|
||||
@@ -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
|
||||
@@ -184,6 +216,15 @@ class ConnectThread(threading.Thread):
|
||||
|
||||
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):
|
||||
""" Set the threads current status message in a thread-safe way.
|
||||
@@ -286,13 +327,14 @@ 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'),
|
||||
BACKEND.SetDNS(self.network.get('dns1'),
|
||||
self.network.get('dns2'),
|
||||
self.network.get('dns3'))
|
||||
|
||||
def connect_aborted(self, reason):
|
||||
@@ -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.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
|
||||
@@ -767,21 +807,21 @@ class Wired(Controller):
|
||||
|
||||
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
|
||||
|
||||
@@ -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())
|
||||
@@ -181,6 +180,25 @@ class PreferencesDialog(object):
|
||||
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)
|
||||
|
||||
def run(self):
|
||||
@@ -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:')
|
||||
|
||||
@@ -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")
|
||||
|
||||
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()
|
||||
@@ -484,10 +521,10 @@ class TrayIcon:
|
||||
bus = dbus_manager.get_bus()
|
||||
bus.add_signal_receiver(self.gui_win.dbus_scan_finished,
|
||||
'SendEndScanSignal',
|
||||
'org.wicd.daemon')
|
||||
'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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
File diff suppressed because it is too large
Load Diff
@@ -31,51 +31,15 @@ class WirelessInterface() -- Control a wireless network interface.
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
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 = [';', '`', '$', '!', '*', '|', '>', '<']
|
||||
@@ -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.
|
||||
@@ -202,8 +148,6 @@ class Interface(object):
|
||||
self.IP_FOUND = False
|
||||
self.flush_tool = None
|
||||
self.link_detect = None
|
||||
self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
self.Check()
|
||||
|
||||
def SetDebugMode(self, value):
|
||||
""" If True, verbose output is enabled. """
|
||||
@@ -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])
|
||||
print 'Implement this in a derived class!'
|
||||
pass
|
||||
|
||||
|
||||
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)
|
||||
|
||||
|
||||
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 '<hidden>' 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 ['<hidden>', ""]:
|
||||
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
|
||||
print 'Implement this in a derived class!'
|
||||
pass
|
||||
|
||||
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
|
||||
|
||||
|
||||
|
||||
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()
|
||||
print 'Implement this in a derived class!'
|
||||
pass
|
||||
|
||||
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 _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
|
||||
print 'Implement this in a derived class!'
|
||||
pass
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user